From 2a0528303fb18dcc6799405d62a3a6f19da20b4a Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Sat, 13 Jun 2015 19:02:46 +0200 Subject: [PATCH 001/110] added batch mode to console --- cmd/console/js.go | 24 +++++++++++++++++++++++- cmd/console/main.go | 11 +++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/cmd/console/js.go b/cmd/console/js.go index a5fdaacc2..bda58be4d 100644 --- a/cmd/console/js.go +++ b/cmd/console/js.go @@ -30,6 +30,7 @@ import ( "sort" + "github.com/codegangsta/cli" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common/docserver" re "github.com/ethereum/go-ethereum/jsre" @@ -329,7 +330,28 @@ func (self *jsre) welcome(ipcpath string) { } } -func (self *jsre) interactive() { +func (self *jsre) batch(args cli.Args) { + statement := strings.Join(args, " ") + + val, err := self.re.Run(statement) + + if err != nil { + fmt.Printf("error: %v", err) + } else if val.IsDefined() { + fmt.Printf("%v", val) + } + + if self.atexit != nil { + self.atexit() + } + + self.re.Stop(false) + +} + +func (self *jsre) interactive(ipcpath string) { + self.welcome(ipcpath) + // Read input lines. prompt := make(chan string) inputln := make(chan string) diff --git a/cmd/console/main.go b/cmd/console/main.go index e8dd412ba..00a9ca9c4 100644 --- a/cmd/console/main.go +++ b/cmd/console/main.go @@ -40,7 +40,7 @@ const ( var ( gitCommit string // set via linker flag nodeNameVersion string - app = utils.NewApp(Version, "the ether console") + app = utils.NewApp(Version, "the geth console") ) func init() { @@ -93,8 +93,11 @@ func main() { func run(ctx *cli.Context) { jspath := ctx.GlobalString(utils.JSpathFlag.Name) ipcpath := utils.IpcSocketPath(ctx) - repl := newJSRE(jspath, ipcpath) - repl.welcome(ipcpath) - repl.interactive() + + if ctx.Args().Present() { + repl.batch(ctx.Args()) + } else { + repl.interactive(ipcpath) + } } From f9a0a13fa97a969b23d98c8dddc63bf8047450d3 Mon Sep 17 00:00:00 2001 From: SilentCicero Date: Sun, 14 Jun 2015 18:07:03 -0400 Subject: [PATCH 002/110] eth_pushTx send raw signed encoded TX data to the chain through RPC --- rpc/api.go | 11 +++++++++++ rpc/api/eth.go | 21 +++++++++++++++++++++ rpc/api/utils.go | 1 + 3 files changed, 33 insertions(+) diff --git a/rpc/api.go b/rpc/api.go index e35395734..64d27df2e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -170,6 +170,17 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } *reply = v + case "eth_pushTx": + args := new(NewSigArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { + return err + } + v, err := api.xeth().PushTx(args.encodedTx) + if err != nil { + return err + } + *reply = v + case "eth_sendTransaction", "eth_transact": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/rpc/api/eth.go b/rpc/api/eth.go index a0b9dad86..c5de2cd3b 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -46,6 +46,7 @@ var ( "eth_getData": (*ethApi).GetData, "eth_getCode": (*ethApi).GetData, "eth_sign": (*ethApi).Sign, + "eth_pushTx": (*ethApi).PushTx, "eth_sendTransaction": (*ethApi).SendTransaction, "eth_transact": (*ethApi).SendTransaction, "eth_estimateGas": (*ethApi).EstimateGas, @@ -247,6 +248,26 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { return v, nil } + +func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) { + args := new(NewTxArgs) + if err := self.codec.Decode(req.Params, &args); err != nil { + return nil, shared.NewDecodeParamError(err.Error()) + } + + // nonce may be nil ("guess" mode) + var nonce string + if args.Nonce != nil { + nonce = args.Nonce.String() + } + + v, err := self.xeth.PushTx(args.encodedTx) + if err != nil { + return nil, err + } + return v, nil +} + func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) { args := new(NewTxArgs) if err := self.codec.Decode(req.Params, &args); err != nil { diff --git a/rpc/api/utils.go b/rpc/api/utils.go index 318d7c39b..13f580f58 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -51,6 +51,7 @@ var ( "getData", "getCode", "sign", + "pushTx", "sendTransaction", "transact", "estimateGas", From d6233c7d2daca8f1c757740e04ba1a8d64588fc0 Mon Sep 17 00:00:00 2001 From: SilentCicero Date: Mon, 15 Jun 2015 10:07:32 -0400 Subject: [PATCH 003/110] Changed variable names --- rpc/api.go | 2 +- rpc/api/eth.go | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 64d27df2e..01f3007cf 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -175,7 +175,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - v, err := api.xeth().PushTx(args.encodedTx) + v, err := api.xeth().PushTx(args.Data) if err != nil { return err } diff --git a/rpc/api/eth.go b/rpc/api/eth.go index c5de2cd3b..2857202dd 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -255,13 +255,7 @@ func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) { return nil, shared.NewDecodeParamError(err.Error()) } - // nonce may be nil ("guess" mode) - var nonce string - if args.Nonce != nil { - nonce = args.Nonce.String() - } - - v, err := self.xeth.PushTx(args.encodedTx) + v, err := self.xeth.PushTx(args.Data) if err != nil { return nil, err } From f06f220c7c8de5fe4a08cf7d6d9531a0a564ee12 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 15 Jun 2015 16:33:36 +0200 Subject: [PATCH 004/110] added printing support for objects --- cmd/console/js.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/console/js.go b/cmd/console/js.go index bda58be4d..15ea9bedd 100644 --- a/cmd/console/js.go +++ b/cmd/console/js.go @@ -332,11 +332,13 @@ func (self *jsre) welcome(ipcpath string) { func (self *jsre) batch(args cli.Args) { statement := strings.Join(args, " ") - val, err := self.re.Run(statement) if err != nil { fmt.Printf("error: %v", err) + } else if val.IsDefined() && val.IsObject() { + obj, _ := self.re.Get("ret_result") + fmt.Printf("%v", obj) } else if val.IsDefined() { fmt.Printf("%v", val) } @@ -346,7 +348,6 @@ func (self *jsre) batch(args cli.Args) { } self.re.Stop(false) - } func (self *jsre) interactive(ipcpath string) { From f9f9352ceb2655cdf10010b6e8c30797ac97ae25 Mon Sep 17 00:00:00 2001 From: Nick Dodson Date: Mon, 15 Jun 2015 10:50:07 -0400 Subject: [PATCH 005/110] Change eth_pushTx case to eth_sendRawTransaction --- rpc/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api.go b/rpc/api.go index 01f3007cf..943d50119 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -170,7 +170,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } *reply = v - case "eth_pushTx": + case "eth_sendRawTransaction": args := new(NewSigArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err From c3b80123e3099eaf0eef5ed7ee43eb5605fc8e6f Mon Sep 17 00:00:00 2001 From: Nick Dodson Date: Mon, 15 Jun 2015 11:10:24 -0400 Subject: [PATCH 006/110] Update eth.go --- rpc/api/eth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api/eth.go b/rpc/api/eth.go index 2857202dd..1e392a63d 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -46,7 +46,7 @@ var ( "eth_getData": (*ethApi).GetData, "eth_getCode": (*ethApi).GetData, "eth_sign": (*ethApi).Sign, - "eth_pushTx": (*ethApi).PushTx, + "eth_sendRawTransaction": (*ethApi).PushTx, "eth_sendTransaction": (*ethApi).SendTransaction, "eth_transact": (*ethApi).SendTransaction, "eth_estimateGas": (*ethApi).EstimateGas, From ad56aef5d2a5e04f528f85c2d29b6574991d5e79 Mon Sep 17 00:00:00 2001 From: Nick Dodson Date: Mon, 15 Jun 2015 11:10:40 -0400 Subject: [PATCH 007/110] Update utils.go --- rpc/api/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api/utils.go b/rpc/api/utils.go index 13f580f58..dcd5b0089 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -51,7 +51,7 @@ var ( "getData", "getCode", "sign", - "pushTx", + "eth_sendRawTransaction", "sendTransaction", "transact", "estimateGas", From dfd18d245af37344f8e6fadca55f22a639d7f1ba Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Jun 2015 19:29:22 +0200 Subject: [PATCH 008/110] cmd/geth: bump 0.9.31 --- cmd/geth/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 5ea670f20..89aae43e5 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -44,7 +44,7 @@ import ( const ( ClientIdentifier = "Geth" - Version = "0.9.30" + Version = "0.9.31" ) var ( From 2642e091e95f7c74c04502dfd05af0d9d1217158 Mon Sep 17 00:00:00 2001 From: Nick Dodson Date: Mon, 15 Jun 2015 16:01:01 -0400 Subject: [PATCH 009/110] NewSigArgs arg change. --- rpc/api/eth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api/eth.go b/rpc/api/eth.go index 1e392a63d..bb89615cf 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -250,7 +250,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) { - args := new(NewTxArgs) + args := new(NewSigArgs) if err := self.codec.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } From e952bb65e7f74dc023a983415821b3522cc30746 Mon Sep 17 00:00:00 2001 From: Nick Dodson Date: Tue, 16 Jun 2015 00:06:28 -0400 Subject: [PATCH 010/110] thanks subtly :) --- rpc/api/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api/utils.go b/rpc/api/utils.go index dcd5b0089..40bcae52f 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -51,7 +51,7 @@ var ( "getData", "getCode", "sign", - "eth_sendRawTransaction", + "sendRawTransaction", "sendTransaction", "transact", "estimateGas", From 8f372c867d0717560640d513058bda9af24335e5 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Tue, 16 Jun 2015 12:09:25 +0200 Subject: [PATCH 011/110] Update Ethereum JSON test files --- .../files/BlockTests/bcInvalidHeaderTest.json | 310 +++- .../BlockTests/bcUncleHeaderValiditiy.json | 850 +++++---- .../RandomTests/st201506091836GO.json | 71 + .../RandomTests/st201506092032GO.json | 71 + .../RandomTests/st201506101359JS.json | 71 + .../RandomTests/st201506101754PYTHON.json | 71 - .../stPrecompiledContractsTransaction.json | 1556 +++++++++++++++++ .../RandomTests/vm201506052232CPPJIT.json | 31 - .../RandomTests/vm201506052232PYTHON.json | 46 - .../RandomTests/vm201506060003CPPJIT.json | 31 - .../RandomTests/vm201506060003PYTHON.json | 46 - .../RandomTests/vm201506060013CPPJIT.json | 31 - .../RandomTests/vm201506060035CPPJIT.json | 31 - .../RandomTests/vm201506060035PYTHON.json | 47 - .../RandomTests/vm201506060134CPPJIT.json | 31 - .../RandomTests/vm201506060134PYTHON.json | 47 - 16 files changed, 2539 insertions(+), 802 deletions(-) create mode 100644 tests/files/StateTests/RandomTests/st201506091836GO.json create mode 100644 tests/files/StateTests/RandomTests/st201506092032GO.json create mode 100644 tests/files/StateTests/RandomTests/st201506101359JS.json delete mode 100644 tests/files/StateTests/RandomTests/st201506101754PYTHON.json create mode 100644 tests/files/StateTests/stPrecompiledContractsTransaction.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506052232CPPJIT.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506052232PYTHON.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060003CPPJIT.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060003PYTHON.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060013CPPJIT.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060035CPPJIT.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060035PYTHON.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060134CPPJIT.json delete mode 100644 tests/files/VMTests/RandomTests/vm201506060134PYTHON.json diff --git a/tests/files/BlockTests/bcInvalidHeaderTest.json b/tests/files/BlockTests/bcInvalidHeaderTest.json index a5c16b803..e74840d47 100644 --- a/tests/files/BlockTests/bcInvalidHeaderTest.json +++ b/tests/files/BlockTests/bcInvalidHeaderTest.json @@ -2,7 +2,7 @@ "DifferentExtraData1025" : { "blocks" : [ { - "rlp" : "0xf90665f905fca0c6d177167d978c66a02083c59d7e04f00bf068140e178f0eb744d4e64c4ac28da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0704eb309526a1478e1eec2dff7015b2bd31731fa6c985f6316fea4bc57e89535a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b845571777fb904010101020304050607080910111213141516171819202122232410000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000100000000000000000002000000000000000000030000000000000000000400000000000000000005000000000000000000060000000000000000000700000000000000000008000000000000000000090000000000000000000100000000000000000001000000000000000000020000000000000000000300000000000000000004000000000000000000050000000000000000000600000000000000000007000000000000000000080000000000000000000900000000000000000001000000000000000000010000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000100000000000000000002000000000000000000030000000000000000000400000000000000000005000000000000000000060000000000000000000700000000000000000008000000000000000000090000000000000000000100000000000000000001000000000000000000020000000000000000000300000000000000000004000000000000000000050000000000000000000600000000000000000007000000000000000000080000000000000000000900000000000000000001000000000000000000010000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000100000000000000000002000000000000000000030000000000000000000400000000000000000005000000000000000000060000000000000000000700000000000000000008000000000000000000090000000000000000000100000000000000000001000000000000000000020000000000000000000300000000000000000004000000000000000000050000000000000000000600000000000000000007000000000000000000080000000000000000000900000000000000000001000000000000000000010000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000a0b26aa271af67dbbce21140251d07d1a1e7a6cce51b427e2e6033cf80d1f6d33e88d92cd1710471a9a0f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca00bb090ec0e32468558690bb11b677a881d2079f345716c587df2c55a9760e55ea0143d4a093577bae50dd48fb2b006c0636fe03cbe65f7df75a2ffbac73b4fd04ec0" + "rlp" : "0xf90665f905fca0801e9dfc2d12f33d8372ee4192bb02e65f4af5a870745aed2910a6ab4e115cd2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0bd320f0acf90f5a246c237637f11ef21b05d76fdd9f647f9c3267bb34a743de7a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4c0b904010101020304050607080910111213141516171819202122232410000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000100000000000000000002000000000000000000030000000000000000000400000000000000000005000000000000000000060000000000000000000700000000000000000008000000000000000000090000000000000000000100000000000000000001000000000000000000020000000000000000000300000000000000000004000000000000000000050000000000000000000600000000000000000007000000000000000000080000000000000000000900000000000000000001000000000000000000010000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000100000000000000000002000000000000000000030000000000000000000400000000000000000005000000000000000000060000000000000000000700000000000000000008000000000000000000090000000000000000000100000000000000000001000000000000000000020000000000000000000300000000000000000004000000000000000000050000000000000000000600000000000000000007000000000000000000080000000000000000000900000000000000000001000000000000000000010000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000100000000000000000002000000000000000000030000000000000000000400000000000000000005000000000000000000060000000000000000000700000000000000000008000000000000000000090000000000000000000100000000000000000001000000000000000000020000000000000000000300000000000000000004000000000000000000050000000000000000000600000000000000000007000000000000000000080000000000000000000900000000000000000001000000000000000000010000000000000000000200000000000000000003000000000000000000040000000000000000000500000000000000000006000000000000000000070000000000000000000800000000000000000009000000000000000000010000000000000000000a0da2d90bff4f835b72117284c8eb34446b9121dba6d14006b2766a579f5f003858869b0977b1699157df863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca042756f995aaedcbb380ecbf42e8b38249c8918ba0b0950ee997570a390f111b4a0f731d1b73239601cd56f1b1d0c6e13343e029f89737e3fcecbf0b12a85f5f62dc0" } ], "genesisBlockHeader" : { @@ -12,9 +12,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "c6d177167d978c66a02083c59d7e04f00bf068140e178f0eb744d4e64c4ac28d", - "mixHash" : "720adb221d6e68020cba806fc84a42bae4fcea4022266864ace1df198f661063", - "nonce" : "9197d35dd2f8f78b", + "hash" : "801e9dfc2d12f33d8372ee4192bb02e65f4af5a870745aed2910a6ab4e115cd2", + "mixHash" : "ca735c79245c5304ec6d8a6b02db4c6c7993b49a9f782efd6210034a42beb8c1", + "nonce" : "2ae839b01a3709f9", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -23,8 +23,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0720adb221d6e68020cba806fc84a42bae4fcea4022266864ace1df198f661063889197d35dd2f8f78bc0c0", - "lastblockhash" : "c6d177167d978c66a02083c59d7e04f00bf068140e178f0eb744d4e64c4ac28d", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0ca735c79245c5304ec6d8a6b02db4c6c7993b49a9f782efd6210034a42beb8c1882ae839b01a3709f9c0c0", + "lastblockhash" : "801e9dfc2d12f33d8372ee4192bb02e65f4af5a870745aed2910a6ab4e115cd2", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -61,7 +61,7 @@ "GasLimitIsZero" : { "blocks" : [ { - "rlp" : "0xf9025ef901f6a0767ebbfe066c1b5e0da78be7b7f2e432ebddfbeabfeb264b820244ee317927f5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0ff6c12f6bda0cb5d19ee77ba7feafe35c64635ced9c6af60022724054b4258fca05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b901000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000004000000000000000000000000000000000000000000000000000000083020000018082560b845571778180a0d000a09ce995335977209ed74b1af291e1d7b4b9fa52596a4e502b60d0d3936488bef9414aec541abdf862f860800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801b9fb196993b5b7db21765295cdc2463d908159e7de2882e05c799b55b89c2f634a05769ff65182b0bb2a80b6417b1fe35d8e4bd2b9b27d32a6917f1d6862e66285dc0" + "rlp" : "0xf9025ff901f6a0294fb6f9125c5926ab028dac7c344ee39ade18aee1a188c817c391f1897a2655a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0c93866bffee7bcec3910a365091aff84edd9e8a621a121898a4901c9c146e538a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b901000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000004000000000000000000000000000000000000000000000000000000083020000018082560b84557ff4c380a0a5782206a67c90a7fa20b54ab6afb246956bef23482a39c8eac9abe90b1103b4883cd9dcee62bb1ed9f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0a4043e901d565fe6f80663e0a7b109d7d3c5d41d1ad0c584713a592adab2ef8fa04dde69b415e3bd757aca11b3ff9b62fbd0139b6b1168d23d832622ce68053bfcc0" } ], "genesisBlockHeader" : { @@ -71,9 +71,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "767ebbfe066c1b5e0da78be7b7f2e432ebddfbeabfeb264b820244ee317927f5", - "mixHash" : "55c5b5c0d878ec90ba09c902e5f0223e559814c70c2bf7bdff04e45162471451", - "nonce" : "557b8dcca44e77c1", + "hash" : "294fb6f9125c5926ab028dac7c344ee39ade18aee1a188c817c391f1897a2655", + "mixHash" : "a9d33ca61587dc9d28c0860a4f5d6a78c82e29b2207c570a886a6668a2f16c88", + "nonce" : "d475b1cdd15c16cd", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -82,8 +82,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a055c5b5c0d878ec90ba09c902e5f0223e559814c70c2bf7bdff04e4516247145188557b8dcca44e77c1c0c0", - "lastblockhash" : "767ebbfe066c1b5e0da78be7b7f2e432ebddfbeabfeb264b820244ee317927f5", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0a9d33ca61587dc9d28c0860a4f5d6a78c82e29b2207c570a886a6668a2f16c8888d475b1cdd15c16cdc0c0", + "lastblockhash" : "294fb6f9125c5926ab028dac7c344ee39ade18aee1a188c817c391f1897a2655", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -120,7 +120,7 @@ "log1_wrongBlockNumber" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a095684697c91a94d4c4448bd3578754f6eefb60b5b672e04deda174eddcf959eaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa024046d212ac9d0954067b296e42683ab90c9c13a46cc2ee49b83290b94f74eeba05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000002832fefd882560b845571778580a0e8953d67e22f0fce7bbbef25de1bf0c8433959c39521c944000f1a71b086c62488c9f1168b6501724ef863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca03076226629e809e10cf8444a7b7ff7d1ae2e0dd5a4030946308952b9c5bfcbb0a07a61d4688f6285c6f9b80dd2b1847da230e1a22b97b339816a20ded78046838fc0" + "rlp" : "0xf90262f901f9a0620e681cb4df774ab54c0232376b909199e24b42ff5c84507fe8b08ff43b09e2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0dd1cea4016b2072a0c5f4e3c7d734fc8607d223db9a96b6a3e0d490334e29af9a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000002832fefd882560b84557ff4c680a0b8f5d358696f4f8f6dc7b305b235ef1f19cbf1900c6edfa060e99279419055bb88a587b355bfe6e26ff863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca07b27f8b769a18c5e45961c6f058c68317703391b92b490e12dcade6a8b7bcb63a0c13691e75e2fdc8a7bf12cab717d8a735201e6cde67c879bea240005d930026fc0" } ], "genesisBlockHeader" : { @@ -130,9 +130,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "95684697c91a94d4c4448bd3578754f6eefb60b5b672e04deda174eddcf959ea", - "mixHash" : "293420f1dc7c9c7af40b76858aead8cfb1ab26548c5692119cc2dd74b4ae0223", - "nonce" : "c0d18019a7a381ad", + "hash" : "620e681cb4df774ab54c0232376b909199e24b42ff5c84507fe8b08ff43b09e2", + "mixHash" : "86f621add0bb4a000fb726f614f83287fbe63e9584195d87ad7b245a8b756a72", + "nonce" : "b80c084b56a750fa", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -141,8 +141,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0293420f1dc7c9c7af40b76858aead8cfb1ab26548c5692119cc2dd74b4ae022388c0d18019a7a381adc0c0", - "lastblockhash" : "95684697c91a94d4c4448bd3578754f6eefb60b5b672e04deda174eddcf959ea", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a086f621add0bb4a000fb726f614f83287fbe63e9584195d87ad7b245a8b756a7288b80c084b56a750fac0c0", + "lastblockhash" : "620e681cb4df774ab54c0232376b909199e24b42ff5c84507fe8b08ff43b09e2", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -179,7 +179,7 @@ "log1_wrongBloom" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a05b65ba0dde01c352aca92e1fc66c16b7575bd923d5c01737e6f1db85bf08af77a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa017b5c1f224727a466f14f80fbd641a3a27a97928413fe3d886d6f015d7490c4da05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882560b845571778780a0542dec5c23c3eaded951cd55626458319e7e23efbde919516c6a1e514f3d260188c46503f09b58ca3af863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca04191594d0073963078907fc1bc226e390892582c1f84fcdffc651c7b9ffda3e9a0df1406ecc4b41ff030b25ed852ca47cd53f9ced3fcfe1c8103406dc679e9da2cc0" + "rlp" : "0xf90262f901f9a061816f6181fedda93826656e70683c8bfbb3acd4b00964bc65b4835c7f1ae41da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa098535fe3c1eb69c7d218780e728f89d3b3e2c76d20953c1242e4bca37a778360a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4ca80a0b41717f2daecff0cd492e10d411be5214dc30b7b1fd99e69e39002d552802c75880bbc6ced3ce651a9f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba08d0c6e6b1db2f976c0167887f418dfaaa317fb3268dbef25a56c67d6b8aca7b3a02775f6b29f3057b451b069b09281e79591e247f88d068d202e5ce5364217dda1c0" } ], "genesisBlockHeader" : { @@ -189,9 +189,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "5b65ba0dde01c352aca92e1fc66c16b7575bd923d5c01737e6f1db85bf08af77", - "mixHash" : "6333422cd270aa72999c0edc1b749cbed8458be7d9789cb42b3584ffdbb6ea9f", - "nonce" : "7afd54fabcc98bb0", + "hash" : "61816f6181fedda93826656e70683c8bfbb3acd4b00964bc65b4835c7f1ae41d", + "mixHash" : "fd7c4c44729ca29af51db4c3cefaabd8ae09899ae8c7a77413e941062fb90792", + "nonce" : "5633654b840d2d49", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -200,8 +200,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a06333422cd270aa72999c0edc1b749cbed8458be7d9789cb42b3584ffdbb6ea9f887afd54fabcc98bb0c0c0", - "lastblockhash" : "5b65ba0dde01c352aca92e1fc66c16b7575bd923d5c01737e6f1db85bf08af77", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0fd7c4c44729ca29af51db4c3cefaabd8ae09899ae8c7a77413e941062fb90792885633654b840d2d49c0c0", + "lastblockhash" : "61816f6181fedda93826656e70683c8bfbb3acd4b00964bc65b4835c7f1ae41d", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -238,7 +238,7 @@ "wrongCoinbase" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a0e1dc5c4eef8b9bca44074c3317bc212c9dcffb138e83a6fad3f5260cdd59092da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa07438243bc5c79aa4a3f605db9c133c0e356d072e3ac6fba4aa96e11424ca73b0a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b845571778c80a0bb5b4e9db25ef43eebd1cf786ed0f5c9197d35d3fb923648061ce4981f70f5d788aecd18084b367266f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca01c1c6a510fa61e0ae8608e9ac0feebb44394d6aae913a5844de3e15a730ef9a3a027f1e4099b593d5add6629ae5772a73d3220705e270295b1f8e0eb69326582d3c0" + "rlp" : "0xf90262f901f9a0203d78c55325b7d2b33def1e65799b3e8a697bd2d38be07912d89c521d0a831ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0ee1f71f8612a1a0dc36d8c318576c4d5dca3f67c1a1111e06874a7187a75e273a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4cc80a02871566a90428b72b54900bbed49a3b42bcc5f6ff4bc135d63550ad3638b110488ceb940b576899ec8f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0c39dfc246695c6d84a7c59b5bee73c249507d1ce8c35b1473bf70366225a8212a038bf288841a713102009c8d4ff66bf8e5463c503e3995b21366e1cd078eef248c0" } ], "genesisBlockHeader" : { @@ -248,9 +248,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "e1dc5c4eef8b9bca44074c3317bc212c9dcffb138e83a6fad3f5260cdd59092d", - "mixHash" : "159026361f12572817e93416afc95417755152b0ad07a2ce7ce75d115bd27226", - "nonce" : "6b69b9df6635df44", + "hash" : "203d78c55325b7d2b33def1e65799b3e8a697bd2d38be07912d89c521d0a831b", + "mixHash" : "1bc0f803c19f1a996cbed7db7cd04bc061de6a1078dd25fbdadbf2eb051f518a", + "nonce" : "18c615f04cd1a057", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -259,8 +259,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0159026361f12572817e93416afc95417755152b0ad07a2ce7ce75d115bd27226886b69b9df6635df44c0c0", - "lastblockhash" : "e1dc5c4eef8b9bca44074c3317bc212c9dcffb138e83a6fad3f5260cdd59092d", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a01bc0f803c19f1a996cbed7db7cd04bc061de6a1078dd25fbdadbf2eb051f518a8818c615f04cd1a057c0c0", + "lastblockhash" : "203d78c55325b7d2b33def1e65799b3e8a697bd2d38be07912d89c521d0a831b", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -297,7 +297,7 @@ "wrongDifficulty" : { "blocks" : [ { - "rlp" : "0xf90261f901f8a028c23861416beea344ac67e6cf5b36b0c25d1710b0651fb8000117b69206a337a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa04571453a1786ae7fa055cd12ee147dca558e3939bcaa2c1fb35033013e8006d2a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b901000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000004000000000000000000000000000000000000000000000000000000082271001832fefd882560b845571778e80a08157ea9f3de2da0da0a2e5b7ee45fa225e44af726148ac08c5d923b4f6adecdf88368177e797490361f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0f48035b21e50a7331b958aec69a0c70c2fa44e250dd013d9bd58eb3f2714ddd0a04bd907fdd7d28d0664ece8d15cc27414ce47db5b8d3a4e4ccf71ef4298c61608c0" + "rlp" : "0xf90261f901f8a0e26518455a4d9989da691c2ace65c758795e586c24f085a55c3d81c14e142a7ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0a3367304ab7d594d34e0983ee5152d44c77a9018d38ef582c33f3b3beca3505ea05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b901000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000004000000000000000000000000000000000000000000000000000000082271001832fefd882560b84557ff4cf80a0e73f7cc84d40e67259477ba9bf046e746bc83c7d9d648533ab249c2f8247313288ef74b1391e6bea87f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0094bd4e29d134267f5d5f040601a8520225990a22c69aad1a27fe45861fcaf96a0afe5fc4870e4b6e5d82dd3e4939291097d858c1223314e05eda817169641483fc0" } ], "genesisBlockHeader" : { @@ -307,9 +307,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "28c23861416beea344ac67e6cf5b36b0c25d1710b0651fb8000117b69206a337", - "mixHash" : "d8b1d7496cc566ed583f7548463d8f83cf39c67645ba29fbaaea55de1b3b5a7e", - "nonce" : "81417c4cd48b2824", + "hash" : "e26518455a4d9989da691c2ace65c758795e586c24f085a55c3d81c14e142a7c", + "mixHash" : "39a07d831e0d27a8b433d2cefba7992a4bc10d1b8cc44d9dde945c7cddb2f170", + "nonce" : "d2fbfc19d43f1e0f", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -318,8 +318,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0d8b1d7496cc566ed583f7548463d8f83cf39c67645ba29fbaaea55de1b3b5a7e8881417c4cd48b2824c0c0", - "lastblockhash" : "28c23861416beea344ac67e6cf5b36b0c25d1710b0651fb8000117b69206a337", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a039a07d831e0d27a8b433d2cefba7992a4bc10d1b8cc44d9dde945c7cddb2f17088d2fbfc19d43f1e0fc0c0", + "lastblockhash" : "e26518455a4d9989da691c2ace65c758795e586c24f085a55c3d81c14e142a7c", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -356,7 +356,7 @@ "wrongGasLimit" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a0ab0bc3b824e00781e2b5157de39911a65536441e4a1fd1f3e15df3f4029c6bbba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa04c312949d2300f715fe47dc30e92764eb164bdaaf965ec7480244ad46ed4f588a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001830186a082560b845571779280a0b6fe955b66651246a165a9c9aa3657db741b89e3c8b443dec43ba6cbfbb643ef88de116b29b785b0a7f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0427ff068b8facebce0ecbd6e9125ccb6ee5f9ccce186dbf7c0e23777a5c93942a07b1b218a7bc14cde41b07aefc80e521f262a01b742f24d8a6fd62215b4e455a9c0" + "rlp" : "0xf90262f901f9a0cc1c0a26f21579ac40bbc494604824fc473b6faa3fd3d68edd433fa8f70c932da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa093a856cb300c99471e166d0b11d4a22450987b4bac8c35338c233cedcc67be1da05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001830186a082560b84557ff4d280a053b148958caa66dee6417a154c348297614883976b8c16f03cf5b268b0e893e8888106219c66e62361f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba082e54b7f7d5671d0ee93138b0300f0e807bd115ce3bd1bc99e21925f7bd96e0ba0d0217b852d89ae38d5681c6975ec492f69e4c411c6046a8668f044db2864483ac0" } ], "genesisBlockHeader" : { @@ -366,9 +366,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "ab0bc3b824e00781e2b5157de39911a65536441e4a1fd1f3e15df3f4029c6bbb", - "mixHash" : "4e7e88d99e1c60d632b7f77370a3d97751798b83c7dd6afbabed984685cc2b10", - "nonce" : "8eaab15f19039717", + "hash" : "cc1c0a26f21579ac40bbc494604824fc473b6faa3fd3d68edd433fa8f70c932d", + "mixHash" : "b033eeba6bf1a9d293f067d0d395e1893d2cc788992182bb14bea5f220c7be5a", + "nonce" : "5246583fa42e6da0", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -377,8 +377,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a04e7e88d99e1c60d632b7f77370a3d97751798b83c7dd6afbabed984685cc2b10888eaab15f19039717c0c0", - "lastblockhash" : "ab0bc3b824e00781e2b5157de39911a65536441e4a1fd1f3e15df3f4029c6bbb", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0b033eeba6bf1a9d293f067d0d395e1893d2cc788992182bb14bea5f220c7be5a885246583fa42e6da0c0c0", + "lastblockhash" : "cc1c0a26f21579ac40bbc494604824fc473b6faa3fd3d68edd433fa8f70c932d", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -415,7 +415,7 @@ "wrongGasUsed" : { "blocks" : [ { - "rlp" : "0xf90260f901f7a056c737fb93a2ef921f1f215431fcfc642c253bbcea162264cfc726c2659d8847a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0fe2082bd92c7a0fd597d14068178619fdd8fca14b85d31964f025bb92105d91ea05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd880845571779680a0b0c7c644ab33b7104683be72f84a830620bfffdeade55bdabe77691c3c73a3d48884777344d9b3c42bf863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca098600c061936e1a90b0ea43d54a816d6d7e4bd27c3a64a5f7395ee1390d44d26a0c66a6018f3e65282096a37ece5e462d7790804bc9a626eb30f3caf3fdde61be5c0" + "rlp" : "0xf90260f901f7a0dd8be3fc6598a9c6c9c210a994b2e4e28c75e4f4fca5fe8cf657cd06d9002085a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa00a9b78ba07eed41fbc66630ed6b4d01e96231a4a130c4bbb39f272368dc79642a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd88084557ff4d580a0b237b0476170afbcde1e949c44c60176dc86a77df0b3ac7a19227e3afe798502884e1ce1bf32090576f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0f5ec14a149f51a6507fab88f921df3c51417d98feabfbaacfa3bb39ec75d0ccfa00255304a957f4779c19cc5700b0bd44d80436e52327f97cb9f3b9340942317b7c0" } ], "genesisBlockHeader" : { @@ -425,9 +425,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "56c737fb93a2ef921f1f215431fcfc642c253bbcea162264cfc726c2659d8847", - "mixHash" : "62c2a16e600f769646d8d14884b16c35d2b8209809460e78124040685cf9490a", - "nonce" : "e2ba1769d3c2f42b", + "hash" : "dd8be3fc6598a9c6c9c210a994b2e4e28c75e4f4fca5fe8cf657cd06d9002085", + "mixHash" : "4417af0859b6d2e10793172a151ad1e6a03f34cbd7c2f2cfbb863426925702a7", + "nonce" : "44f1d62f7b9b0a78", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -436,8 +436,126 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a062c2a16e600f769646d8d14884b16c35d2b8209809460e78124040685cf9490a88e2ba1769d3c2f42bc0c0", - "lastblockhash" : "56c737fb93a2ef921f1f215431fcfc642c253bbcea162264cfc726c2659d8847", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a04417af0859b6d2e10793172a151ad1e6a03f34cbd7c2f2cfbb863426925702a78844f1d62f7b9b0a78c0c0", + "lastblockhash" : "dd8be3fc6598a9c6c9c210a994b2e4e28c75e4f4fca5fe8cf657cd06d9002085", + "postState" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x64", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x174876e800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x64", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x174876e800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "wrongMixHash" : { + "blocks" : [ + { + "rlp" : "0xf90262f901f9a034071a807d83f8e634082378e3c236b5d790c5bb3f6f5e81b857067eb0a8679fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0b7d4d7f8d724567a6837e3872f014100704c2848ad2b1d2a3e0d410b35c81280a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4d880a0bad81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421889626a46727781363f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba06d7dc3c29c4473543b574413536b608d7afa4c96bbfbbf033473a088e6662ff8a07be035d2fa3e7a2b0c8ac6dea2f53dcde4ebc9020f008057bb90c044e6cfb895c0" + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "34071a807d83f8e634082378e3c236b5d790c5bb3f6f5e81b857067eb0a8679f", + "mixHash" : "c7f735b359771b6bf60f2aa2e3a32398e9ee3632b1764ea4d825cc3fc2472610", + "nonce" : "68e84fc7fccee640", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0c7f735b359771b6bf60f2aa2e3a32398e9ee3632b1764ea4d825cc3fc24726108868e84fc7fccee640c0c0", + "lastblockhash" : "34071a807d83f8e634082378e3c236b5d790c5bb3f6f5e81b857067eb0a8679f", + "postState" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x64", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x174876e800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x64", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x174876e800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "wrongNonce" : { + "blocks" : [ + { + "rlp" : "0xf90262f901f9a09f8661c236c947e990a8ec6a36826a04116a3b8b538580fb11b4c24c002414aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0c0bd2a6e974187ddf5947f6da175d1ba181571fe404596b18566719b1d1f1a10a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4db80a0d606f0a099a1665471070b58a59e8c010bc0f5e4cdc21bb7a3fd8e019e04ba3e880102030405060708f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0e0ac29311ef444214c39a01dda74283660281755b080f736525ead2a44ef43d2a00601b2fd9fde08b0642a0ea65648ede9f90b4d038e8297849cb9546b78d3cd78c0" + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "9f8661c236c947e990a8ec6a36826a04116a3b8b538580fb11b4c24c002414ae", + "mixHash" : "7bba8aacca3f5f41b164a5fe9be14d4423482a8db61567be534fba8487c4542b", + "nonce" : "f9e12735eac5c35e", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a07bba8aacca3f5f41b164a5fe9be14d4423482a8db61567be534fba8487c4542b88f9e12735eac5c35ec0c0", + "lastblockhash" : "9f8661c236c947e990a8ec6a36826a04116a3b8b538580fb11b4c24c002414ae", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -474,7 +592,7 @@ "wrongNumber" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a0bd5affba6e8314914d1c80e449fc86bb32422655191a539295e561bb95859b7fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0d0f521c3d2b1500b19006e0a35f77b0a9b2fd84322d3c379de013e36b2b70db9a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000080832fefd882560b845571779980a06bddf76856f614acfd4e0314e0d99e511a453c1685e3acfec644ca9b6310e41688517671c8a2609713f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0c966be9864575e52010fe2af467e2d5cf6e4a199136a23eab0ee85d47846bbd3a0c7ec181ac50f5ec53fa0b4f41026c856574bbe2098d9d90317a250697d971753c0" + "rlp" : "0xf90262f901f9a0355330178117d2d83a04982501753442e9cb04e037f7df1f9eca29ddea6666baa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa02209b441926c515a6da60653f83b71e448236e1ae5240847b2e316b725521649a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000080832fefd882560b84557ff4dd80a086286d028f067a84fd47ad22b04492dda6ee99fb1e0f84b60e9e12b3b2fd55ec88831fba7fec7ee0d4f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0f6e994176cfd1896f4cbf8bf15afa87b3471aa18c5d2fa0ed27a4c5b32ccef49a0d41553c633e2857252a873728f1260c6dfb6c034eb3e16cee7eec2432351d4f8c0" } ], "genesisBlockHeader" : { @@ -484,9 +602,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "bd5affba6e8314914d1c80e449fc86bb32422655191a539295e561bb95859b7f", - "mixHash" : "cd387b50c1b42183ed83d32782f8c5fa049952eff9c706c208bf7b0db67cc2c4", - "nonce" : "262f976bd596e80e", + "hash" : "355330178117d2d83a04982501753442e9cb04e037f7df1f9eca29ddea6666ba", + "mixHash" : "7acac5570c7e5c6b105b8c16a3072a5bf79e2dabddda3b732ea1aee2c5ddec63", + "nonce" : "3129a41a4c150512", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -495,8 +613,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0cd387b50c1b42183ed83d32782f8c5fa049952eff9c706c208bf7b0db67cc2c488262f976bd596e80ec0c0", - "lastblockhash" : "bd5affba6e8314914d1c80e449fc86bb32422655191a539295e561bb95859b7f", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a07acac5570c7e5c6b105b8c16a3072a5bf79e2dabddda3b732ea1aee2c5ddec63883129a41a4c150512c0c0", + "lastblockhash" : "355330178117d2d83a04982501753442e9cb04e037f7df1f9eca29ddea6666ba", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -533,7 +651,7 @@ "wrongParentHash" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0c306ba1a9980da1ce475e972af092937a21033ca5204fadf35a54ea02d996ae6a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b845571779c80a03fb009c625b10c16916e44b0fb0d968f6e95344b4f0618eb67dbc61494d9a7498868f7b521330a24cef863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca07c5c6dfe08c78cd076b9ccd93ba735334fcb8b1c4de1de5eacb1c26687e93f48a0cdc9570b510928cb1b83464ac1cd2faa4657d40514626c655a87fda968033a09c0" + "rlp" : "0xf90262f901f9a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0e9cfddb76c058b94c8617f5aec0e88b4ab114245e268a33b1a70decfb68bb9f5a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4e080a07fbef8b98816e481ae842f068d73295123a84bf5f836faa4968233552542fef688c22ccbe4f4fd97d4f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0df47648ebbd41ebb39b9b82a2cfa6221f86848d3cc9325719eedea1cb5e3236ea0a70f89fb9954ae52f9a9823a28c5973fedd07dca3728585524f7ddf36c4a2699c0" } ], "genesisBlockHeader" : { @@ -543,9 +661,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "e37478e7d70a1c30ee11af597c1c9a333dbd7bb4cd66c9c1bcb26c3b68b67e09", - "mixHash" : "538d7430220da84452852f2f1073b03737f15abb1ccffc54a3d9f68324fab47c", - "nonce" : "d359e87c1400ce8d", + "hash" : "19ba95521795315095932fdbcdfd6252f5be122ed9e11a4bdc76ff37d9e01126", + "mixHash" : "da98a6b8dff33e89dc016b90c713bb001a50654a90fbf004929b85a629e0ec98", + "nonce" : "df4c80f3d5a91dad", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -554,8 +672,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0538d7430220da84452852f2f1073b03737f15abb1ccffc54a3d9f68324fab47c88d359e87c1400ce8dc0c0", - "lastblockhash" : "e37478e7d70a1c30ee11af597c1c9a333dbd7bb4cd66c9c1bcb26c3b68b67e09", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0da98a6b8dff33e89dc016b90c713bb001a50654a90fbf004929b85a629e0ec9888df4c80f3d5a91dadc0c0", + "lastblockhash" : "19ba95521795315095932fdbcdfd6252f5be122ed9e11a4bdc76ff37d9e01126", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -592,7 +710,7 @@ "wrongParentHash2" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a06151889c8f14ab46e32ee0b1894bc276416385d068a1ade000d0dadef9b08b18a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa071d88e6e06291f18f96be0cc281a56e74e86f18c9e629fbc8e71a0cd1c3f1270a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557177a080a026e252aa11d17b9f7013bac91f4af3a13cacda951288cf230f5ccb94eb3e67f1884730e9f33c34acc5f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba09f77959c844c8df3ee3203c103c7619fb767f8afd2815abcb03e569e9f61cfc5a0a6aecb59b767433a351b0513298a0a005c210f50cba4016fedb52ddb0143aecac0" + "rlp" : "0xf90262f901f9a06151889c8f14ab46e32ee0b1894bc276416385d068a1ade000d0dadef9b08b18a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa08447f44931420a82dc813998fc980608ba69b6e989d8e067ed54f4e4d1b00516a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4e480a0a96d9d00cb83d9a3eaa10269ac9e3297f9af79ebe15b02033bd6c1f6a237836c88f99d1d09396a9c18f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0a830793b992f6725dda16af6d2a3e7c8b5b6d39bd15cf15fa13ed68caa5d8db1a04fb1a8166dba1eb68377ded6cc8f416762401ca12c7bda444356e320a2fbbd3fc0" } ], "genesisBlockHeader" : { @@ -602,9 +720,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "4e3b39e51bcdd22e59994d247ba6b77df7aa7e9e08594371e34dfbf1dcfce134", - "mixHash" : "0d087968734c2f1ac05a44e617d327e9e029756f7601b5ab8418ecc84a2892ac", - "nonce" : "777e523a58296f05", + "hash" : "5272d5baa3babce753a5f092b5c3634743ab41d6f40de3fb867b044cdfa50a4c", + "mixHash" : "4ff65189a4cb2b2f799783a0551050eb4797e0e6260eae53676780be9939d97f", + "nonce" : "fcb284742b76ee35", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -613,8 +731,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a00d087968734c2f1ac05a44e617d327e9e029756f7601b5ab8418ecc84a2892ac88777e523a58296f05c0c0", - "lastblockhash" : "4e3b39e51bcdd22e59994d247ba6b77df7aa7e9e08594371e34dfbf1dcfce134", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a04ff65189a4cb2b2f799783a0551050eb4797e0e6260eae53676780be9939d97f88fcb284742b76ee35c0c0", + "lastblockhash" : "5272d5baa3babce753a5f092b5c3634743ab41d6f40de3fb867b044cdfa50a4c", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -651,7 +769,7 @@ "wrongReceiptTrie" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a0e7c72d4a61a09444f2d2943d8d082e8cdac1435b71028353e6ff844873ccec30a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa029b33e4a7d8727adea58fc785f731c639a53bf13ed35b54cd6f93c633d3c699aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557177a480a09f34c56d65ace260a8eb94312f02d64b21cdc48eac53c500a1cd249b930aa247887c276c1c1c5a635ef863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca05126c2ad77f95f072ea6a3cf9af36ba4141dd58c69cfef35ce083ba25494f6bda0e72a2d2bf4c9229e94a65c53c8e57dcc65252010056516dd95753f3b10d4d881c0" + "rlp" : "0xf90262f901f9a06605eef6ead056d45d2b56c83703faad6172fb0081e486f9f249949fe7d5e953a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa035c5334d1e4423d1373bdcfece52dc1dbe7b74d0deff46c3384f212150b50282a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4e880a06026e2cfa76464cd9f33e8f3a29181323530cd68243ba848725d11e81af0b63b8892b0b0478ae521f9f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0ce136fc0dd98a87f038919adff9146a56f47dee178e08fec457fd5e8ffedeb96a0877183fd1b9c22c05a7d48efac8d14f4d7826a32f0f1c917bcb995df201f21c2c0" } ], "genesisBlockHeader" : { @@ -661,9 +779,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "e7c72d4a61a09444f2d2943d8d082e8cdac1435b71028353e6ff844873ccec30", - "mixHash" : "94b663897de987d5a5ceba67796d1df9c7e5f5145cd2342ad87b6d065ecde894", - "nonce" : "3abefb0f334e3acb", + "hash" : "6605eef6ead056d45d2b56c83703faad6172fb0081e486f9f249949fe7d5e953", + "mixHash" : "b3fdfcbef5c525dbb62f57a184a555b0c58d97c77e09268598d8c4c60d2ea77d", + "nonce" : "7858c0f32c2ed54f", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -672,8 +790,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a094b663897de987d5a5ceba67796d1df9c7e5f5145cd2342ad87b6d065ecde894883abefb0f334e3acbc0c0", - "lastblockhash" : "e7c72d4a61a09444f2d2943d8d082e8cdac1435b71028353e6ff844873ccec30", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0b3fdfcbef5c525dbb62f57a184a555b0c58d97c77e09268598d8c4c60d2ea77d887858c0f32c2ed54fc0c0", + "lastblockhash" : "6605eef6ead056d45d2b56c83703faad6172fb0081e486f9f249949fe7d5e953", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -710,7 +828,7 @@ "wrongStateRoot" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a0776fad25ff482621c89ec92445f9d94f66a3b85acd96ef10d4fdc57ec3cf5fa9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0f99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903aa0fb69849347ef970d17cc5f13c41e54557a35c7047bd67a845d0c6021fea45b3fa05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557177a680a0e3da7eeb0673c29f6d834aba69806398d489385acdc2f3ba8ac684ffd508defa8854cac331df56361cf863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0a8a9158d5959148d489d6a0b3d6d83cfa81d61e7e3fcb1198ed083cb52842215a081aa6240b34ed33abbb2c2b91ca948a2ee2b8e01a9ceb9803839afdcbdeb79a1c0" + "rlp" : "0xf90262f901f9a0edcba92aa67f033d719c6d1b619c6a53df9a572219b9e553e4949e5e11e42be7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0f99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903aa00220feb94650793c6e5b5c82da3bc726257b8578952f2007f5a43a221cf644dda05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4eb80a03655fc3d30ce560424d4276b783df42363da9127557f80b452f0057e0093303e882db7f68a9bac0f8df863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0172577eb4010360f0104a92844e03b56ac437157135ca3e22a5ed6326e0ecfc9a01e27afa553dd478cf4881a671e8da268c9cb5dfa00cdc25539a14268cc069527c0" } ], "genesisBlockHeader" : { @@ -720,9 +838,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "776fad25ff482621c89ec92445f9d94f66a3b85acd96ef10d4fdc57ec3cf5fa9", - "mixHash" : "385b4bffb7b533ac510736f7350778086b629cfe89be11bdc07362e5b55029a5", - "nonce" : "065d56d415c6aa32", + "hash" : "edcba92aa67f033d719c6d1b619c6a53df9a572219b9e553e4949e5e11e42be7", + "mixHash" : "88af4ef320f4e007fe1eb3b683fdf9adbf38c98e8d4e350bed853e2bb63552bd", + "nonce" : "7bf2e2bf22b302c9", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -731,8 +849,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0385b4bffb7b533ac510736f7350778086b629cfe89be11bdc07362e5b55029a588065d56d415c6aa32c0c0", - "lastblockhash" : "776fad25ff482621c89ec92445f9d94f66a3b85acd96ef10d4fdc57ec3cf5fa9", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a088af4ef320f4e007fe1eb3b683fdf9adbf38c98e8d4e350bed853e2bb63552bd887bf2e2bf22b302c9c0c0", + "lastblockhash" : "edcba92aa67f033d719c6d1b619c6a53df9a572219b9e553e4949e5e11e42be7", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -769,7 +887,7 @@ "wrongTimestamp" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a004e093f74ca345acfa7f9937543ad2decb4e7f9af0c95727c8b5a06f9406a8faa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa06bfe92fe8e2d747dff04a01ddd66d2672351ca67988e9f2dc30fa780cd9f05c8a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b8454c98c8080a03d3e7303d9a0a35f6dc8daf18e87882355d151c94ccd567dc35a1fae5acec2d588e84459defbe3e7b6f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca0cafe9452e7a37396339d2093b6b6efe0f69857acc7e9804a7c7c8df5107d6237a0baa18322cd05d89e3111ef81f4ab79912aeae93a5a1740eb2e3a5602ba7598f5c0" + "rlp" : "0xf90262f901f9a0325d37a5c37719331172d7d393211fa6f768c27cd6caf54134d0f821769404aaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0c33dadd6c3c8060f83d1f94e481b0940ea2bdea2dc32d773205bcc6083856f43a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b8454c98c8080a0fc1df352eae9084145df1a657decd03ef7fd842798f4ef3ac9090c2faf0095f28858d51dbe68417246f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca021a1e6616055d70e7d5e47789985356469bc6027c5515c9ed758ce80b6874d17a0d270a747a2c1fdb4b6bbd4b7465db93a72cb13068e196a04c7b4660ae5625175c0" } ], "genesisBlockHeader" : { @@ -779,9 +897,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "04e093f74ca345acfa7f9937543ad2decb4e7f9af0c95727c8b5a06f9406a8fa", - "mixHash" : "cbda32a16e5af050a76cc260b0d40d6fe147059cccc4436873d834d84f92aa0b", - "nonce" : "81e5d0975917faec", + "hash" : "325d37a5c37719331172d7d393211fa6f768c27cd6caf54134d0f821769404aa", + "mixHash" : "136c26720914f9bd3a463d9b77845cd9e87072f741a7816c20fcde7f0788765d", + "nonce" : "58912a71e2613c86", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -790,8 +908,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0cbda32a16e5af050a76cc260b0d40d6fe147059cccc4436873d834d84f92aa0b8881e5d0975917faecc0c0", - "lastblockhash" : "04e093f74ca345acfa7f9937543ad2decb4e7f9af0c95727c8b5a06f9406a8fa", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0136c26720914f9bd3a463d9b77845cd9e87072f741a7816c20fcde7f0788765d8858912a71e2613c86c0c0", + "lastblockhash" : "325d37a5c37719331172d7d393211fa6f768c27cd6caf54134d0f821769404aa", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -828,7 +946,7 @@ "wrongTransactionsTrie" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a00da149d94bb1a3296507424cf46cc722151c628beaf5417cbd9b20ce168d541aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa055e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557177ac80a0c1f8ef3218bb72ee11cabcac7bb745caa29ce7391cdb67fc45fef396c9670bdc881237dbd2888df697f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0bf73e0d0dcda9773a898d2122d09f9e608274f8ba724a1987d2f606be4169809a02ab7dde281bf138f1dfda161100d731c725ea8f73e6158105e034135a91655d9c0" + "rlp" : "0xf90262f901f9a06a3767b6a08363f58f77cfa98fc68a70279cecc75e1961967851b9cdd04210c9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa055e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4f280a0bf84dfbf14c6f38086a79c92c5544cb40793646234a78ac75e30430f436743a788faf2ad3f0d068414f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba042bf238a8911d8c3606b17b889a5eb28cd9615b92a3786f2ec9923dc8a583982a073fe353a68edd8e3ef69b6bbfcd7c2e4aa5ac4cd30799359022e992a0b05a33fc0" } ], "genesisBlockHeader" : { @@ -838,9 +956,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "0da149d94bb1a3296507424cf46cc722151c628beaf5417cbd9b20ce168d541a", - "mixHash" : "fa8c8b1330f0d305db969d083e94a23cf9691372ce535c63d10881922285af8c", - "nonce" : "2cebdf39cdcf6511", + "hash" : "6a3767b6a08363f58f77cfa98fc68a70279cecc75e1961967851b9cdd04210c9", + "mixHash" : "12f8ecbe70493ad82c374c2790718cb4cbe715811e368b59e5571194aeab640e", + "nonce" : "43ede73455d20c96", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -849,8 +967,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0fa8c8b1330f0d305db969d083e94a23cf9691372ce535c63d10881922285af8c882cebdf39cdcf6511c0c0", - "lastblockhash" : "0da149d94bb1a3296507424cf46cc722151c628beaf5417cbd9b20ce168d541a", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a012f8ecbe70493ad82c374c2790718cb4cbe715811e368b59e5571194aeab640e8843ede73455d20c96c0c0", + "lastblockhash" : "6a3767b6a08363f58f77cfa98fc68a70279cecc75e1961967851b9cdd04210c9", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", @@ -887,7 +1005,7 @@ "wrongUncleHash" : { "blocks" : [ { - "rlp" : "0xf90262f901f9a075c1d09b246fc5325caf2ac5f1674cdae7866f575ac531ad1dc01ea66821133ba00dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa0c8cd1d94a37eeba942bca1c417b8ef95c7fbbf4a3cdb7c72ebb590eba462cd14a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557177af80a02a52ae694a0f2e08c0e5df95a64b5523ccfbffe234a8b045d674c0c09bb3df418874791692338348d6f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ca05cd0036147259815d89511154d5912e968def824434d36e46745b7d80ad9a604a05e3165d52ec8e2a7099f4c21830b8f25a99d8c3579f3b6c645f5e9c2c885569ec0" + "rlp" : "0xf90262f901f9a02fdc5ea2e08e8ae80a0aed1efc05125f25e5f109f3c6d0e2e71e663c20efd382a00dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b3afc95220fb6e2df7fca71206d36e81b458ecfaff6c18b1c3414d30ad6b64efa06923d4c8153b65641c6d4474e419e2ee39805bf80f7e898428f8a7db312505a5a05e7d8bf8bc817405813b0866e3bfa1ad048f982be5b81ab17b4db03266b24b26b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b84557ff4f680a07e8315ad74c3e73b3a0e0ca1b34d33d244c27fa3863a76f131bea4f561fee93a888358852fea734303f863f861800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d87821388801ba0195aff059a6627625b77818df5cd44a4aa84c21a2afcc60fd92531ac00860503a0f1fa453ebdacb26ebfcc302a5fc3fa9e4fec0646dfbfe4e45fad937a868fd76dc0" } ], "genesisBlockHeader" : { @@ -897,9 +1015,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "75c1d09b246fc5325caf2ac5f1674cdae7866f575ac531ad1dc01ea66821133b", - "mixHash" : "9ec415d83e4b8f85bb80f25c77183b70bc73de7831e01062858b74524c0c9fc7", - "nonce" : "48fe540a3bd532ac", + "hash" : "2fdc5ea2e08e8ae80a0aed1efc05125f25e5f109f3c6d0e2e71e663c20efd382", + "mixHash" : "caebfc33a6b7811665aefadc1104c5d32aec2a1637a468c157c6de7ffcec13c9", + "nonce" : "9eddc636c8cb7c86", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -908,8 +1026,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a09ec415d83e4b8f85bb80f25c77183b70bc73de7831e01062858b74524c0c9fc78848fe540a3bd532acc0c0", - "lastblockhash" : "75c1d09b246fc5325caf2ac5f1674cdae7866f575ac531ad1dc01ea66821133b", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0b7829295a16db7cae65a071afbb272390f893dc1b0d3f098504148a7056f8056a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0caebfc33a6b7811665aefadc1104c5d32aec2a1637a468c157c6de7ffcec13c9889eddc636c8cb7c86c0c0", + "lastblockhash" : "2fdc5ea2e08e8ae80a0aed1efc05125f25e5f109f3c6d0e2e71e663c20efd382", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x64", diff --git a/tests/files/BlockTests/bcUncleHeaderValiditiy.json b/tests/files/BlockTests/bcUncleHeaderValiditiy.json index 608e345da..cb57d05ed 100644 --- a/tests/files/BlockTests/bcUncleHeaderValiditiy.json +++ b/tests/files/BlockTests/bcUncleHeaderValiditiy.json @@ -9,28 +9,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "faf88420835b29e20e9819a6160ebb73a155a8cd547f2a3013a67d7056f54f42", - "mixHash" : "913f9c34fef9165288351a349c7d4542678f4c158caf20918c5e86ae9d6dea72", - "nonce" : "15a314625ff5ddec", + "hash" : "4b10a7c3fbff1e908ef9bc0c44f41583e9e59f887e60cdd65ef0e5385dc6fab4", + "mixHash" : "ad1fd8a02a3102a925afb719d3e73b0f6683230bf09719b920fa69d2bef411a1", + "nonce" : "a76764550b0f5f55", "number" : "0x01", - "parentHash" : "bd2977fef3e5f70ef767e4df71b9a0528e578ea162a86873e4fa6d17bc28c230", + "parentHash" : "611bb4eefd9d9f09a33df2c63059c637d7dd7b2e93391de1edbc546ff31cc75e", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x55550164", - "transactionsTrie" : "ba41bee508f4dbb16fe8919f9370bd035ee907495f8395bb8bbffbd6bd68eb24", + "timestamp" : "0x557fea12", + "transactionsTrie" : "131ddef1489989143823976a5923c98a222f5ebf04ed7b24c4ce31f6fff6b138", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0bd2977fef3e5f70ef767e4df71b9a0528e578ea162a86873e4fa6d17bc28c230a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0ba41bee508f4dbb16fe8919f9370bd035ee907495f8395bb8bbffbd6bd68eb24a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845555016480a0913f9c34fef9165288351a349c7d4542678f4c158caf20918c5e86ae9d6dea728815a314625ff5ddecf862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0c669f7163ea9c2d3a9d41ba992a946f661d3e36ad8a8642ddeaa203d8b1eb704a0fe988533aa4a852f17b7fd3050b2aa7b3d6bc82886a9d182c56e0bc42a5438eec0", + "rlp" : "0xf90261f901f9a0611bb4eefd9d9f09a33df2c63059c637d7dd7b2e93391de1edbc546ff31cc75ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0131ddef1489989143823976a5923c98a222f5ebf04ed7b24c4ce31f6fff6b138a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882520884557fea1280a0ad1fd8a02a3102a925afb719d3e73b0f6683230bf09719b920fa69d2bef411a188a76764550b0f5f55f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca083e3f79d08cb5930fe40e6d5eb31c6f339363529cdbbf10cbfe5dc786b86ea21a077f3cef0ff992b0fb4e405e054c2077e6af1a4108f08fd2c9ad9e68cd40aaa65c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0xc669f7163ea9c2d3a9d41ba992a946f661d3e36ad8a8642ddeaa203d8b1eb704", - "s" : "0xfe988533aa4a852f17b7fd3050b2aa7b3d6bc82886a9d182c56e0bc42a5438ee", + "r" : "0x83e3f79d08cb5930fe40e6d5eb31c6f339363529cdbbf10cbfe5dc786b86ea21", + "s" : "0x77f3cef0ff992b0fb4e405e054c2077e6af1a4108f08fd2c9ad9e68cd40aaa65", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", + "v" : "0x1c", "value" : "0x0a" } ], @@ -45,28 +45,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "b999e4d623696a156ad6a57c0e99b8f106029fce21efabbf05fd3b71a7346ff4", - "mixHash" : "0fc08cfb5f0253f7262a5a39c04cc12f232a8eb45f931a75ecd7e5a3e6b65341", - "nonce" : "dc28f00060ef7592", + "hash" : "e1cbc5496b4f812419efa4ee0608a3b13ceb9f37d86b33d5ffa37318614f61c7", + "mixHash" : "fdf8d895953f84ed3fc4c300a2a31340065ba2ed61854b9e3a459e0dd7d4a6ca", + "nonce" : "9caac7aaa86927cd", "number" : "0x02", - "parentHash" : "faf88420835b29e20e9819a6160ebb73a155a8cd547f2a3013a67d7056f54f42", + "parentHash" : "4b10a7c3fbff1e908ef9bc0c44f41583e9e59f887e60cdd65ef0e5385dc6fab4", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x55550167", - "transactionsTrie" : "70f8efcebdd7ec387bb024964af2df2af53717a7440cf47554d0964657dfe412", + "timestamp" : "0x557fea14", + "transactionsTrie" : "2661fd12fa821f1d2f563eec4a93346278d288dbc417851b8791b604ac74cc4a", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0faf88420835b29e20e9819a6160ebb73a155a8cd547f2a3013a67d7056f54f42a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea070f8efcebdd7ec387bb024964af2df2af53717a7440cf47554d0964657dfe412a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd8825208845555016780a00fc08cfb5f0253f7262a5a39c04cc12f232a8eb45f931a75ecd7e5a3e6b6534188dc28f00060ef7592f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca00ca044ba50a108425a8829a0d2becb39bceee8a80da5b636abe340287e5e3c7ba032c91afcbea4aa08a75291b758104aeb711d512ee591da727ffca22fa2e352f2c0", + "rlp" : "0xf90261f901f9a04b10a7c3fbff1e908ef9bc0c44f41583e9e59f887e60cdd65ef0e5385dc6fab4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea02661fd12fa821f1d2f563eec4a93346278d288dbc417851b8791b604ac74cc4aa05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd882520884557fea1480a0fdf8d895953f84ed3fc4c300a2a31340065ba2ed61854b9e3a459e0dd7d4a6ca889caac7aaa86927cdf862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0c9c1ddf464d43b6019c409f3436cefa9b2edcae2a422e3b97e40cd7449d3a790a0810abdd17eac3ca0ee9222ada03f2331058519138e56c7fcb3b58c4df9517704c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x0ca044ba50a108425a8829a0d2becb39bceee8a80da5b636abe340287e5e3c7b", - "s" : "0x32c91afcbea4aa08a75291b758104aeb711d512ee591da727ffca22fa2e352f2", + "r" : "0xc9c1ddf464d43b6019c409f3436cefa9b2edcae2a422e3b97e40cd7449d3a790", + "s" : "0x810abdd17eac3ca0ee9222ada03f2331058519138e56c7fcb3b58c4df9517704", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", + "v" : "0x1b", "value" : "0x0a" } ], @@ -81,28 +81,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "a6eb3d409a9d4fcdc8d2d75ab33fb3c023e2ceec4d8936e7fd107a6dbe28470a", - "mixHash" : "35a82c47abc98ea114bc354d68707da8edbfb31b959b69536304c34d22bea5b7", - "nonce" : "3ac923c23e1593ef", + "hash" : "d968d2d34979c3c993744608d48e80fc21248628811fd4c7e652e06e42a077fc", + "mixHash" : "da9bfc38cde54aa134b22590f2072aba128a9e6dcdd4db2546f3b02581ba9ee7", + "nonce" : "5600908c687c23bf", "number" : "0x03", - "parentHash" : "b999e4d623696a156ad6a57c0e99b8f106029fce21efabbf05fd3b71a7346ff4", + "parentHash" : "e1cbc5496b4f812419efa4ee0608a3b13ceb9f37d86b33d5ffa37318614f61c7", "receiptTrie" : "2b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78", "stateRoot" : "a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2", - "timestamp" : "0x5555016a", - "transactionsTrie" : "c9b0f949595f5f18d7626193148e062870da82d82d2ab4e4de2ac5b2dde70754", - "uncleHash" : "94b1f7e669a6b833eabfee173a66665a127c0ac03c6e3cbd85df8845c198b022" + "timestamp" : "0x557fea15", + "transactionsTrie" : "6f25bf8357a3c2a25ba928aa4ca5eafc4f2a8abd823959b534eb8c7d4e2af836", + "uncleHash" : "19228fe88e3d00b4ee6e0d8dd215f6a744ef32138879b65d3fcf20d335939e50" }, - "rlp" : "0xf9045df901f9a0b999e4d623696a156ad6a57c0e99b8f106029fce21efabbf05fd3b71a7346ff4a094b1f7e669a6b833eabfee173a66665a127c0ac03c6e3cbd85df8845c198b022948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a0c9b0f949595f5f18d7626193148e062870da82d82d2ab4e4de2ac5b2dde70754a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd8825208845555016a80a035a82c47abc98ea114bc354d68707da8edbfb31b959b69536304c34d22bea5b7883ac923c23e1593eff862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba08013f62730adcd70e98b07e02d4cb9186f1b5800979547330c22b365f6c7d9d3a0e01282d81b8dd8b41703e31a522b153b2d72f784a676e573854652618028c2aff901faf901f7a0faf88420835b29e20e9819a6160ebb73a155a8cd547f2a3013a67d7056f54f42a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd880845555016a80a0c45261dd899c6f7554bbbbd6f07464e681fcb587ed2fe29ad8c017d682abaac588f416b4f8415127d2", + "rlp" : "0xf9045df901f9a0e1cbc5496b4f812419efa4ee0608a3b13ceb9f37d86b33d5ffa37318614f61c7a019228fe88e3d00b4ee6e0d8dd215f6a744ef32138879b65d3fcf20d335939e50948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a06f25bf8357a3c2a25ba928aa4ca5eafc4f2a8abd823959b534eb8c7d4e2af836a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd882520884557fea1580a0da9bfc38cde54aa134b22590f2072aba128a9e6dcdd4db2546f3b02581ba9ee7885600908c687c23bff862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca00c08596a78fa940274ffdc4aab5e6feab9cf6cefabe6f4da3b332763a2d9d896a0f6e8aded667702e9803599611dd38accc9e2c06b81125cc589c674623374a8d5f901faf901f7a04b10a7c3fbff1e908ef9bc0c44f41583e9e59f887e60cdd65ef0e5385dc6fab4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd88084557fea1580a01024bb277fbd84527b4d31c5768e6a332393f20f9a23c748cc49aece3b5d6118880e5e2ee702d1315a", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x02", - "r" : "0x8013f62730adcd70e98b07e02d4cb9186f1b5800979547330c22b365f6c7d9d3", - "s" : "0xe01282d81b8dd8b41703e31a522b153b2d72f784a676e573854652618028c2af", + "r" : "0x0c08596a78fa940274ffdc4aab5e6feab9cf6cefabe6f4da3b332763a2d9d896", + "s" : "0xf6e8aded667702e9803599611dd38accc9e2c06b81125cc589c674623374a8d5", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", + "v" : "0x1c", "value" : "0x0a" } ], @@ -114,14 +114,14 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "f1ec67402905204c9cf1c1afcc8911d432c986d89437b7c611c440ca6f62608c", - "mixHash" : "c45261dd899c6f7554bbbbd6f07464e681fcb587ed2fe29ad8c017d682abaac5", - "nonce" : "f416b4f8415127d2", + "hash" : "37fb5b24f8cb5cce6652304ba1ad4c8aa7235ce02bac0184567f8bb03ac73aa1", + "mixHash" : "1024bb277fbd84527b4d31c5768e6a332393f20f9a23c748cc49aece3b5d6118", + "nonce" : "0e5e2ee702d1315a", "number" : "0x02", - "parentHash" : "faf88420835b29e20e9819a6160ebb73a155a8cd547f2a3013a67d7056f54f42", + "parentHash" : "4b10a7c3fbff1e908ef9bc0c44f41583e9e59f887e60cdd65ef0e5385dc6fab4", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x5555016a", + "timestamp" : "0x557fea15", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" } @@ -135,9 +135,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "bd2977fef3e5f70ef767e4df71b9a0528e578ea162a86873e4fa6d17bc28c230", - "mixHash" : "7008f402b62e9f5c37612906f238ea2a6ea5957666aff170b0a6be8468e0f541", - "nonce" : "3a162adb0dd64d96", + "hash" : "611bb4eefd9d9f09a33df2c63059c637d7dd7b2e93391de1edbc546ff31cc75e", + "mixHash" : "970689d77fb975396a9f030259f2134e42d9125f75693f7a990a27f74c8d8b3b", + "nonce" : "b7fd58d68844cc3f", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -146,8 +146,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a07008f402b62e9f5c37612906f238ea2a6ea5957666aff170b0a6be8468e0f541883a162adb0dd64d96c0c0", - "lastblockhash" : "a6eb3d409a9d4fcdc8d2d75ab33fb3c023e2ceec4d8936e7fd107a6dbe28470a", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0970689d77fb975396a9f030259f2134e42d9125f75693f7a990a27f74c8d8b3b88b7fd58d68844cc3fc0c0", + "lastblockhash" : "d968d2d34979c3c993744608d48e80fc21248628811fd4c7e652e06e42a077fc", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x1e", @@ -198,28 +198,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "48969515fd4d604d9a52bcd2a409645d82349e8357b2afc390dd54fcf1fd6b05", - "mixHash" : "eebc9aeb85dedb95afe9a30eb24fa8f8944f2e6e747bfbd44021520f4f46ca2e", - "nonce" : "5b9132df0cbcf3af", + "hash" : "f6cde068d90ac7249393e1df15a5782845fcc4f98cc494d7cdbe8bb0277ac93f", + "mixHash" : "85bb14195bb2557c3cd71172447cc55a0546a3809d701df563dbb310fe639a23", + "nonce" : "9d56cf657fdb9dcb", "number" : "0x01", - "parentHash" : "90d08b283a218fbf47741eb81e8407e73ad81165c461c5feb4982db4e1af33f2", + "parentHash" : "c983e3a988acd69a643b4229ff8ffab4990cf48a502b7ff925c2ac3f71f4b1b2", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x5555016d", - "transactionsTrie" : "9ea12f7f18ee6192c1adbbadaaea431f6c6d153973095ad32cfbc27d4299b920", + "timestamp" : "0x557fea1a", + "transactionsTrie" : "bed128895f83effdcb26c69c7f7ef7a8334f1bd310f134c12ee6f7be088cc196", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a090d08b283a218fbf47741eb81e8407e73ad81165c461c5feb4982db4e1af33f2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a09ea12f7f18ee6192c1adbbadaaea431f6c6d153973095ad32cfbc27d4299b920a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845555016d80a0eebc9aeb85dedb95afe9a30eb24fa8f8944f2e6e747bfbd44021520f4f46ca2e885b9132df0cbcf3aff862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0381218916f2aff52f3c433b0f43cc14001d6d4e43b5d2fa1bc614d152abf8b56a053d07600981741f58170925e25899f028e0f2bbf37289e916747a9ddd04c6d50c0", + "rlp" : "0xf90261f901f9a0c983e3a988acd69a643b4229ff8ffab4990cf48a502b7ff925c2ac3f71f4b1b2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0bed128895f83effdcb26c69c7f7ef7a8334f1bd310f134c12ee6f7be088cc196a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882520884557fea1a80a085bb14195bb2557c3cd71172447cc55a0546a3809d701df563dbb310fe639a23889d56cf657fdb9dcbf862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0aebb457be8703f8c7d67db77ac57e9aebf2a82bef4c2abe4183a8e72e70e327ba0c27e3b68f57b97bb71c2eb066290db9c8edb04369c97011d588c95c5aa4c09d2c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x381218916f2aff52f3c433b0f43cc14001d6d4e43b5d2fa1bc614d152abf8b56", - "s" : "0x53d07600981741f58170925e25899f028e0f2bbf37289e916747a9ddd04c6d50", + "r" : "0xaebb457be8703f8c7d67db77ac57e9aebf2a82bef4c2abe4183a8e72e70e327b", + "s" : "0xc27e3b68f57b97bb71c2eb066290db9c8edb04369c97011d588c95c5aa4c09d2", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", + "v" : "0x1b", "value" : "0x0a" } ], @@ -234,26 +234,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "06e12b02ccc5dccd4b4266008a1bcab0c9f40bb35a7788b2c48783b3c95bd014", - "mixHash" : "f873e110fe8a1e94e7aca44402ee0c84206b996c89cbbfa65f65da7dac2067a5", - "nonce" : "2d4ab2a10a099747", + "hash" : "4055efe3689bf3f83cbbbf7dbf825188a3698ca70239b4c9a2fc3009b5eb8296", + "mixHash" : "5412c2d1713374d5546f94103c647497d2623607c71aeebc710ebb8671b3366b", + "nonce" : "a5b7a5aa559a2a87", "number" : "0x02", - "parentHash" : "48969515fd4d604d9a52bcd2a409645d82349e8357b2afc390dd54fcf1fd6b05", + "parentHash" : "f6cde068d90ac7249393e1df15a5782845fcc4f98cc494d7cdbe8bb0277ac93f", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x5555016f", - "transactionsTrie" : "30293f3165a4af49c84bba02651c40fa96aa051f0fc576e127f2b0aeae42598e", + "timestamp" : "0x557fea1b", + "transactionsTrie" : "21d7c9bb42cecbc4e0fbc0b86a907e27d5301ba313cc5eac35c6db3e44340ab8", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a048969515fd4d604d9a52bcd2a409645d82349e8357b2afc390dd54fcf1fd6b05a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea030293f3165a4af49c84bba02651c40fa96aa051f0fc576e127f2b0aeae42598ea05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd8825208845555016f80a0f873e110fe8a1e94e7aca44402ee0c84206b996c89cbbfa65f65da7dac2067a5882d4ab2a10a099747f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba067fed55c7e608d37f39566ec37facc775d83792fb535378d4d9c988edb2e31d2a049176000ba20cd0d68bf11d32ab40fa4b647e0e1da476c35afd216e2e069b13cc0", + "rlp" : "0xf90261f901f9a0f6cde068d90ac7249393e1df15a5782845fcc4f98cc494d7cdbe8bb0277ac93fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea021d7c9bb42cecbc4e0fbc0b86a907e27d5301ba313cc5eac35c6db3e44340ab8a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd882520884557fea1b80a05412c2d1713374d5546f94103c647497d2623607c71aeebc710ebb8671b3366b88a5b7a5aa559a2a87f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0106991745143be1ec27a9c9450ac5307b5557964dd1a0ff1273fdd0fa426968fa0a1f592b1ba4bde12e09e33a76fe87971c3b4ce5ccf1f6fae4513aa31c1698cc2c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x67fed55c7e608d37f39566ec37facc775d83792fb535378d4d9c988edb2e31d2", - "s" : "0x49176000ba20cd0d68bf11d32ab40fa4b647e0e1da476c35afd216e2e069b13c", + "r" : "0x106991745143be1ec27a9c9450ac5307b5557964dd1a0ff1273fdd0fa426968f", + "s" : "0xa1f592b1ba4bde12e09e33a76fe87971c3b4ce5ccf1f6fae4513aa31c1698cc2", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -263,7 +263,7 @@ ] }, { - "rlp" : "0xf9045df901f9a006e12b02ccc5dccd4b4266008a1bcab0c9f40bb35a7788b2c48783b3c95bd014a0c660f7cbb8f6a2c6398e1e45ef7909a8ccad6e8e818d9f8e7336dea2b3bd2635948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a02dc00df6f2a20d546ff18a6b6ae0a7ddae435fb8424faafa5bab88c652d9816fa02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd8825208845555017280a0a5e5cb8a60a338a0ae4a07a4bbcf1d9511bea3022829ac13e61da5bd21c541838891de71c04eab1c42f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca055a4b88a8f468c2144a1a7849ce40aa3cda2778bf9b60b874fe76c20839521e6a08a791f81d3dcac2ac1216ab97f86de81f43fba1d57c757a83e722d69adf9c9bbf901faf901f7a048969515fd4d604d9a52bcd2a409645d82349e8357b2afc390dd54fcf1fd6b05a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000102832fefd880845555017280a04b0163a2018fe94981bf974e89d9928a66a6698a6e1ba4e2a35d6be20a5c8b4f88e758c8e3e1d55d0a" + "rlp" : "0xf9045df901f9a04055efe3689bf3f83cbbbf7dbf825188a3698ca70239b4c9a2fc3009b5eb8296a0b19aa35dc941d28c67ea07bd08e55a2bcdc3a4c115e1ab26ce5660fb26600012948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a047e40e1257339bbbde4a7044a6be79fddc7c2a10bbc0eb78a9f1cfddea59bd42a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd882520884557fea1d80a03d895978d27b77e8884b47a21dbd7ad3575e907c458a1ac784f47892174ba5a588533e297fada35f0af862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0c042baeec3abd55e810b401706ba48e58a3b08599e2b0edc6a330fa774debed0a0ab7886e593e1585b7f93a3782157ae52129fe18862feabf12d35fa0869f0f00ef901faf901f7a0f6cde068d90ac7249393e1df15a5782845fcc4f98cc494d7cdbe8bb0277ac93fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000102832fefd88084557fea1d80a0ee35a97e5c5b6699d18eb9d08a0a46fea96f498724ab9e5deed47d2d19d39eb9887656acd926144286" } ], "genesisBlockHeader" : { @@ -273,9 +273,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "90d08b283a218fbf47741eb81e8407e73ad81165c461c5feb4982db4e1af33f2", - "mixHash" : "2e498b5cade393f581d9fb0daa6d990598f598307112e6b3a3eccb8cee8304eb", - "nonce" : "a1002e453c4b6083", + "hash" : "c983e3a988acd69a643b4229ff8ffab4990cf48a502b7ff925c2ac3f71f4b1b2", + "mixHash" : "c86af0cd547c9f8bc16b3bebdd9e3ebfc86954603651776231e8e79b4459f33c", + "nonce" : "cece7d13e2fe59e4", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -284,8 +284,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a02e498b5cade393f581d9fb0daa6d990598f598307112e6b3a3eccb8cee8304eb88a1002e453c4b6083c0c0", - "lastblockhash" : "06e12b02ccc5dccd4b4266008a1bcab0c9f40bb35a7788b2c48783b3c95bd014", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0c86af0cd547c9f8bc16b3bebdd9e3ebfc86954603651776231e8e79b4459f33c88cece7d13e2fe59e4c0c0", + "lastblockhash" : "4055efe3689bf3f83cbbbf7dbf825188a3698ca70239b4c9a2fc3009b5eb8296", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", @@ -329,26 +329,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "8d16d8500f12a8dfd3793a3ebd29e164dc0ac5eca393404de7439f242c9d0991", - "mixHash" : "9ec901a7cdb1ff500d754e253f83dc71294e72d333187d540343ea81269f7f90", - "nonce" : "eb728226ff3a3c13", + "hash" : "fefae693e783163eaf6facb8fc3dbacfde6585b3ebb1b443fb3f757677069794", + "mixHash" : "0f0f2d7c8db01dd0bbbbbd047aba83ab98112aaa9cdf86d43f33efea35f1502b", + "nonce" : "d6ffc45d6e745e83", "number" : "0x01", - "parentHash" : "055c5d9a9c8465ab099a64bf8bb393a8d3bd1abdd14cd2749b155115ca80a1db", + "parentHash" : "2acd9bb0743dc559c897b8613eda723fd895e3abb15fb3eb6a6d305b36a63954", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x55550176", - "transactionsTrie" : "583bf55bf693d83e95b4e9593bf4c1f2a402365536c338ea030aac4137c285eb", + "timestamp" : "0x557fea20", + "transactionsTrie" : "a251e1fdb141137994329ecdadb6799660093bcef3b0d4caf2af4bce7226f339", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90260f901f9a0055c5d9a9c8465ab099a64bf8bb393a8d3bd1abdd14cd2749b155115ca80a1dba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0583bf55bf693d83e95b4e9593bf4c1f2a402365536c338ea030aac4137c285eba0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845555017680a09ec901a7cdb1ff500d754e253f83dc71294e72d333187d540343ea81269f7f9088eb728226ff3a3c13f861f85f80018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0e864c73df821c9babefca008f6e4851a2c6f5c637d4d010e8003b8b473f6351d9f03d2c622fd99387243d323a3e88bbc1a1f9583f3a1543ea8e7e4f567ad45bcc0", + "rlp" : "0xf90261f901f9a02acd9bb0743dc559c897b8613eda723fd895e3abb15fb3eb6a6d305b36a63954a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0a251e1fdb141137994329ecdadb6799660093bcef3b0d4caf2af4bce7226f339a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882520884557fea2080a00f0f2d7c8db01dd0bbbbbd047aba83ab98112aaa9cdf86d43f33efea35f1502b88d6ffc45d6e745e83f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca05053dfee8de087ef8b6c37b2e39090885bf63c8ca35f48c9edd678118e0f9df7a092caa685f1d97fd7ee4ae8b2c40797e087de7d6da821e4977024e23f71b991bdc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0xe864c73df821c9babefca008f6e4851a2c6f5c637d4d010e8003b8b473f6351d", - "s" : "0x03d2c622fd99387243d323a3e88bbc1a1f9583f3a1543ea8e7e4f567ad45bc", + "r" : "0x5053dfee8de087ef8b6c37b2e39090885bf63c8ca35f48c9edd678118e0f9df7", + "s" : "0x92caa685f1d97fd7ee4ae8b2c40797e087de7d6da821e4977024e23f71b991bd", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1c", "value" : "0x0a" @@ -365,28 +365,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "53894eee2d3ffa6d27a6e7d1a5d41a044047009bda1855cac67cf667f5b8c8b2", - "mixHash" : "fd0397fbb0db49ed91b792e4ab780a6716d570788e49e41158391f81c9c8703c", - "nonce" : "237437077cca191c", + "hash" : "d7d8747dc16a3b37b58f2f8f5e63b4ba338339f286c049148eb1f5d5542b359c", + "mixHash" : "0f80342c244441aae61898f9bf4e6b50aa5aa021c35b90197e7259b65d0d3f2a", + "nonce" : "9959cfe967b6250c", "number" : "0x02", - "parentHash" : "8d16d8500f12a8dfd3793a3ebd29e164dc0ac5eca393404de7439f242c9d0991", + "parentHash" : "fefae693e783163eaf6facb8fc3dbacfde6585b3ebb1b443fb3f757677069794", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x55550179", - "transactionsTrie" : "4bd04db776d5aab61443a7d2de4100b5adda3eb72ed1c97dc5ef896141f7f663", + "timestamp" : "0x557fea23", + "transactionsTrie" : "8f614e76ed346b8096afd61f08e559d3f4f00445658566ddcce80d19bc3154e6", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a08d16d8500f12a8dfd3793a3ebd29e164dc0ac5eca393404de7439f242c9d0991a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea04bd04db776d5aab61443a7d2de4100b5adda3eb72ed1c97dc5ef896141f7f663a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd8825208845555017980a0fd0397fbb0db49ed91b792e4ab780a6716d570788e49e41158391f81c9c8703c88237437077cca191cf862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca021a0e58298790c43d83e66d1cecbda17cdeec6bfe78d00d51bac8a6cc49ee36ea0fb0a3b2e2226aaac6c07b2a9a8f2e83ee1dfd934251985a6d993d72b00d52c5ec0", + "rlp" : "0xf90261f901f9a0fefae693e783163eaf6facb8fc3dbacfde6585b3ebb1b443fb3f757677069794a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea08f614e76ed346b8096afd61f08e559d3f4f00445658566ddcce80d19bc3154e6a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd882520884557fea2380a00f80342c244441aae61898f9bf4e6b50aa5aa021c35b90197e7259b65d0d3f2a889959cfe967b6250cf862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba00b56ebf6c62bfe049e18b1ea4b03f7411b162ddbe5cb8235d97a18d27c25f679a003b0e88c0e4edcee2eb9894685ef98c3769ca43d2506ab6c34659cf662a7bdd3c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x21a0e58298790c43d83e66d1cecbda17cdeec6bfe78d00d51bac8a6cc49ee36e", - "s" : "0xfb0a3b2e2226aaac6c07b2a9a8f2e83ee1dfd934251985a6d993d72b00d52c5e", + "r" : "0x0b56ebf6c62bfe049e18b1ea4b03f7411b162ddbe5cb8235d97a18d27c25f679", + "s" : "0x03b0e88c0e4edcee2eb9894685ef98c3769ca43d2506ab6c34659cf662a7bdd3", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", + "v" : "0x1b", "value" : "0x0a" } ], @@ -394,7 +394,7 @@ ] }, { - "rlp" : "0xf9045df901f9a053894eee2d3ffa6d27a6e7d1a5d41a044047009bda1855cac67cf667f5b8c8b2a0638b44e1dd59c7ea7f6ec6dc2f36ced3395306c0e5e926413fd8c7527adeabad948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a090e4f4346323b80f7506c37ae03a90b61294d9ea43ae3cc93a9dbe8ae20c797da02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd8825208845555017c80a0c5821acb4fadf3a9e726fa6c389a120b276ef6e416a327784bfde9a227e8e5c48878618a14506e4173f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba08ee856d60282b5e466b094661627be2df1d4eb4495b8cd12cf0e5dea864bf4f0a0c8b3416752b94914c16456e70ff745262cada5a7dd0c4cd8cc5e55d5277204c5f901faf901f7a08d16d8500f12a8dfd3793a3ebd29e164dc0ac5eca393404de7439f242c9d0991a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008301ffff02832fefd880845555017c80a089ffafddb6d913fd5a2916d7000cd165bf3663781840688b2737cc5daa4c9da888d078106bdfd5cd43" + "rlp" : "0xf9045df901f9a0d7d8747dc16a3b37b58f2f8f5e63b4ba338339f286c049148eb1f5d5542b359ca021757cc95d7e0e2a26f3650d2e5cf84c961fccc588fa10e28619e563d1545aec948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a00372a6314a85e52beca61b6fe6dd538d966b724f12a131f45b6b9eace7baeb9fa02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd882520884557fea2680a0de9d181195d07b0c88641992b8461a31143e9e813061c16e1c6aa7424277efb288ba6915200769c997f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca03adf0c2db892c2d7f748691e5a920d8976aec11c300a24cccd178d0e69a15c28a0dd7d71b780fc5eb8f4d7fff06206db6cf944c43070c373fb14c4113480594d6af901faf901f7a0fefae693e783163eaf6facb8fc3dbacfde6585b3ebb1b443fb3f757677069794a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008301ffff02832fefd88084557fea2680a020eb2bc5cf105d975f3355caf8bc549d0554c2b5c23c03ed69fc8d88694db0c588429eb2c19392709f" } ], "genesisBlockHeader" : { @@ -404,9 +404,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "055c5d9a9c8465ab099a64bf8bb393a8d3bd1abdd14cd2749b155115ca80a1db", - "mixHash" : "bceefded1246bf0c0bd93484f6d67cb77717935c7af8576988a2000bfab9a407", - "nonce" : "e791bce41cc7b793", + "hash" : "2acd9bb0743dc559c897b8613eda723fd895e3abb15fb3eb6a6d305b36a63954", + "mixHash" : "18f5ac7d90121919f0eec6c1bb284481a4e0a0401a2133fca06e0f01db259615", + "nonce" : "729d21785bf56efa", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -415,8 +415,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0bceefded1246bf0c0bd93484f6d67cb77717935c7af8576988a2000bfab9a40788e791bce41cc7b793c0c0", - "lastblockhash" : "53894eee2d3ffa6d27a6e7d1a5d41a044047009bda1855cac67cf667f5b8c8b2", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a018f5ac7d90121919f0eec6c1bb284481a4e0a0401a2133fca06e0f01db25961588729d21785bf56efac0c0", + "lastblockhash" : "d7d8747dc16a3b37b58f2f8f5e63b4ba338339f286c049148eb1f5d5542b359c", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", @@ -460,28 +460,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "3a07c31b431b92668bceb0f65f5567e500fd2f96a73b4d444d3f3a8d593aa67f", - "mixHash" : "be69c6ef60b63801e47cb973edb4b8e861cd94dfce9f8f2d82b7e39e0e1e1b5a", - "nonce" : "b847ced9affb2d12", + "hash" : "74bb7a98cb2aa3a285c75d2b476c127f5cf9bac00f0a60a3432129884b6375f3", + "mixHash" : "a4a51d2ebc8286df2bc2e412e53d847f65a238bc1fc4faac3c153115acda2b02", + "nonce" : "1510fe6e53a69ef1", "number" : "0x01", - "parentHash" : "f029709eb89ec010fe61f07a54925f1d1772030c2af0359842be07429dc4bc2a", + "parentHash" : "42a3279d65af8f7d15fd370048c5035c600286e4623afe988435f9bb35a8a762", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x5555017f", - "transactionsTrie" : "d15ff8eac215a3a96220081ad3d6baaab76f652daaef3c4c4478afe1e674c59c", + "timestamp" : "0x557fea2a", + "transactionsTrie" : "b733dd575da3bcd610e089ee5b8be0917cf5d1a2c35427dad6549877d5a2c903", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0f029709eb89ec010fe61f07a54925f1d1772030c2af0359842be07429dc4bc2aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0d15ff8eac215a3a96220081ad3d6baaab76f652daaef3c4c4478afe1e674c59ca0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd8825208845555017f80a0be69c6ef60b63801e47cb973edb4b8e861cd94dfce9f8f2d82b7e39e0e1e1b5a88b847ced9affb2d12f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0bd2c211918a746a2033e972150238e344f42e7b411813c85e265e4ef4a48c2c2a06ce56e51fcc8181e1a98ef1608c63a989e9496cdda0103f01eb0c7a8049a9b19c0", + "rlp" : "0xf90261f901f9a042a3279d65af8f7d15fd370048c5035c600286e4623afe988435f9bb35a8a762a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0b733dd575da3bcd610e089ee5b8be0917cf5d1a2c35427dad6549877d5a2c903a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea2a80a0a4a51d2ebc8286df2bc2e412e53d847f65a238bc1fc4faac3c153115acda2b02881510fe6e53a69ef1f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba02f6fdd979ab4f7c6bb010fad075de570e79b7eb97bb0ae725c8d2109b435a260a0d6f226c5afe7dd5ec23fbc5e1c1b9e0e2ae66ce5e9a243f0fe5a6ed8f4636df7c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0xbd2c211918a746a2033e972150238e344f42e7b411813c85e265e4ef4a48c2c2", - "s" : "0x6ce56e51fcc8181e1a98ef1608c63a989e9496cdda0103f01eb0c7a8049a9b19", + "r" : "0x2f6fdd979ab4f7c6bb010fad075de570e79b7eb97bb0ae725c8d2109b435a260", + "s" : "0xd6f226c5afe7dd5ec23fbc5e1c1b9e0e2ae66ce5e9a243f0fe5a6ed8f4636df7", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", + "v" : "0x1b", "value" : "0x0a" } ], @@ -496,28 +496,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "8619878aefd8f5f3bb38df752c8fcd836ee80d2f62205cad7da52121787ae192", - "mixHash" : "f4190b88a5613bf1a9ca5dd90afac26f8356bff6724c44df63860ce2f3b2bdba", - "nonce" : "23958da3e4d38dc6", + "hash" : "da6acbbea03d49b7a39b5a08c462575e3b092d5baa6779c0dc79aa2cb6f801c0", + "mixHash" : "4d54bb1289489308f788add836c400dd9f3e89d8f70784ec28adac946dd62bb3", + "nonce" : "52ad73b8296927a1", "number" : "0x02", - "parentHash" : "3a07c31b431b92668bceb0f65f5567e500fd2f96a73b4d444d3f3a8d593aa67f", + "parentHash" : "74bb7a98cb2aa3a285c75d2b476c127f5cf9bac00f0a60a3432129884b6375f3", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x55550184", - "transactionsTrie" : "49f105b74255212e17ecac59b8ae9daf9ee85e5f5237025a5feed88ef1442d95", + "timestamp" : "0x557fea2e", + "transactionsTrie" : "f06292dff80d0a85ddf962b552c22a2b8f44285690abc942075d6b3550971f63", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a03a07c31b431b92668bceb0f65f5567e500fd2f96a73b4d444d3f3a8d593aa67fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea049f105b74255212e17ecac59b8ae9daf9ee85e5f5237025a5feed88ef1442d95a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd8825208845555018480a0f4190b88a5613bf1a9ca5dd90afac26f8356bff6724c44df63860ce2f3b2bdba8823958da3e4d38dc6f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba050073eee69655032876ec7820e02509e7410700b4f40cad13efcee4e518cbb23a0b739b571077206ab47af7298784fa2a9dacc4bc68ef61c395d004547ab32cfc3c0", + "rlp" : "0xf90261f901f9a074bb7a98cb2aa3a285c75d2b476c127f5cf9bac00f0a60a3432129884b6375f3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0f06292dff80d0a85ddf962b552c22a2b8f44285690abc942075d6b3550971f63a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea2e80a04d54bb1289489308f788add836c400dd9f3e89d8f70784ec28adac946dd62bb38852ad73b8296927a1f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0a854e41b3c28fdf2a4aa78dd653f9f9a1d2ada74afdae29ff89583940fdcefdba0670cf5fd2a73674d8a9dfc5e0882859406ee998195c0e86088ae08aa387ed58dc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x50073eee69655032876ec7820e02509e7410700b4f40cad13efcee4e518cbb23", - "s" : "0xb739b571077206ab47af7298784fa2a9dacc4bc68ef61c395d004547ab32cfc3", + "r" : "0xa854e41b3c28fdf2a4aa78dd653f9f9a1d2ada74afdae29ff89583940fdcefdb", + "s" : "0x670cf5fd2a73674d8a9dfc5e0882859406ee998195c0e86088ae08aa387ed58d", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", + "v" : "0x1c", "value" : "0x0a" } ], @@ -525,7 +525,7 @@ ] }, { - "rlp" : "0xf9045df901f9a08619878aefd8f5f3bb38df752c8fcd836ee80d2f62205cad7da52121787ae192a09fffb969a29c70ddd46da55eea08f7b07453cdeb8e83862cbf860f26e6b93467948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a0961557d89e3ac76c77ef8eacece1fd2ddaeb38d9693bdd06c5fe566cd8856e51a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd8825208845555018980a055c14437a1c2e76c15448cdcc13cb0c290a3a03097be581da7e741e4e6424507886f188037cb659d84f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba01d354753350459414574425456d5f421d58d55b8f3bdb427fd58302d4ff17232a07979b8dc9049b364aca1d13becc783c207325b4cb02623e53d3e72d3f55ef311f901faf901f7a03a07c31b431b92668bceb0f65f5567e500fd2f96a73b4d444d3f3a8d593aa67fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830385bf02832fefd880845555018980a03926a75d208055d5ce218c84586aadaa977c11d08846f90e6a1d276c1a0e3e67884eb19a13e9e640a8" + "rlp" : "0xf9045df901f9a0da6acbbea03d49b7a39b5a08c462575e3b092d5baa6779c0dc79aa2cb6f801c0a0ee0832479fb8481013db5226cb2229626b9e18999ac6a71d16e73af3ecbb56e2948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a072835939cff5ef70169f91f2d23f1a140ef0958a55b1f98293c97c85071cc20ca02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea3080a0b9b6f7a4454b874125904bc198c36aea2587a1177358299c7c3c7f8adb2b630488fd248f691ab0472df862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca04c2ef9f6f53ea3aeb60ae031fac41113e9bb7aaf492eeaf06c01594f40eaa414a04e298f0249c5afcb66909ce5b1f1ece3f2b2108e2f59f21e22ed55ab5ef97466f901faf901f7a074bb7a98cb2aa3a285c75d2b476c127f5cf9bac00f0a60a3432129884b6375f3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830385bf02832fefd88084557fea3080a01b4948c6c7375a4c48652b5e3b7d7ca0ce24653a42082bd453b68a4d9d6785658897be20ead7dbacba" } ], "genesisBlockHeader" : { @@ -535,9 +535,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "f029709eb89ec010fe61f07a54925f1d1772030c2af0359842be07429dc4bc2a", - "mixHash" : "01a3421ac34cf63bb508749996c3f1067392591041e2ca2548a1c4cd637e68b3", - "nonce" : "fd96d67e24298e0d", + "hash" : "42a3279d65af8f7d15fd370048c5035c600286e4623afe988435f9bb35a8a762", + "mixHash" : "848ed43f722b7cd58f7564a40dcf6a0760c0068cbaa40ce815a69d60e1d7e7fe", + "nonce" : "79732f45e8c80f83", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -546,8 +546,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a001a3421ac34cf63bb508749996c3f1067392591041e2ca2548a1c4cd637e68b388fd96d67e24298e0dc0c0", - "lastblockhash" : "8619878aefd8f5f3bb38df752c8fcd836ee80d2f62205cad7da52121787ae192", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0848ed43f722b7cd58f7564a40dcf6a0760c0068cbaa40ce815a69d60e1d7e7fe8879732f45e8c80f83c0c0", + "lastblockhash" : "da6acbbea03d49b7a39b5a08c462575e3b092d5baa6779c0dc79aa2cb6f801c0", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", @@ -591,26 +591,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "cf323a783b3fe34c132d7f24677361a3607e4e2fc250b1e7219657f0ea8ac3d3", - "mixHash" : "06611f525418504b266994532bfe2aa772deeb996a68025fbc84f703789917f5", - "nonce" : "6df4f8d8986744ff", + "hash" : "4cda6d5ea90d0e1522f9652ae0676384fcd7b1dd943dc2998722d9d42ac43e06", + "mixHash" : "536eaa9d9deac48d737b314041765e36fb37eab7705a92f6de6e32389241a4ac", + "nonce" : "5069aadb6b0170e6", "number" : "0x01", - "parentHash" : "3ab50f686522706a1b2891189bcc68a1f0c1d6d7a39534c875bd6217fe6111f8", + "parentHash" : "d1b2eaca11a6f6e85b9d773217aa822ba4bac8940851a808d766d38567c24b20", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x5555018e", - "transactionsTrie" : "e2e5d2d40df98b30088e0351ac4f8d8e696309ff349ac14ad6920990866a3068", + "timestamp" : "0x557fea35", + "transactionsTrie" : "2351d1017ac82d42c2f380e36cc6ca7682434856e91e7c02751cd9a30fa44c2e", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a03ab50f686522706a1b2891189bcc68a1f0c1d6d7a39534c875bd6217fe6111f8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0e2e5d2d40df98b30088e0351ac4f8d8e696309ff349ac14ad6920990866a3068a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd8825208845555018e80a006611f525418504b266994532bfe2aa772deeb996a68025fbc84f703789917f5886df4f8d8986744fff862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0989f4f53bd8e59e1596c6b1fa61b514fb3de633cadf02f4fb34a50180f3dad08a0e138376bf165ed29cd0ae86c220e5ab39419b7018392a3b82eaef4b0c47c9762c0", + "rlp" : "0xf90261f901f9a0d1b2eaca11a6f6e85b9d773217aa822ba4bac8940851a808d766d38567c24b20a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a02351d1017ac82d42c2f380e36cc6ca7682434856e91e7c02751cd9a30fa44c2ea0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea3580a0536eaa9d9deac48d737b314041765e36fb37eab7705a92f6de6e32389241a4ac885069aadb6b0170e6f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0c77df764ec05ae298c7165bdf9fc5c7e4af3536b03dc7892f4e0231883e12f54a0c627814fc59c39816c6e93440d13d56296b59b58f8bf69a961faedef6e1d3639c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x989f4f53bd8e59e1596c6b1fa61b514fb3de633cadf02f4fb34a50180f3dad08", - "s" : "0xe138376bf165ed29cd0ae86c220e5ab39419b7018392a3b82eaef4b0c47c9762", + "r" : "0xc77df764ec05ae298c7165bdf9fc5c7e4af3536b03dc7892f4e0231883e12f54", + "s" : "0xc627814fc59c39816c6e93440d13d56296b59b58f8bf69a961faedef6e1d3639", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -627,28 +627,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "7d7bf8f2f1d132e3824ce7e0b9fc949b0852e97eba4accb3b3463225e13b1272", - "mixHash" : "e4abf3ad6f22f2dda205ab2664455615e7d890bc34d7daf69aaaad1db315a028", - "nonce" : "5fe990f304e6951f", + "hash" : "7d1d2aefdb088fdde2613f09c4566bbe71ab52e42b8ef781cc09b8acab2cae5c", + "mixHash" : "59c54a8f997182b9a061ca93587d51fb15d40c010fe8c85161969f41ec7cac44", + "nonce" : "f086a0edb895354b", "number" : "0x02", - "parentHash" : "cf323a783b3fe34c132d7f24677361a3607e4e2fc250b1e7219657f0ea8ac3d3", + "parentHash" : "4cda6d5ea90d0e1522f9652ae0676384fcd7b1dd943dc2998722d9d42ac43e06", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x55550191", - "transactionsTrie" : "484692674cff0bead4998d371d7c8f8b6b6f59f5ddb91b69af4b31be7b086f80", + "timestamp" : "0x557fea37", + "transactionsTrie" : "5b8eb45f5507df294b7a59d12b627bcbe6cd54023a915d45ddfdbd8610bfe7aa", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0cf323a783b3fe34c132d7f24677361a3607e4e2fc250b1e7219657f0ea8ac3d3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0484692674cff0bead4998d371d7c8f8b6b6f59f5ddb91b69af4b31be7b086f80a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd8825208845555019180a0e4abf3ad6f22f2dda205ab2664455615e7d890bc34d7daf69aaaad1db315a028885fe990f304e6951ff862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca028e5f56214ed9715cb1920cdcccc5da7c7daf38caecd21d9d0afd0ec4cd54496a0d29269981fb045b927bf90336afbc0eb2f320e7ab0599cc806dabc2974119caec0", + "rlp" : "0xf90261f901f9a04cda6d5ea90d0e1522f9652ae0676384fcd7b1dd943dc2998722d9d42ac43e06a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea05b8eb45f5507df294b7a59d12b627bcbe6cd54023a915d45ddfdbd8610bfe7aaa05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea3780a059c54a8f997182b9a061ca93587d51fb15d40c010fe8c85161969f41ec7cac4488f086a0edb895354bf862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba026be035eda9f6dcfd81ae76e92db8dc418c28abff2bb96eb88e265a0f1efef72a041ca3928663107624e51e094d744958cd1a159eb29ae2955ef93889c6fb13acbc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x28e5f56214ed9715cb1920cdcccc5da7c7daf38caecd21d9d0afd0ec4cd54496", - "s" : "0xd29269981fb045b927bf90336afbc0eb2f320e7ab0599cc806dabc2974119cae", + "r" : "0x26be035eda9f6dcfd81ae76e92db8dc418c28abff2bb96eb88e265a0f1efef72", + "s" : "0x41ca3928663107624e51e094d744958cd1a159eb29ae2955ef93889c6fb13acb", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", + "v" : "0x1b", "value" : "0x0a" } ], @@ -663,26 +663,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "7785a240ca1a6b956214518e2ed68e194ac0228e84adb8ed6e888082e49acd1e", - "mixHash" : "e71085ee4b6a0791043cda699d60be0b53f1cd58a66676b33a94499151d00c75", - "nonce" : "3e6e7cc272ac573a", + "hash" : "190e7baace3947b1c5786e4ce143451b4e339f77085ea4fe9a45e7f3c4cfa7b1", + "mixHash" : "9aa86ae7a684161ddc5112d1616a07129f43b0585252efdbc419c6accdd41ae9", + "nonce" : "215b7ac12fc51862", "number" : "0x03", - "parentHash" : "7d7bf8f2f1d132e3824ce7e0b9fc949b0852e97eba4accb3b3463225e13b1272", + "parentHash" : "7d1d2aefdb088fdde2613f09c4566bbe71ab52e42b8ef781cc09b8acab2cae5c", "receiptTrie" : "2b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78", "stateRoot" : "a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2", - "timestamp" : "0x55550193", - "transactionsTrie" : "7b571f35f17f728cf91e64cce3b662a30296f2214ce82a085a10903d108f3909", - "uncleHash" : "325e355c820ff6f4c56b11bf8d356e14f7100f5853f797f53b89a8a6b9e6adcd" + "timestamp" : "0x557fea3a", + "transactionsTrie" : "26615a960522fde5db004d80af29788199b6d22355a879a9d98854ee140119fb", + "uncleHash" : "18dba1a4bfce045b462a8dd0afc76da97822814b1fd2e0d6f3c2e495a519c890" }, - "rlp" : "0xf9045df901f9a07d7bf8f2f1d132e3824ce7e0b9fc949b0852e97eba4accb3b3463225e13b1272a0325e355c820ff6f4c56b11bf8d356e14f7100f5853f797f53b89a8a6b9e6adcd948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a07b571f35f17f728cf91e64cce3b662a30296f2214ce82a085a10903d108f3909a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd8825208845555019380a0e71085ee4b6a0791043cda699d60be0b53f1cd58a66676b33a94499151d00c75883e6e7cc272ac573af862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0e1e6d4a72aa2d3cee4f18202c854da9753e5edeba688edeecd3b2bc40da38154a0c3a33ea1365d4a4924a9fa286c8798d0ec39ed2f545b7a462bf27422011dffbef901faf901f7a0cf323a783b3fe34c132d7f24677361a3607e4e2fc250b1e7219657f0ea8ac3d3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd980845555019380a06959fe650d3412c2ca7b1dc1a6cac2f50caf8b4f349319c9647577203cc22b4688da5cdbe124a57ec1", + "rlp" : "0xf9045df901f9a07d1d2aefdb088fdde2613f09c4566bbe71ab52e42b8ef781cc09b8acab2cae5ca018dba1a4bfce045b462a8dd0afc76da97822814b1fd2e0d6f3c2e495a519c890948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a026615a960522fde5db004d80af29788199b6d22355a879a9d98854ee140119fba02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea3a80a09aa86ae7a684161ddc5112d1616a07129f43b0585252efdbc419c6accdd41ae988215b7ac12fc51862f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba041331e7f2f2c78c7372a643791b3273794346dbfbd66cf76846fbffa75c8001ea04ec74fd7351555330778783039ed84ec0f216ddd9fa9eba90a0474c3e466e57ff901faf901f7a04cda6d5ea90d0e1522f9652ae0676384fcd7b1dd943dc2998722d9d42ac43e06a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd98084557fea3a80a080f3b70ced14d0e9ddf2264a94e847df8fbb6ad42574b75bb37c08f89f9913c588c0e11419b693f4c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x02", - "r" : "0xe1e6d4a72aa2d3cee4f18202c854da9753e5edeba688edeecd3b2bc40da38154", - "s" : "0xc3a33ea1365d4a4924a9fa286c8798d0ec39ed2f545b7a462bf27422011dffbe", + "r" : "0x41331e7f2f2c78c7372a643791b3273794346dbfbd66cf76846fbffa75c8001e", + "s" : "0x4ec74fd7351555330778783039ed84ec0f216ddd9fa9eba90a0474c3e466e57f", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -696,14 +696,14 @@ "extraData" : "0x", "gasLimit" : "0x2fefd9", "gasUsed" : "0x00", - "hash" : "562cfb8cc5e76b6f84ff6027bb51d38c36382db73ce1eaf440fc037449809e3d", - "mixHash" : "6959fe650d3412c2ca7b1dc1a6cac2f50caf8b4f349319c9647577203cc22b46", - "nonce" : "da5cdbe124a57ec1", + "hash" : "1a25cb07a52901454f2792d6e09f1669141bb9a05f3691eabc9bcaaed97bbf35", + "mixHash" : "80f3b70ced14d0e9ddf2264a94e847df8fbb6ad42574b75bb37c08f89f9913c5", + "nonce" : "c0e11419b693f4c0", "number" : "0x02", - "parentHash" : "cf323a783b3fe34c132d7f24677361a3607e4e2fc250b1e7219657f0ea8ac3d3", + "parentHash" : "4cda6d5ea90d0e1522f9652ae0676384fcd7b1dd943dc2998722d9d42ac43e06", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x55550193", + "timestamp" : "0x557fea3a", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" } @@ -717,9 +717,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "3ab50f686522706a1b2891189bcc68a1f0c1d6d7a39534c875bd6217fe6111f8", - "mixHash" : "297b6abffe46ada1e1dc8a6229851857b1a1865c1d2ca2c6d5cb26aa2aa545c0", - "nonce" : "e3dbb40d35f00ab0", + "hash" : "d1b2eaca11a6f6e85b9d773217aa822ba4bac8940851a808d766d38567c24b20", + "mixHash" : "4f85b187392fa2c50235cbb4ac21969ef94ec0eced913ff28df8b27faa5d665c", + "nonce" : "ee1091b109d8b8c9", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -728,8 +728,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0297b6abffe46ada1e1dc8a6229851857b1a1865c1d2ca2c6d5cb26aa2aa545c088e3dbb40d35f00ab0c0c0", - "lastblockhash" : "7785a240ca1a6b956214518e2ed68e194ac0228e84adb8ed6e888082e49acd1e", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a04f85b187392fa2c50235cbb4ac21969ef94ec0eced913ff28df8b27faa5d665c88ee1091b109d8b8c9c0c0", + "lastblockhash" : "190e7baace3947b1c5786e4ce143451b4e339f77085ea4fe9a45e7f3c4cfa7b1", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x1e", @@ -780,28 +780,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "7fc58c7227d9ad4cd3f8de017a93e3a9018a8e71cb251945b54466c19a15d868", - "mixHash" : "5dd7203323bc8e695ce959699aea0770ccbd839befa2aa46415ee3499078b3bb", - "nonce" : "3b693c4a65f982a4", + "hash" : "631e8d1ac1f21f008fa48decf940b853527a18a6a3ba3c01c982312e9218695f", + "mixHash" : "14fa07dd095f21dfa27969ca6f4e9f6402863d5b5f11e8c3d2079cf36317981b", + "nonce" : "e39ba598870ebad5", "number" : "0x01", - "parentHash" : "14d040a99b6cb025d543c6c89f1e61e80538fc6e34499096516af9fd9fc94723", + "parentHash" : "b98a1b2d7b53794f4a4c2f400c7e9812236bbe3c56db8719b110285394aadfc2", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x55550199", - "transactionsTrie" : "1c6b6c321cfaeed08b2fb4e7dbe7d6bc622586e47b3d877996809921d0ed81d1", + "timestamp" : "0x557fea3e", + "transactionsTrie" : "10a1bd33be5e93c1120bc3bb8e6b278737d0c1543ed07ee3acce3d64f965bd8d", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a014d040a99b6cb025d543c6c89f1e61e80538fc6e34499096516af9fd9fc94723a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a01c6b6c321cfaeed08b2fb4e7dbe7d6bc622586e47b3d877996809921d0ed81d1a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd8825208845555019980a05dd7203323bc8e695ce959699aea0770ccbd839befa2aa46415ee3499078b3bb883b693c4a65f982a4f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba091bb9f31e7ddb36cd6f7772cf909a9c84229f482d3d851204c357b3fef6a07f9a0337bcf61cc0aab74498bdcfece1d345c85458f7b6a616fa0dff33fce8a704240c0", + "rlp" : "0xf90261f901f9a0b98a1b2d7b53794f4a4c2f400c7e9812236bbe3c56db8719b110285394aadfc2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a010a1bd33be5e93c1120bc3bb8e6b278737d0c1543ed07ee3acce3d64f965bd8da0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea3e80a014fa07dd095f21dfa27969ca6f4e9f6402863d5b5f11e8c3d2079cf36317981b88e39ba598870ebad5f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0cccab1681ef0b8a8f654ac319b2a41316a0fe10120b61e2c097257bfb1181e71a04831b0f41d75f08549468d213d4ba7f02bb30f64ef88caeacbbe9af4e6483edbc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x91bb9f31e7ddb36cd6f7772cf909a9c84229f482d3d851204c357b3fef6a07f9", - "s" : "0x337bcf61cc0aab74498bdcfece1d345c85458f7b6a616fa0dff33fce8a704240", + "r" : "0xcccab1681ef0b8a8f654ac319b2a41316a0fe10120b61e2c097257bfb1181e71", + "s" : "0x4831b0f41d75f08549468d213d4ba7f02bb30f64ef88caeacbbe9af4e6483edb", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", + "v" : "0x1c", "value" : "0x0a" } ], @@ -816,26 +816,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "13172534ea6a9fa1e9416df01f7583a365857fe1804c5684ae2fb751d13c90a8", - "mixHash" : "d9813fa1c2d51e1ecd3c61411c162f2dee9cd90834e36e6e27ab5e86b46e2869", - "nonce" : "9663fc44a97f1328", + "hash" : "279dd0a522f74e930182901c9c448c67896b009d5478cb09182f0d7923102cda", + "mixHash" : "754b8c6c206ad44f61646baf1c823719da1ccfdb14fe388e88cbbb821014c27f", + "nonce" : "5e6c5517dabd4d91", "number" : "0x02", - "parentHash" : "7fc58c7227d9ad4cd3f8de017a93e3a9018a8e71cb251945b54466c19a15d868", + "parentHash" : "631e8d1ac1f21f008fa48decf940b853527a18a6a3ba3c01c982312e9218695f", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x5555019d", - "transactionsTrie" : "dbc11390747af31405ffafb3631fe9ee43b6d4a5103e50392f7a640c858adcf9", + "timestamp" : "0x557fea41", + "transactionsTrie" : "98a3fa5f71b2230d4d02c0a97dd399efafcb90a901877e7ce31f7e80b3872b37", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a07fc58c7227d9ad4cd3f8de017a93e3a9018a8e71cb251945b54466c19a15d868a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0dbc11390747af31405ffafb3631fe9ee43b6d4a5103e50392f7a640c858adcf9a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd8825208845555019d80a0d9813fa1c2d51e1ecd3c61411c162f2dee9cd90834e36e6e27ab5e86b46e2869889663fc44a97f1328f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba08ca44fd9f339ddb0c596ec0f23d74793029357e1dbb832cf9ab151fbc17e10faa044850eb49de6dcd15c35c9c2fe7799d30d6492d4deb45c1f824ac5232fbf826ac0", + "rlp" : "0xf90261f901f9a0631e8d1ac1f21f008fa48decf940b853527a18a6a3ba3c01c982312e9218695fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea098a3fa5f71b2230d4d02c0a97dd399efafcb90a901877e7ce31f7e80b3872b37a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea4180a0754b8c6c206ad44f61646baf1c823719da1ccfdb14fe388e88cbbb821014c27f885e6c5517dabd4d91f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0c3417cba9e622b8f7fdb5c311223404fac7fb996d5a6253c8cf07a08ec96f9e1a02ffe46053f80edaf2d1233f382bb1cfc9b5234a525803886cb74f879d438d20ec0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x8ca44fd9f339ddb0c596ec0f23d74793029357e1dbb832cf9ab151fbc17e10fa", - "s" : "0x44850eb49de6dcd15c35c9c2fe7799d30d6492d4deb45c1f824ac5232fbf826a", + "r" : "0xc3417cba9e622b8f7fdb5c311223404fac7fb996d5a6253c8cf07a08ec96f9e1", + "s" : "0x2ffe46053f80edaf2d1233f382bb1cfc9b5234a525803886cb74f879d438d20e", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -852,26 +852,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "446832a213aa1af12baef490b5a3344c400d6a2e196b7e4dbe8f7026c0e91e86", - "mixHash" : "6446c9eaf571d019f34704c2b48872dfcabe159022f004206ef86c506957f0f6", - "nonce" : "b848eb983073c49a", + "hash" : "05cb7f185b7b2250b5c2eb39077bf8f6b8df752ecd14e728177950ae5852221f", + "mixHash" : "cf5d2d875578aedf2dedd2fbebd406d0c587d3a05cc1ab51f75bd83602335892", + "nonce" : "9756214ef565cb82", "number" : "0x03", - "parentHash" : "13172534ea6a9fa1e9416df01f7583a365857fe1804c5684ae2fb751d13c90a8", + "parentHash" : "279dd0a522f74e930182901c9c448c67896b009d5478cb09182f0d7923102cda", "receiptTrie" : "2b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78", "stateRoot" : "a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2", - "timestamp" : "0x5555019e", - "transactionsTrie" : "d7402cf1671e587f7ddf5aea9b4558283e6fb8d5c8fa28e94972cb1c5a3a52a5", - "uncleHash" : "7730f689fb363374263e82aea0de5470fcda07098ccdfb58e0699f3649bb8d53" + "timestamp" : "0x557fea43", + "transactionsTrie" : "bc94a38729725d880d54d2159f7630b3ae74484d8c771afc9814d0421cb7642f", + "uncleHash" : "157404f6ae5760e3d73c801b92ba1bf9a9e5f8de2be16bb954e342c24260d538" }, - "rlp" : "0xf9045df901f9a013172534ea6a9fa1e9416df01f7583a365857fe1804c5684ae2fb751d13c90a8a07730f689fb363374263e82aea0de5470fcda07098ccdfb58e0699f3649bb8d53948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a0d7402cf1671e587f7ddf5aea9b4558283e6fb8d5c8fa28e94972cb1c5a3a52a5a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd8825208845555019e80a06446c9eaf571d019f34704c2b48872dfcabe159022f004206ef86c506957f0f688b848eb983073c49af862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba033ea5525314bc6547359d1c83ea4a0203c419d6697831450835d6b520b223ecba025dc3e78ae4093fa580ff61558c153dab93ba0cc2d4c75e32aee313c14481a37f901faf901f7a07fc58c7227d9ad4cd3f8de017a93e3a9018a8e71cb251945b54466c19a15d868a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd780845555019e80a0491f0b640ed25995c5e44dcc04de01bda2d4781360172276760fc9daf099d886881a3670228de5f62d", + "rlp" : "0xf9045df901f9a0279dd0a522f74e930182901c9c448c67896b009d5478cb09182f0d7923102cdaa0157404f6ae5760e3d73c801b92ba1bf9a9e5f8de2be16bb954e342c24260d538948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a0bc94a38729725d880d54d2159f7630b3ae74484d8c771afc9814d0421cb7642fa02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea4380a0cf5d2d875578aedf2dedd2fbebd406d0c587d3a05cc1ab51f75bd83602335892889756214ef565cb82f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0085c3d1d22a610e0466b8e591fcf6d5ed2f67c9ab7a838d3843d86acbcbcb725a060065afe628ba4878b1796c74fdda234cd32ccfa2b3105715dcdd7435f612da2f901faf901f7a0631e8d1ac1f21f008fa48decf940b853527a18a6a3ba3c01c982312e9218695fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd78084557fea4380a0baab05997ba90b30a4f5fa573fa0facf3a925e252ce9095557984b9099f5a675886ac9226b21ed4ff6", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x02", - "r" : "0x33ea5525314bc6547359d1c83ea4a0203c419d6697831450835d6b520b223ecb", - "s" : "0x25dc3e78ae4093fa580ff61558c153dab93ba0cc2d4c75e32aee313c14481a37", + "r" : "0x085c3d1d22a610e0466b8e591fcf6d5ed2f67c9ab7a838d3843d86acbcbcb725", + "s" : "0x60065afe628ba4878b1796c74fdda234cd32ccfa2b3105715dcdd7435f612da2", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -885,14 +885,14 @@ "extraData" : "0x", "gasLimit" : "0x2fefd7", "gasUsed" : "0x00", - "hash" : "3cd2fe746e16910b70a3174f3b594c348d41b8a567029ceaa09e5d3fa7eb715f", - "mixHash" : "491f0b640ed25995c5e44dcc04de01bda2d4781360172276760fc9daf099d886", - "nonce" : "1a3670228de5f62d", + "hash" : "40228b954d98b01aa588c6291adcc46ee37171050a99e1faede3c1dcfd794c09", + "mixHash" : "baab05997ba90b30a4f5fa573fa0facf3a925e252ce9095557984b9099f5a675", + "nonce" : "6ac9226b21ed4ff6", "number" : "0x02", - "parentHash" : "7fc58c7227d9ad4cd3f8de017a93e3a9018a8e71cb251945b54466c19a15d868", + "parentHash" : "631e8d1ac1f21f008fa48decf940b853527a18a6a3ba3c01c982312e9218695f", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x5555019e", + "timestamp" : "0x557fea43", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" } @@ -906,9 +906,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "14d040a99b6cb025d543c6c89f1e61e80538fc6e34499096516af9fd9fc94723", - "mixHash" : "cc10690e934042e418715ba196972be8a245c0a55c9207da7036fc14e26d91c7", - "nonce" : "17870d004d687fdf", + "hash" : "b98a1b2d7b53794f4a4c2f400c7e9812236bbe3c56db8719b110285394aadfc2", + "mixHash" : "b11086f57c0dbf2c3a9402d1053f988c38de8afff550eef811cc7296cd065e71", + "nonce" : "96373f1fc2c9cbe7", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -917,8 +917,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0cc10690e934042e418715ba196972be8a245c0a55c9207da7036fc14e26d91c78817870d004d687fdfc0c0", - "lastblockhash" : "446832a213aa1af12baef490b5a3344c400d6a2e196b7e4dbe8f7026c0e91e86", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0b11086f57c0dbf2c3a9402d1053f988c38de8afff550eef811cc7296cd065e718896373f1fc2c9cbe7c0c0", + "lastblockhash" : "05cb7f185b7b2250b5c2eb39077bf8f6b8df752ecd14e728177950ae5852221f", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x1e", @@ -959,7 +959,7 @@ } } }, - "timestampTooHigh" : { + "nonceWrong" : { "blocks" : [ { "blockHeader" : { @@ -969,26 +969,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "4bf604ea8f6773747a7ba30df257064b2d7a37a68305ed6c5d28fab0bf5ca9af", - "mixHash" : "71b1f8e0c21a46865aa65e3101957b2b41536c4eb74c5da8ab2864c8fa558067", - "nonce" : "76a898fc2016c17a", + "hash" : "212fa2f874ad9bce6a1d45eb8c923a639b6fe20676f7b274622650b6b98f5b2f", + "mixHash" : "df1fcc2f231cedebdf0b34dd233385fa5cacbabd0d8577c500729de9d053fd96", + "nonce" : "d3145311199b6d87", "number" : "0x01", - "parentHash" : "8271939ad95d33fea21504b3876c7fb06d60e8a50d60b6d71000f3ebfaf037f1", + "parentHash" : "75182b6534c8c6609a2fac84e56915bc0f5157751c78282c302b526113f06fb6", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x555501a2", - "transactionsTrie" : "f5bb5a75e477b36b82eaa7b7a8bcc4e19c93c8010535ca8b87c0dab671d6e6bd", + "timestamp" : "0x557fea48", + "transactionsTrie" : "19720ee77660138e67c53de4cbcbc13b8e63c8061d55b8de1d5168f6765ead05", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a08271939ad95d33fea21504b3876c7fb06d60e8a50d60b6d71000f3ebfaf037f1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0f5bb5a75e477b36b82eaa7b7a8bcc4e19c93c8010535ca8b87c0dab671d6e6bda0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884555501a280a071b1f8e0c21a46865aa65e3101957b2b41536c4eb74c5da8ab2864c8fa5580678876a898fc2016c17af862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba07edbbbacdad2c583f4f961eb57b4a7cc19b64e17cc00250413bda4c564e60a24a0def83a0853368d836592f7382063eae6a1545ff1568408b28681804fc8de5797c0", + "rlp" : "0xf90261f901f9a075182b6534c8c6609a2fac84e56915bc0f5157751c78282c302b526113f06fb6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a019720ee77660138e67c53de4cbcbc13b8e63c8061d55b8de1d5168f6765ead05a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea4880a0df1fcc2f231cedebdf0b34dd233385fa5cacbabd0d8577c500729de9d053fd9688d3145311199b6d87f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0cbadbeff9ab100bb999fb7db1ff46d59edddacef74923433c7d1fe4921e0b97ba0071756ee82880d1939cde6c48b74a55f93006c4834b1835e72bef3e399878e6bc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x7edbbbacdad2c583f4f961eb57b4a7cc19b64e17cc00250413bda4c564e60a24", - "s" : "0xdef83a0853368d836592f7382063eae6a1545ff1568408b28681804fc8de5797", + "r" : "0xcbadbeff9ab100bb999fb7db1ff46d59edddacef74923433c7d1fe4921e0b97b", + "s" : "0x071756ee82880d1939cde6c48b74a55f93006c4834b1835e72bef3e399878e6b", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -1005,26 +1005,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "c3ea81d7ed58c7ed44bea7ab32ab1f0b7bbbcf38dfde0a2cb900d17dba8642e0", - "mixHash" : "bbeaacfde4374a22e9bc55d46ebb817487d66de16823e9d85f2cdd9c1057ff7e", - "nonce" : "7c162b3ff32a6516", + "hash" : "6cd7b78a9d70e9ab6e5e3c7cff6c5486aa476940988988998a253c6789a0af35", + "mixHash" : "14e6c9fdeba9446350189a9286ac29cdd0aeb63a5f136f07de5182567a07914f", + "nonce" : "bcc3dcfc2dfa12d8", "number" : "0x02", - "parentHash" : "4bf604ea8f6773747a7ba30df257064b2d7a37a68305ed6c5d28fab0bf5ca9af", + "parentHash" : "212fa2f874ad9bce6a1d45eb8c923a639b6fe20676f7b274622650b6b98f5b2f", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x555501a6", - "transactionsTrie" : "cd1c608d996954c091273c979158b5a596b650d4ac44f7f02d82411a5cd67a04", + "timestamp" : "0x557fea4b", + "transactionsTrie" : "831c039a91633d70b0ba29dc1243db0566c90e73862a87d9b073ebe80f2f95b8", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a04bf604ea8f6773747a7ba30df257064b2d7a37a68305ed6c5d28fab0bf5ca9afa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0cd1c608d996954c091273c979158b5a596b650d4ac44f7f02d82411a5cd67a04a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884555501a680a0bbeaacfde4374a22e9bc55d46ebb817487d66de16823e9d85f2cdd9c1057ff7e887c162b3ff32a6516f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca025d6bf17253ce9ba787d07d7827ff9740f0fbfa6c0d2da533c89f1bd91c2e032a0f55cca6fbbc9ae892bd1ed8b0394aedfcd18e81443d8de4077ad66a4d42f3e34c0", + "rlp" : "0xf90261f901f9a0212fa2f874ad9bce6a1d45eb8c923a639b6fe20676f7b274622650b6b98f5b2fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0831c039a91633d70b0ba29dc1243db0566c90e73862a87d9b073ebe80f2f95b8a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea4b80a014e6c9fdeba9446350189a9286ac29cdd0aeb63a5f136f07de5182567a07914f88bcc3dcfc2dfa12d8f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca040d89a551344f0d19b0f618e614455b08582cf71068b411e408e9d085cb83023a005dc87a52badc568d2d042d497a555387bbbd81ef81930c39baf2cf8ee6d5fafc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x25d6bf17253ce9ba787d07d7827ff9740f0fbfa6c0d2da533c89f1bd91c2e032", - "s" : "0xf55cca6fbbc9ae892bd1ed8b0394aedfcd18e81443d8de4077ad66a4d42f3e34", + "r" : "0x40d89a551344f0d19b0f618e614455b08582cf71068b411e408e9d085cb83023", + "s" : "0x05dc87a52badc568d2d042d497a555387bbbd81ef81930c39baf2cf8ee6d5faf", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1c", "value" : "0x0a" @@ -1034,7 +1034,7 @@ ] }, { - "rlp" : "0xf9045df901f9a0c3ea81d7ed58c7ed44bea7ab32ab1f0b7bbbcf38dfde0a2cb900d17dba8642e0a0486fe1b671ec67a08b66ff57193f3b1b9193eedd27f8ae666aafb617389e9113948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a0655c8522d5fbb4019a875c6984e3e8a6d7a2c882cc3702f762b6856d1e5e71b1a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884555501aa80a0e97aa998a60d838207c75678d5888c84036dbc5bb8b11089984e90557a3718cf880808efde58f25da0f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0c9fd6abd955a11e418c248f1f15aeb2b82ba8ecdc87e7a074f16da7d9bc4b486a07204dbc8de94586368253abfa097140f1be2831e913a2705ff09e7f16297a14bf901faf901f7a04bf604ea8f6773747a7ba30df257064b2d7a37a68305ed6c5d28fab0bf5ca9afa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830385c002832fefd880845b18d39e80a04ef1db3283064515b120f89e531ec1b61836d768321c1e93116da3c3269f685388eb07dad141bf0902" + "rlp" : "0xf9045df901f9a06cd7b78a9d70e9ab6e5e3c7cff6c5486aa476940988988998a253c6789a0af35a058557918866c827d5c8585a1aad7cdcc649b1f649a216886ae3f41ce73f2b064948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a0d6eec79e306f143482b3b0f70abee962b57671b126bad9ffbf398b48d8857a4ca02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea4c80a0df24c29a76f5dccd7d6c3a1a33bcd966761243ad5dc08fd66049dac408a4b82d8886d1d260e4a98f96f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba02d8e7dcb7db173f17adff3561859fc3a71bc4d08e14996b62bd472e0e114bbe6a020572f2bc55aa7ace094e161bf7633bb316ee2ccee558213e00956698d11d313f901faf901f7a0212fa2f874ad9bce6a1d45eb8c923a639b6fe20676f7b274622650b6b98f5b2fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd88084557fea4c80a044c53f8e2de38550928942cfd90aa5472ab49ec82bba95c3477ecc0e7900f9e688bad524c1790fa83b" } ], "genesisBlockHeader" : { @@ -1044,9 +1044,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "8271939ad95d33fea21504b3876c7fb06d60e8a50d60b6d71000f3ebfaf037f1", - "mixHash" : "102804dc290abd07a4fe1fa4934e61edbc5e02c9a8c2a9de836519b5cf0cfa85", - "nonce" : "532135000aafb9a4", + "hash" : "75182b6534c8c6609a2fac84e56915bc0f5157751c78282c302b526113f06fb6", + "mixHash" : "006cccd756e7b81c5428749c724d691307ab76704bc807144ea5b811e6b25cf5", + "nonce" : "0bb9cfb8f3adfcbb", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -1055,8 +1055,139 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0102804dc290abd07a4fe1fa4934e61edbc5e02c9a8c2a9de836519b5cf0cfa8588532135000aafb9a4c0c0", - "lastblockhash" : "c3ea81d7ed58c7ed44bea7ab32ab1f0b7bbbcf38dfde0a2cb900d17dba8642e0", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0006cccd756e7b81c5428749c724d691307ab76704bc807144ea5b811e6b25cf5880bb9cfb8f3adfcbbc0c0", + "lastblockhash" : "6cd7b78a9d70e9ab6e5e3c7cff6c5486aa476940988988998a253c6789a0af35", + "postState" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x14", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x29a2241af62ca410", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x09184e71fbdc", + "code" : "0x", + "nonce" : "0x02", + "storage" : { + } + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x09184e72a000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "timestampTooHigh" : { + "blocks" : [ + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x038630", + "extraData" : "0x", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x5208", + "hash" : "372aa804dc737dfd950d63046d91c3c078aee0d833cfbfd2797244ad58146a54", + "mixHash" : "ee47da70ceb1f70c8aa05de0a98694e5ebc161c7cc6ac162e54c388b65093976", + "nonce" : "7fe5a73cf8e1f854", + "number" : "0x01", + "parentHash" : "f20d712bce4fb7a223b801adb1548142cc14a583f7a413e1933e2f62f71c5739", + "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", + "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", + "timestamp" : "0x557fea52", + "transactionsTrie" : "9e1194678d4be7f82e88c271d96308bc2810a0d9f15449ced9e6da0062fcc160", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90261f901f9a0f20d712bce4fb7a223b801adb1548142cc14a583f7a413e1933e2f62f71c5739a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a09e1194678d4be7f82e88c271d96308bc2810a0d9f15449ced9e6da0062fcc160a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea5280a0ee47da70ceb1f70c8aa05de0a98694e5ebc161c7cc6ac162e54c388b65093976887fe5a73cf8e1f854f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0550f070ef1e03e2368118c15bc8deb64e0a2e3a880e063c7aeaa6406ec9b81bca08fa22fe68c02e7f09b45106af5cb361fdb028bc34bfea28f335e09632dffdf27c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x04cb2f", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x550f070ef1e03e2368118c15bc8deb64e0a2e3a880e063c7aeaa6406ec9b81bc", + "s" : "0x8fa22fe68c02e7f09b45106af5cb361fdb028bc34bfea28f335e09632dffdf27", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0386a0", + "extraData" : "0x", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x5208", + "hash" : "65df3af12c9f8d77dcfb6032f3b32f4cefeef497ad477c2c7fd2549cf2b128c1", + "mixHash" : "16e51d971cc0c5246970816f7113b05fa85a93d7713d95f0d3ab1b322a613720", + "nonce" : "063df4ff49506cbc", + "number" : "0x02", + "parentHash" : "372aa804dc737dfd950d63046d91c3c078aee0d833cfbfd2797244ad58146a54", + "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", + "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", + "timestamp" : "0x557fea53", + "transactionsTrie" : "ad3a813000c55c0b33148c797b8bdce8ba5fb1aac80a2c66e2f250ca1e51461e", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90261f901f9a0372aa804dc737dfd950d63046d91c3c078aee0d833cfbfd2797244ad58146a54a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0ad3a813000c55c0b33148c797b8bdce8ba5fb1aac80a2c66e2f250ca1e51461ea05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea5380a016e51d971cc0c5246970816f7113b05fa85a93d7713d95f0d3ab1b322a61372088063df4ff49506cbcf862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba02564ca2019d20fc2c99501f3c6bf94dd78ebe96d215c8e1d01ddbf34a4d8cedfa0df6a67c928d7c703eb2b83068bb1551d1665b0673f234aa434ef9656a068b2e8c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x04cb2f", + "gasPrice" : "0x01", + "nonce" : "0x01", + "r" : "0x2564ca2019d20fc2c99501f3c6bf94dd78ebe96d215c8e1d01ddbf34a4d8cedf", + "s" : "0xdf6a67c928d7c703eb2b83068bb1551d1665b0673f234aa434ef9656a068b2e8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "rlp" : "0xf9045df901f9a065df3af12c9f8d77dcfb6032f3b32f4cefeef497ad477c2c7fd2549cf2b128c1a007359f368ed2ee408fd25814c4b618d9daf706e7fe8066d38578c620b31ce558948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a044b9f02f33677c410fcc4f392a3f3667d12d1de92e4700cb59d887e08b74da8ba02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea5580a00a4079ff6fd68e3b3a5e2d28665691f3bb1f5e286420267f05eb64551b69d733881fe0dd388a30c9bdf862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09462f1139967c0cfebd8d74ce4e04211fcf9c2080ea4ec8b192074ed2b38290ca0d60d6748c8a284c7048d5f71658b40f62d8cec762661f5363fcb4ad56a775501f901faf901f7a0372aa804dc737dfd950d63046d91c3c078aee0d833cfbfd2797244ad58146a54a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830385c002832fefd880845b18d39e80a08a0fbf35a5fc532b479ae80eda70bec69c615f2463b3e6c2ee0cdeb0f1c567d488a56e5d9bf1c830a2" + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0386a0", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "f20d712bce4fb7a223b801adb1548142cc14a583f7a413e1933e2f62f71c5739", + "mixHash" : "55e9d50d181eaaac9d1a49af692aa41636c7eb17fc5cc61b68567d0194ae4e74", + "nonce" : "a34f6030fd86054a", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "7dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a055e9d50d181eaaac9d1a49af692aa41636c7eb17fc5cc61b68567d0194ae4e7488a34f6030fd86054ac0c0", + "lastblockhash" : "65df3af12c9f8d77dcfb6032f3b32f4cefeef497ad477c2c7fd2549cf2b128c1", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", @@ -1100,26 +1231,157 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "a28de9ec2cee57445a93d498091565bba1d0e2eea6b5a2c2ae435fced7b40269", - "mixHash" : "2ac81886b15428cfb920d9aa8bc733344c99e082e7ade8df49f84ed8d1bbaf45", - "nonce" : "689f850d0cf6d442", + "hash" : "5ed68bb67a4ef1c931e84e62f855b3cab02fc8b9023779b8149016d03e9bdacc", + "mixHash" : "3178ff7dbd7fb028ad21c65373d2391521e1642fdc3220024e46c002ab3ee604", + "nonce" : "151a514c5c57d93f", "number" : "0x01", - "parentHash" : "f77be32aac97a01fff3fdccc7cd65444333724155938dd3baa159b7a9cd67477", + "parentHash" : "6d0ae8cd327b41291551d7048eb918ca5dc394d28d25402c495faab44e73971e", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x555501b2", - "transactionsTrie" : "25dea3bbd68ef636a982325a703fa22791b12e115ce911666fcf071ec0830334", + "timestamp" : "0x557fea5a", + "transactionsTrie" : "9ef061028b23d18b1a879b43bf46c709bc9fd170eaa35a153a0cafb076bbabe9", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0f77be32aac97a01fff3fdccc7cd65444333724155938dd3baa159b7a9cd67477a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a025dea3bbd68ef636a982325a703fa22791b12e115ce911666fcf071ec0830334a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884555501b280a02ac81886b15428cfb920d9aa8bc733344c99e082e7ade8df49f84ed8d1bbaf4588689f850d0cf6d442f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca08394687a7ae8d5f56ec40f18bcff00a2ec07a6de0ee48f9e666e7219c5e65103a0061c979d857689dca24b07c4663b8eed3a3391c03d69949b1a1d1f5c0dd94d11c0", + "rlp" : "0xf90261f901f9a06d0ae8cd327b41291551d7048eb918ca5dc394d28d25402c495faab44e73971ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a09ef061028b23d18b1a879b43bf46c709bc9fd170eaa35a153a0cafb076bbabe9a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea5a80a03178ff7dbd7fb028ad21c65373d2391521e1642fdc3220024e46c002ab3ee60488151a514c5c57d93ff862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba096c723cb3d61f269fc2e06d4bf63d142e7b82d082f645baae9d753fe08d501c9a09af0b24a490ad680ea82222d32cd516f69b232f7d2e265fbc4d60c43bad9ef83c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x8394687a7ae8d5f56ec40f18bcff00a2ec07a6de0ee48f9e666e7219c5e65103", - "s" : "0x061c979d857689dca24b07c4663b8eed3a3391c03d69949b1a1d1f5c0dd94d11", + "r" : "0x96c723cb3d61f269fc2e06d4bf63d142e7b82d082f645baae9d753fe08d501c9", + "s" : "0x9af0b24a490ad680ea82222d32cd516f69b232f7d2e265fbc4d60c43bad9ef83", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0386a0", + "extraData" : "0x", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x5208", + "hash" : "3f0c95de871aee5c19d760ce7d2b9c128a1c30a09339e942a47326b21f6acb2b", + "mixHash" : "5116c123a7361290685fef2a7e405227747edb791133b95ec1245d0bad71aadf", + "nonce" : "4a5f84c3405aff0e", + "number" : "0x02", + "parentHash" : "5ed68bb67a4ef1c931e84e62f855b3cab02fc8b9023779b8149016d03e9bdacc", + "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", + "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", + "timestamp" : "0x557fea5d", + "transactionsTrie" : "bd4ff120afac4ed3d8ee3eaf3f594aab23055cea9b2593b0ae15219249cfcc40", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90261f901f9a05ed68bb67a4ef1c931e84e62f855b3cab02fc8b9023779b8149016d03e9bdacca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0bd4ff120afac4ed3d8ee3eaf3f594aab23055cea9b2593b0ae15219249cfcc40a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea5d80a05116c123a7361290685fef2a7e405227747edb791133b95ec1245d0bad71aadf884a5f84c3405aff0ef862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0a24b1797a2a2a816786f5bc5f3709a6474eea09cba5374d7c80a3ea4e79fe537a0563bf77bdc856af050c91dc2cc19a75f6092ffeb1340112d34770aa9d5ea39d2c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x04cb2f", + "gasPrice" : "0x01", + "nonce" : "0x01", + "r" : "0xa24b1797a2a2a816786f5bc5f3709a6474eea09cba5374d7c80a3ea4e79fe537", + "s" : "0x563bf77bdc856af050c91dc2cc19a75f6092ffeb1340112d34770aa9d5ea39d2", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "rlp" : "0xf9045df901f9a03f0c95de871aee5c19d760ce7d2b9c128a1c30a09339e942a47326b21f6acb2ba034b415b05618e8c0827940dce6470c7f62fcb64a1d17e965f33709a81eef3621948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a0dabd2a041c64cb26a3ffc9856aeca497c543a01b4b7628ba8d465b36d0abd127a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea5e80a0ce284b413af3e7b6c4439192aad3e36e17ee3b175ead1f9f890a98928ebc7b7388c8683853adde69b6f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0c48096f3bf864a4116ea7953f6ad8a73e922ae9442d4552d1d1909ce0351bec6a0cd347472b7452a12ade89a203005d21d73895323fafbd83155adccfb7c2523b5f901faf901f7a05ed68bb67a4ef1c931e84e62f855b3cab02fc8b9023779b8149016d03e9bdacca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd880845522f29e80a0758827df1e60170448687d3f34bf7e0054529039cbf08359b83300da1976ea348805b8e5b210f3f11f" + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0386a0", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "6d0ae8cd327b41291551d7048eb918ca5dc394d28d25402c495faab44e73971e", + "mixHash" : "9b97fa62eab10576ecf678e6109f69e3c5826dfb2b355f82cba65b7317958144", + "nonce" : "a38a1b2440fa1705", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "7dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a09b97fa62eab10576ecf678e6109f69e3c5826dfb2b355f82cba65b731795814488a38a1b2440fa1705c0c0", + "lastblockhash" : "3f0c95de871aee5c19d760ce7d2b9c128a1c30a09339e942a47326b21f6acb2b", + "postState" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x14", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x29a2241af62ca410", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x09184e71fbdc", + "code" : "0x", + "nonce" : "0x02", + "storage" : { + } + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x09184e72a000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "wrongMixHash" : { + "blocks" : [ + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x038630", + "extraData" : "0x", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x5208", + "hash" : "02d9e686db27a43745ec82cddecf0d49857698ca6f0c80b871a993cce9b76f4d", + "mixHash" : "8360e4f85dc1b051b6448c22d62345d090b753e3bfd46c107c8f95b8864e214e", + "nonce" : "c50c06f5f136a787", + "number" : "0x01", + "parentHash" : "71b90167bfc9d16c075fc6dfc40477f8eeb680a4d6eb25b4c7c0db8b6b2a8fab", + "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", + "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", + "timestamp" : "0x557fea62", + "transactionsTrie" : "4e0d7ae9283245265ece2999cde6d479e579194154103b35a648b6be0ad2be66", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90261f901f9a071b90167bfc9d16c075fc6dfc40477f8eeb680a4d6eb25b4c7c0db8b6b2a8faba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a04e0d7ae9283245265ece2999cde6d479e579194154103b35a648b6be0ad2be66a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea6280a08360e4f85dc1b051b6448c22d62345d090b753e3bfd46c107c8f95b8864e214e88c50c06f5f136a787f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca04f4960f2eb3bec7396b4b0db840383f62a22c6d2dad175688a23972ff2a9c9eda0c6dbcf7dc70547e2942875d0236c7a1bace28306e3e846deecdce97b5839aca0c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x04cb2f", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x4f4960f2eb3bec7396b4b0db840383f62a22c6d2dad175688a23972ff2a9c9ed", + "s" : "0xc6dbcf7dc70547e2942875d0236c7a1bace28306e3e846deecdce97b5839aca0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1c", "value" : "0x0a" @@ -1136,28 +1398,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "4300af02ac3d852277bc047654bc15e754e9d537cfc0558b2a832d2868a6ece5", - "mixHash" : "60bde277e998331df9a427e8676c51efecf6ed19f1355838a38bf57ac6dee43b", - "nonce" : "d69a59020e02e04d", + "hash" : "a2f9cca853c5cdce8a970689dd09501e2d852d3759b57047461646e0c0ef89aa", + "mixHash" : "cf6be3ef50326186217079637d7026ca9c4c616693ebf9b2cca226e08e0e19db", + "nonce" : "93926ab2aae46d22", "number" : "0x02", - "parentHash" : "a28de9ec2cee57445a93d498091565bba1d0e2eea6b5a2c2ae435fced7b40269", + "parentHash" : "02d9e686db27a43745ec82cddecf0d49857698ca6f0c80b871a993cce9b76f4d", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x555501b4", - "transactionsTrie" : "07b152f2328b919fd42afdb2162fe34b95dfaced2546f8ebd05142279924d688", + "timestamp" : "0x557fea65", + "transactionsTrie" : "3a6b24f697df43db09029e425ce1495f64deb4195757991784189c240d6824a2", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0a28de9ec2cee57445a93d498091565bba1d0e2eea6b5a2c2ae435fced7b40269a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea007b152f2328b919fd42afdb2162fe34b95dfaced2546f8ebd05142279924d688a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884555501b480a060bde277e998331df9a427e8676c51efecf6ed19f1355838a38bf57ac6dee43b88d69a59020e02e04df862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca085e0e179c762f6fbf8cb38898ecacb7067faa567d285cfc0d43abcc575e7c8fda0902b3f160af1f9f8b699cd10d75d916d90b59efc58a0fc650f36320ceadf01d0c0", + "rlp" : "0xf90261f901f9a002d9e686db27a43745ec82cddecf0d49857698ca6f0c80b871a993cce9b76f4da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea03a6b24f697df43db09029e425ce1495f64deb4195757991784189c240d6824a2a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea6580a0cf6be3ef50326186217079637d7026ca9c4c616693ebf9b2cca226e08e0e19db8893926ab2aae46d22f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0cd272b71866a035bd6e6c58d0a92b141044516651c4d228c303cb9344f24cf4ea0e1bed38e900826a8f15f1421cb0ccfbb06fef4b2c682f78bfd86a66d02f1ecdcc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x85e0e179c762f6fbf8cb38898ecacb7067faa567d285cfc0d43abcc575e7c8fd", - "s" : "0x902b3f160af1f9f8b699cd10d75d916d90b59efc58a0fc650f36320ceadf01d0", + "r" : "0xcd272b71866a035bd6e6c58d0a92b141044516651c4d228c303cb9344f24cf4e", + "s" : "0xe1bed38e900826a8f15f1421cb0ccfbb06fef4b2c682f78bfd86a66d02f1ecdc", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", + "v" : "0x1b", "value" : "0x0a" } ], @@ -1165,7 +1427,7 @@ ] }, { - "rlp" : "0xf9045df901f9a04300af02ac3d852277bc047654bc15e754e9d537cfc0558b2a832d2868a6ece5a080eb05ca81d53d0a328b94c24cc0b463ade527abbf4444837e8d6abc3e403f71948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a0935e29e234760ca6f3510bc01127fe0102b92221037a8b7db3b7acf33f7e4223a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884555501b780a018282abb51a8806c03bb6ceafc0222e61393e11c1cecf05e99f10d4538913ada88334e676a7bd005eff862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca09b08366c1662bdf0cb1d4ff1b30460bf5bc5d6d0ae74a87e7321f76a4ef390daa03380020abb297972832a4759b96fa768a36f9eed6db0e3d8c62180ebd11bd931f901faf901f7a0a28de9ec2cee57445a93d498091565bba1d0e2eea6b5a2c2ae435fced7b40269a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd880845522f29e80a06471e8b724464619ad82444551558f944c172559f5116b70ba637405bc2ca8838897b0cfa8ce158dc4" + "rlp" : "0xf9045df901f9a0a2f9cca853c5cdce8a970689dd09501e2d852d3759b57047461646e0c0ef89aaa017924b6f02f496b00c042b2dc7079f73202a68cd30c4e222916518dc1b092763948888f1f195afa192cfee860698584c030f4c9db1a0a7150e152ba824446120f65ec8788e2baa7afbf0bb878bbaafe0631fc60860b2a002e755bb33543510419ffb9add7b41f7b52e749a821bf937b687c0734ceaa629a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea6780a0d6e363b10728c129e2a364e403b09aa7fe4db7f0a416460c9628277e1c5f28ad889b648bc9633f922bf862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba01f74aa243794ae7ccddbe91de5410439e777280d240adcdf8a1d76cf37160269a03ee5b498762af09eebcc0ae9d7ef72fde94ae4bd1e43c7cc9b2db4e7f2e589e5f901faf901f7a002d9e686db27a43745ec82cddecf0d49857698ca6f0c80b871a993cce9b76f4da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd88084557fea6780a0bad7f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee77088d91faa232969d7d4" } ], "genesisBlockHeader" : { @@ -1175,9 +1437,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "f77be32aac97a01fff3fdccc7cd65444333724155938dd3baa159b7a9cd67477", - "mixHash" : "79e16b568eb5c3b4dc2c462d22f193b608bebc327913efb47ccc53f695ad12ba", - "nonce" : "7d3701a83ff41152", + "hash" : "71b90167bfc9d16c075fc6dfc40477f8eeb680a4d6eb25b4c7c0db8b6b2a8fab", + "mixHash" : "b4e9995fd23587b0fbd67b3a1892905bca478e8500e87ec6a06194177c1c80ec", + "nonce" : "4db8f04459632f83", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -1186,8 +1448,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a079e16b568eb5c3b4dc2c462d22f193b608bebc327913efb47ccc53f695ad12ba887d3701a83ff41152c0c0", - "lastblockhash" : "4300af02ac3d852277bc047654bc15e754e9d537cfc0558b2a832d2868a6ece5", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0b4e9995fd23587b0fbd67b3a1892905bca478e8500e87ec6a06194177c1c80ec884db8f04459632f83c0c0", + "lastblockhash" : "a2f9cca853c5cdce8a970689dd09501e2d852d3759b57047461646e0c0ef89aa", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", @@ -1231,28 +1493,28 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "65a5bd411cb91fbba0a66e991572f697b521f680581eb8b7fb468923726c17b5", - "mixHash" : "162c7eb61d287400ca7c7f998a57bd35c14ec3df0e7a640ccef624a9ba2a19f8", - "nonce" : "18e2107e278fdba2", + "hash" : "8faf0e2b1867fce79993022a9b8920a6ac3e3bfeaa106e7eb5be141c17b83374", + "mixHash" : "c8b19bf080b204c22e97bbc28497cdc25fa967b9d228e7e7b265ca84e4cc7b13", + "nonce" : "352344368651a04d", "number" : "0x01", - "parentHash" : "a8d18377bd5079cd5d77799f49908aac13df486600ffc61041e1b6c6ab255fd9", + "parentHash" : "00118efb7d86eb9c9bc864fbc27a550862a611ddd2e7e60a9b07897b0c7a0f57", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x555501ba", - "transactionsTrie" : "839b667f1878d51a82b62e478fd680b8dc0a8610f8889a0a4a54d0c6be970428", + "timestamp" : "0x557fea6d", + "transactionsTrie" : "2c931278d9eebd11426b5bd688ee11b2d02517e22d7c7d1a8df52ab5dd9860fb", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0a8d18377bd5079cd5d77799f49908aac13df486600ffc61041e1b6c6ab255fd9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0839b667f1878d51a82b62e478fd680b8dc0a8610f8889a0a4a54d0c6be970428a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884555501ba80a0162c7eb61d287400ca7c7f998a57bd35c14ec3df0e7a640ccef624a9ba2a19f88818e2107e278fdba2f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba006edf1b8d80154f4ed7005733a41d02f4fd5a070b5bf650c547cc433f9c6308da0a763708477fc0fd2934b354c3068f1a4efaf89842408bba8f5a7af887038c6ebc0", + "rlp" : "0xf90261f901f9a000118efb7d86eb9c9bc864fbc27a550862a611ddd2e7e60a9b07897b0c7a0f57a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a02c931278d9eebd11426b5bd688ee11b2d02517e22d7c7d1a8df52ab5dd9860fba0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea6d80a0c8b19bf080b204c22e97bbc28497cdc25fa967b9d228e7e7b265ca84e4cc7b1388352344368651a04df862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca06b48eb9dc847d025755debc7e322b750e17284677adca57f318807c6d3f1a5cda05da9d67cb68ee0ffbd863fad5603cbd5e6ba794b5590fc5f99432773e4d40ab8c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x06edf1b8d80154f4ed7005733a41d02f4fd5a070b5bf650c547cc433f9c6308d", - "s" : "0xa763708477fc0fd2934b354c3068f1a4efaf89842408bba8f5a7af887038c6eb", + "r" : "0x6b48eb9dc847d025755debc7e322b750e17284677adca57f318807c6d3f1a5cd", + "s" : "0x5da9d67cb68ee0ffbd863fad5603cbd5e6ba794b5590fc5f99432773e4d40ab8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", + "v" : "0x1c", "value" : "0x0a" } ], @@ -1267,26 +1529,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "30209b168cb065b8308085fff406619f66ed6a7fe396c21d6127408166670137", - "mixHash" : "e18c5a5ae2736c820b0542e2f089b50a403026603a414df6807261a8cd93c329", - "nonce" : "85a75ddcce3c977b", + "hash" : "8eb51203ab5f754d4ce1a2d6befde40fb1b746e2f75fd845b270057674d23a15", + "mixHash" : "2dde7a14309a9d40527a455031aa41cc06a7da71dfecaa03ea419283542ace0e", + "nonce" : "6282ff55a76c00ef", "number" : "0x02", - "parentHash" : "65a5bd411cb91fbba0a66e991572f697b521f680581eb8b7fb468923726c17b5", + "parentHash" : "8faf0e2b1867fce79993022a9b8920a6ac3e3bfeaa106e7eb5be141c17b83374", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x555501bb", - "transactionsTrie" : "01bc98b099140e332cf91cf012cd177325e962c321794dc31f4d7c6ded1b0e54", + "timestamp" : "0x557fea71", + "transactionsTrie" : "df453ad06a15fceeb85d297b44f4064c6fd328b02c731ae52e5fea103f291956", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a065a5bd411cb91fbba0a66e991572f697b521f680581eb8b7fb468923726c17b5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea001bc98b099140e332cf91cf012cd177325e962c321794dc31f4d7c6ded1b0e54a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884555501bb80a0e18c5a5ae2736c820b0542e2f089b50a403026603a414df6807261a8cd93c3298885a75ddcce3c977bf862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca08b83729611ea92e329aeeebd24d2e687aed05c0a9135ce1bf27105bff66ad727a0b6ca0533385a8f71cb82d03d5f48e7c4c721fcb60fe3f7955e8c858a819f8729c0", + "rlp" : "0xf90261f901f9a08faf0e2b1867fce79993022a9b8920a6ac3e3bfeaa106e7eb5be141c17b83374a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0df453ad06a15fceeb85d297b44f4064c6fd328b02c731ae52e5fea103f291956a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea7180a02dde7a14309a9d40527a455031aa41cc06a7da71dfecaa03ea419283542ace0e886282ff55a76c00eff862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0c42442b48fdffdce00c186551e3b9f4f7226e228aadff88e3dcf1c216c6c9ee5a0c6e4cb9909b61ca3a83f671e0e06d71e104bd68e14ccceca8bfb5d1b437487d5c0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x8b83729611ea92e329aeeebd24d2e687aed05c0a9135ce1bf27105bff66ad727", - "s" : "0xb6ca0533385a8f71cb82d03d5f48e7c4c721fcb60fe3f7955e8c858a819f8729", + "r" : "0xc42442b48fdffdce00c186551e3b9f4f7226e228aadff88e3dcf1c216c6c9ee5", + "s" : "0xc6e4cb9909b61ca3a83f671e0e06d71e104bd68e14ccceca8bfb5d1b437487d5", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1c", "value" : "0x0a" @@ -1296,7 +1558,7 @@ ] }, { - "rlp" : "0xf9045df901f9a030209b168cb065b8308085fff406619f66ed6a7fe396c21d6127408166670137a0f8d908638f9b383634a06aa13e6c314dc2ab938e1ee204fb4d57c9a3bd5c789b948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a07df3368894be37dd03c77a6990245c2ca99acb18ddfba04c70685bd2094535aea02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863003832fefd882520884555501c380a02499b49865f98dfb583f7d2c0cd18212c5b8426edec79fc17d8ce2ed691cc2c3888de0d58f7a702347f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca01ace5e0282dd710ecba232b275770151d89733471b0553eeb041383f6d148e57a087647b9175529d10a9c39331a825f42818a5da2c7ad0f1638d146fa87bec0403f901faf901f7a0bad4fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938faea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830385c002832fefd88084555501c380a0bd470062a12f64e4568fd66007c1ad9c637fe9cf6658b7aef658cba2366f943a88c9933282bb5b53a9" + "rlp" : "0xf9045df901f9a08eb51203ab5f754d4ce1a2d6befde40fb1b746e2f75fd845b270057674d23a15a082c42500f3b3503ac8486963d51c29e095ad0d1f11138fd9b5c17c4f2f60289f948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a0e8f446c19c15888677a10a11dc22e224bcc51def3da7bd1e0860e971ecb50d76a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea7380a0fe66fe9e5fd0bd177e1f6569d2286b62c942ace050ca851b63db372e8cf40e52887eee7495d814d176f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0ac1c8b909110b78bd392d68e27c28eb08d62a577895dc8ec95f1d811cc8ea76fa0f4c48675c706996d60986670e49ecdaf03c7ab3f0bae4192c2f4253b51aa2f1bf901faf901f7a0bad4fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938faea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd88084557fea7380a06c4478abebb4617e295f2d6e8cc181795cbdb0a6d10b86e0e6f67ffe877b809088404368fb1e7ac701" } ], "genesisBlockHeader" : { @@ -1306,9 +1568,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "a8d18377bd5079cd5d77799f49908aac13df486600ffc61041e1b6c6ab255fd9", - "mixHash" : "9c2b1ce7e46934a4817f17cbb12da7186111d1ccd398f724fc0a4578b4264f97", - "nonce" : "8b5c8cf6880f6f61", + "hash" : "00118efb7d86eb9c9bc864fbc27a550862a611ddd2e7e60a9b07897b0c7a0f57", + "mixHash" : "e7745f10dc1ec697fd4cb9e251b5e2f460b5bf69054035df668048b52bd5ede9", + "nonce" : "54593786268ad10e", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -1317,8 +1579,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a09c2b1ce7e46934a4817f17cbb12da7186111d1ccd398f724fc0a4578b4264f97888b5c8cf6880f6f61c0c0", - "lastblockhash" : "30209b168cb065b8308085fff406619f66ed6a7fe396c21d6127408166670137", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a0e7745f10dc1ec697fd4cb9e251b5e2f460b5bf69054035df668048b52bd5ede98854593786268ad10ec0c0", + "lastblockhash" : "8eb51203ab5f754d4ce1a2d6befde40fb1b746e2f75fd845b270057674d23a15", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", @@ -1362,26 +1624,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "f0004afde39bb63a1b4eaedf1fdbb1ea17816f15e7effd1fccf8314dbc4551e5", - "mixHash" : "3cca9f1725215ef3e686abe8c326733fcb4b4a02820e838c466a01595f086ccf", - "nonce" : "bb487559914f650e", + "hash" : "28cf61a48732e39a06b8d7bf490311e22a730629017adc9673459c2b222bdb07", + "mixHash" : "f1d6290d0674b697b3b0ff7917359680090466fc933370c5a355a1971c2e4b4f", + "nonce" : "5efec6c1c33db629", "number" : "0x01", - "parentHash" : "969a4dd022782b1fd2441a918b20bdc645d8ffc7c741bf609accb599e9e26819", + "parentHash" : "db025097c3cbe28c509c9a5dcfd48528896eeaa964d40d19eaa8b4dc409f972e", "receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313", "stateRoot" : "2c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70", - "timestamp" : "0x555501c9", - "transactionsTrie" : "d1d3898ad7be4f1fa66a444daa2679e77f520d28b6595aa1e3e5423b23ac8f34", + "timestamp" : "0x557fea79", + "transactionsTrie" : "2791538787065e703899678093da7a5e83b28b7517e29b112d1e0d2b9efc0df7", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0969a4dd022782b1fd2441a918b20bdc645d8ffc7c741bf609accb599e9e26819a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a0d1d3898ad7be4f1fa66a444daa2679e77f520d28b6595aa1e3e5423b23ac8f34a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884555501c980a03cca9f1725215ef3e686abe8c326733fcb4b4a02820e838c466a01595f086ccf88bb487559914f650ef862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba037b569f32914b00ddec1c5b75f61ab15974e2464e639895331381c83aa86852ca074017993bf80fcab95fdf1b1944270fc399d7cc6b0497749e386cd07d537bffec0", + "rlp" : "0xf90261f901f9a0db025097c3cbe28c509c9a5dcfd48528896eeaa964d40d19eaa8b4dc409f972ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a02c15e8b5cb6cf880faa558c76c02a591e181ef2c4450ad92e53ae6c21093dc70a02791538787065e703899678093da7a5e83b28b7517e29b112d1e0d2b9efc0df7a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303863001832fefd882520884557fea7980a0f1d6290d0674b697b3b0ff7917359680090466fc933370c5a355a1971c2e4b4f885efec6c1c33db629f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0d1608da5bb394713c42bf02d3436a041e59a3d4bb84bbb3bca0781eef4aecd52a05ea0845d6bae22664156e826643a386fcb3d074263078680faee9edbe5adececc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x00", - "r" : "0x37b569f32914b00ddec1c5b75f61ab15974e2464e639895331381c83aa86852c", - "s" : "0x74017993bf80fcab95fdf1b1944270fc399d7cc6b0497749e386cd07d537bffe", + "r" : "0xd1608da5bb394713c42bf02d3436a041e59a3d4bb84bbb3bca0781eef4aecd52", + "s" : "0x5ea0845d6bae22664156e826643a386fcb3d074263078680faee9edbe5adecec", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1b", "value" : "0x0a" @@ -1398,26 +1660,26 @@ "extraData" : "0x", "gasLimit" : "0x2fefd8", "gasUsed" : "0x5208", - "hash" : "d5fd1ba8d7af892338be88064ec75972e28d2647249c266a3b2b038a2808e000", - "mixHash" : "7ae3d64ab9dbc3f4792636b54fa65a34d3b2ff3ad28e0bc2acb93205ed5d4c9b", - "nonce" : "24ad364d9b12f9b9", + "hash" : "59203337fbc8d4aa04fb7e35b7b3a8160fa205eec4ed2091756b0fcc699c1309", + "mixHash" : "416357f0a146268e21e8eb0de633bb983019559f70acaa138038fcf36d7d0c8a", + "nonce" : "727ea0bb163ff761", "number" : "0x02", - "parentHash" : "f0004afde39bb63a1b4eaedf1fdbb1ea17816f15e7effd1fccf8314dbc4551e5", + "parentHash" : "28cf61a48732e39a06b8d7bf490311e22a730629017adc9673459c2b222bdb07", "receiptTrie" : "5a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27", "stateRoot" : "a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fe", - "timestamp" : "0x555501cb", - "transactionsTrie" : "da997da975cc5d473589038159555334aa0618d10e9ebebaa0a3b32e61ecc04e", + "timestamp" : "0x557fea7b", + "transactionsTrie" : "eb8a58d8199150a8f64e5c0b90ba1936d6b23f510affdc3d1705c81f7ad3e605", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "rlp" : "0xf90261f901f9a0f0004afde39bb63a1b4eaedf1fdbb1ea17816f15e7effd1fccf8314dbc4551e5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0da997da975cc5d473589038159555334aa0618d10e9ebebaa0a3b32e61ecc04ea05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884555501cb80a07ae3d64ab9dbc3f4792636b54fa65a34d3b2ff3ad28e0bc2acb93205ed5d4c9b8824ad364d9b12f9b9f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca003aa5d0e3c3671630fe5111ce0f3fbad36a3a1cde4b0e35f0e8ee937274bb867a0fdecb9c68f5068b54eca124affb391f93bff7ceaea0c4c77fdae1155057ed203c0", + "rlp" : "0xf90261f901f9a028cf61a48732e39a06b8d7bf490311e22a730629017adc9673459c2b222bdb07a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a2a5e3d96e902272adb58e90c364f7b92684c539e0ded77356cf33d966f917fea0eb8a58d8199150a8f64e5c0b90ba1936d6b23f510affdc3d1705c81f7ad3e605a05a750181d80a2b69fac54c1b2f7a37ebc4666ea5320e25db6603b90958686b27b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd882520884557fea7b80a0416357f0a146268e21e8eb0de633bb983019559f70acaa138038fcf36d7d0c8a88727ea0bb163ff761f862f86001018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca03ed1e4baa795244ac64b0b768b91d320bfc3ed138e457622438102b43c0c8bd9a0bcfdafad441cd967a06e534b8f6cbd0bd31407e853484f9195874fc94885628dc0", "transactions" : [ { "data" : "0x", "gasLimit" : "0x04cb2f", "gasPrice" : "0x01", "nonce" : "0x01", - "r" : "0x03aa5d0e3c3671630fe5111ce0f3fbad36a3a1cde4b0e35f0e8ee937274bb867", - "s" : "0xfdecb9c68f5068b54eca124affb391f93bff7ceaea0c4c77fdae1155057ed203", + "r" : "0x3ed1e4baa795244ac64b0b768b91d320bfc3ed138e457622438102b43c0c8bd9", + "s" : "0xbcfdafad441cd967a06e534b8f6cbd0bd31407e853484f9195874fc94885628d", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "v" : "0x1c", "value" : "0x0a" @@ -1427,7 +1689,7 @@ ] }, { - "rlp" : "0xf9045df901f9a0d5fd1ba8d7af892338be88064ec75972e28d2647249c266a3b2b038a2808e000a08a81e616498e5d3bb2558ba4c786569201033d9cb554c35b0ae4e0b98f1f77ce948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a01c464a3f5ca4dac55775a0ea3ac86c85c2cb6e120936dbbd38162184ae67b6dda02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884555501cd80a0f57ac239d1a4233d61897b493ee8886f8ee9ae08cae6ceef4b00f7cb3f0c08a688488d82e383223b92f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca03cb16b681c4078f1310953384c5f7d61b66c74068951ea3dd96a2342bc31784ba017c9fa10b5a8e87dfa3c69096a0cb1b7ee71445dff20d7f9db6ae1e8aed48c67f901faf901f7a0f0004afde39bb63a1b4eaedf1fdbb1ea17816f15e7effd1fccf8314dbc4551e5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba0bad40b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd88084555501cd80a0649ba4273484110720fa67e65845166006e4eedfb105f24ef5a642d58c7dbc4d8871408da66c0a3ded" + "rlp" : "0xf9045df901f9a059203337fbc8d4aa04fb7e35b7b3a8160fa205eec4ed2091756b0fcc699c1309a0e081abd582ad35a31068cab36707730393e1918b55a4ed30cc1d31ac5e339965948888f1f195afa192cfee860698584c030f4c9db1a0d40c133a2d06637484d95e89dd676d06f93ea4dcced745aa67613eeb33948f39a0481632b12f8b565aac7880f0ce1bf61ea5a3a95c6942509692a41aab8bf5c1f6a02b67f7a4806df8b7971f6e30027ac45ec69215a689a1d701da979d78d57c6f78b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008303871003832fefd882520884557fea7f80a0e6e50cf7400653b83616cc1fa23bd4afba50ff69efbdb7b94e142cbf0c8dfc3588084054eedce23c7bf862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca0624d57cfeb71257fb693a705697f42112da63afe8f0c7159357288c34f4faa1aa02e8ff3a1b0fe05d0ddcda2f7a00979ecaa0dfd3da2f64e7d9c6c34221583abbaf901faf901f7a028cf61a48732e39a06b8d7bf490311e22a730629017adc9673459c2b222bdb07a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794acde5374fce5edbc8e2a8697c15331677e6ebf0ba0bad40b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a002832fefd88084557fea7f80a0fae4284379e1a50046c2c30d0979ae83d02a5d70609ecfbfd3167d9b195e8f768889ec0677ae63da0b" } ], "genesisBlockHeader" : { @@ -1437,9 +1699,9 @@ "extraData" : "0x42", "gasLimit" : "0x2fefd8", "gasUsed" : "0x00", - "hash" : "969a4dd022782b1fd2441a918b20bdc645d8ffc7c741bf609accb599e9e26819", - "mixHash" : "7c30d9260124abeb81c0a575481bde08d92e4087b840e86dc2742e5835d2e46c", - "nonce" : "9e8de1149ac18cd7", + "hash" : "db025097c3cbe28c509c9a5dcfd48528896eeaa964d40d19eaa8b4dc409f972e", + "mixHash" : "2ba6a79d4cb8c6e573f0a25ba8af0691914322978670c4ef5c7216bc286c8afc", + "nonce" : "7983221ee55bb09e", "number" : "0x00", "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -1448,8 +1710,8 @@ "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a07c30d9260124abeb81c0a575481bde08d92e4087b840e86dc2742e5835d2e46c889e8de1149ac18cd7c0c0", - "lastblockhash" : "d5fd1ba8d7af892338be88064ec75972e28d2647249c266a3b2b038a2808e000", + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830386a080832fefd8808454c98c8142a02ba6a79d4cb8c6e573f0a25ba8af0691914322978670c4ef5c7216bc286c8afc887983221ee55bb09ec0c0", + "lastblockhash" : "59203337fbc8d4aa04fb7e35b7b3a8160fa205eec4ed2091756b0fcc699c1309", "postState" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "0x14", diff --git a/tests/files/StateTests/RandomTests/st201506091836GO.json b/tests/files/StateTests/RandomTests/st201506091836GO.json new file mode 100644 index 000000000..05a421ad3 --- /dev/null +++ b/tests/files/StateTests/RandomTests/st201506091836GO.json @@ -0,0 +1,71 @@ +{ + "randomStatetest" : { + "env" : { + "currentCoinbase" : "a7f7c8ef9bbbcfb0f7e81c1fd46bb732fba60592", + "currentDifficulty" : "0x4b7a57082929690e", + "currentGasLimit" : "0x0b3be1fc", + "currentNumber" : "0x7ee23b32", + "currentTimestamp" : "0x588de6ec", + "previousHash" : "f3907ec3d962d22b61d2618054c8252a7fe67b65f652a7b8fcc55cfe905a1caa" + }, + "logs" : [ + ], + "out" : "0x", + "post" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x33498455", + "code" : "0x64d552603c577e9a3805d8c55157a82b7660ef2a049cfbf79c15fa8e3261f121d213590fa3917d7d442a5e8734af2aaa4c859b452eed7860c2f7e051580427b6c3cc6d7fee617a0d64ef63e192256de5d2ea2689decfd971c7478effb06aa9e792747ce0492abde8c2f270e93d5ed0b213fed7ae59294537d4864c0e68bbe30ec5d1e6b854027862cfcbea15e8367dfaa080ee0da2b0d2ca892f5a764354370466ccddd03115ec8a7ad2e6c62c29425a45ec842fb74c369fb15a42e4b4e48b3eb70be2a0847469987980e6eaa539365a491d2366334f78f03acb177809e7525add39a234d3d2ef1cf8544a52389411ef846d3cd7f36d0d1db7f414860020171f07598cfb620e15a9681c843d60aee9fb8a4e7e37713afbf6ef9d1667513975c76f26ac35ce209b1e0a3bb7c19821368931537b4095ea42b32baf1ba596b9af5cce961ae705f8c9c5465e349633529871f64351169e7fe48ccbb866952fabbfcf40df723c564e109dbd4c9c15ee9ad625e96a5765f6f56ee0601677961da7ebad5f583f6eb6da7c8348425fe784f532f288963ccdbf9de3ac3ebc38b75a806b40e51b895c662d0bcab255a04b723f1e500517d17eb720e02f445cb046bd0fe7d2759438c79aa2dfcaef1cf57e4eb9c832f7ef449a9c32f673728f4b0dccdfa8fb1d447e2f681076ac51a98f76600a66b4692ca7e1e9c89f64cdf879cb0c625514977ebca28f2ec8bb3a092bd0c30849558fe16a4b7070cb05aec329c0286c26fff57795ce4ac7601160ea2d6656c8f2a554b43e263cc3a60e9fd0a26c0a5f7202f02888a731e84ab326610c77771f85025eb8c552943d2da5de48786015f5b8b5921d26c1e277d5a4cda5f1f77ec5f3a83e6ed6821ff025370e2fad05a0f364f58f3705c8761904d63e0f2e5bdbe2b0b1ddf82bb441c547634e8c1864737333e845ffa373c102303f727bfa14f4c445711f6f9695c36f3627df02a1fe2d7eca55faed6984000ab2a99545148bbe7369a47367bc24256acd6a3a22d5fb32434b1998297ae6b2edf08b72dc4598aa600e16707699a84e55ef611ea0e6da482f6c6e9d05d54bbb4ad06cd62622e469fbcd3e637a8f0d2ac9149b7076cce991cb5d4b4de1229e3decbcf46a3c7e46aa1fdc218d936e56f55b5a38bbd798361040e1badb1ab06adc38a723badfa07a95f78553de4df879855274a1904a31276d7938818021e69d8f5b9279478808a236deefd761df6bc151fded80bbe4ba725e7db7b9fc507f0b8121a009384c7bc4443747bd1ac9dc7682b32bec0937c7fb27ba3926acd0d67b41ba6c951788f1bb1b1168229d15cafdc63209c95df646566024013d766a01d6b8051c357243c9f464f423a2ae8efa4f9efd95777099eac9b0825d18018a5afcb6cecd9ab9a9655ae262db08a271d8adedbc3e7eb6acfd2d576ec297c09c4bd47a80dacd2b123e4e4e6232ef6d70acb10f2f44a62bbcef65a72576506ea119b051880b515f4414920badcd6f726c04e821516f6123c9c52f29e19bfe0fb10fab76536535cc0e01115c83369d4083db2d669654c2fe8c00e37bd78f663a2ce2425d2ce358e213d6c601208bb644fa656678de7633147fbd152c2ae682dec269245f07ba3c79f4e6e1978d40f42a494d44eba128b9d0228d637900cbab73455423156417fae331d26494d1ed4d06ecf206736f04292d5470d5091c48a80ba737372c35729c829af30db3625785ba0b3cfc4240d002276760f2770ead609b52db934a53063ec1c05488188fb37ce61059909b6c975c0e9401ef3b71b6d0ddae39867f3f0878bd172851a98a233fcafae289fc634c36c8b3064926d92deda3d8c5074d6a56daa511e7e693aab3d4347cebdd5b63238acdeedc3d8eb8f69ea18cb429ee8f09c26845507ba28eba916c74fd62cd9e587a8f013122d93579b6b7da091527251a4b70051be4f0f96f61e5dc4ab713c473174c7e2ebb463615b03c4787b74e8c204975399439fa553838f186ae028a47f3ccd46c5fcc46c11a36219f3ba1d34def7bee989fa61e60a2abd3652df9f8e5a1b53d9608e3bb04f5e852333d9c7d761836ef5761178bd07fde9a0ded16e1659a6c80281c259ce42e3fdbe23664ce783b58d595", + "nonce" : "0xe9", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0x4ea91708", + "code" : "0x36", + "nonce" : "0x59", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x24d289465fa51769", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "postStateRoot" : "5a9d4e3d21fb0dee07e0b52772b46dff8b513f0d4fba4765c43096a97e8b088f", + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x33498455", + "code" : "0x64d552603c577e9a3805d8c55157a82b7660ef2a049cfbf79c15fa8e3261f121d213590fa3917d7d442a5e8734af2aaa4c859b452eed7860c2f7e051580427b6c3cc6d7fee617a0d64ef63e192256de5d2ea2689decfd971c7478effb06aa9e792747ce0492abde8c2f270e93d5ed0b213fed7ae59294537d4864c0e68bbe30ec5d1e6b854027862cfcbea15e8367dfaa080ee0da2b0d2ca892f5a764354370466ccddd03115ec8a7ad2e6c62c29425a45ec842fb74c369fb15a42e4b4e48b3eb70be2a0847469987980e6eaa539365a491d2366334f78f03acb177809e7525add39a234d3d2ef1cf8544a52389411ef846d3cd7f36d0d1db7f414860020171f07598cfb620e15a9681c843d60aee9fb8a4e7e37713afbf6ef9d1667513975c76f26ac35ce209b1e0a3bb7c19821368931537b4095ea42b32baf1ba596b9af5cce961ae705f8c9c5465e349633529871f64351169e7fe48ccbb866952fabbfcf40df723c564e109dbd4c9c15ee9ad625e96a5765f6f56ee0601677961da7ebad5f583f6eb6da7c8348425fe784f532f288963ccdbf9de3ac3ebc38b75a806b40e51b895c662d0bcab255a04b723f1e500517d17eb720e02f445cb046bd0fe7d2759438c79aa2dfcaef1cf57e4eb9c832f7ef449a9c32f673728f4b0dccdfa8fb1d447e2f681076ac51a98f76600a66b4692ca7e1e9c89f64cdf879cb0c625514977ebca28f2ec8bb3a092bd0c30849558fe16a4b7070cb05aec329c0286c26fff57795ce4ac7601160ea2d6656c8f2a554b43e263cc3a60e9fd0a26c0a5f7202f02888a731e84ab326610c77771f85025eb8c552943d2da5de48786015f5b8b5921d26c1e277d5a4cda5f1f77ec5f3a83e6ed6821ff025370e2fad05a0f364f58f3705c8761904d63e0f2e5bdbe2b0b1ddf82bb441c547634e8c1864737333e845ffa373c102303f727bfa14f4c445711f6f9695c36f3627df02a1fe2d7eca55faed6984000ab2a99545148bbe7369a47367bc24256acd6a3a22d5fb32434b1998297ae6b2edf08b72dc4598aa600e16707699a84e55ef611ea0e6da482f6c6e9d05d54bbb4ad06cd62622e469fbcd3e637a8f0d2ac9149b7076cce991cb5d4b4de1229e3decbcf46a3c7e46aa1fdc218d936e56f55b5a38bbd798361040e1badb1ab06adc38a723badfa07a95f78553de4df879855274a1904a31276d7938818021e69d8f5b9279478808a236deefd761df6bc151fded80bbe4ba725e7db7b9fc507f0b8121a009384c7bc4443747bd1ac9dc7682b32bec0937c7fb27ba3926acd0d67b41ba6c951788f1bb1b1168229d15cafdc63209c95df646566024013d766a01d6b8051c357243c9f464f423a2ae8efa4f9efd95777099eac9b0825d18018a5afcb6cecd9ab9a9655ae262db08a271d8adedbc3e7eb6acfd2d576ec297c09c4bd47a80dacd2b123e4e4e6232ef6d70acb10f2f44a62bbcef65a72576506ea119b051880b515f4414920badcd6f726c04e821516f6123c9c52f29e19bfe0fb10fab76536535cc0e01115c83369d4083db2d669654c2fe8c00e37bd78f663a2ce2425d2ce358e213d6c601208bb644fa656678de7633147fbd152c2ae682dec269245f07ba3c79f4e6e1978d40f42a494d44eba128b9d0228d637900cbab73455423156417fae331d26494d1ed4d06ecf206736f04292d5470d5091c48a80ba737372c35729c829af30db3625785ba0b3cfc4240d002276760f2770ead609b52db934a53063ec1c05488188fb37ce61059909b6c975c0e9401ef3b71b6d0ddae39867f3f0878bd172851a98a233fcafae289fc634c36c8b3064926d92deda3d8c5074d6a56daa511e7e693aab3d4347cebdd5b63238acdeedc3d8eb8f69ea18cb429ee8f09c26845507ba28eba916c74fd62cd9e587a8f013122d93579b6b7da091527251a4b70051be4f0f96f61e5dc4ab713c473174c7e2ebb463615b03c4787b74e8c204975399439fa553838f186ae028a47f3ccd46c5fcc46c11a36219f3ba1d34def7bee989fa61e60a2abd3652df9f8e5a1b53d9608e3bb04f5e852333d9c7d761836ef5761178bd07fde9a0ded16e1659a6c80281c259ce42e3fdbe23664ce783b58d595", + "nonce" : "0xe9", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0x4ea91708", + "code" : "0x36", + "nonce" : "0x59", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x24d289465fa51769", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0x73151af76abac2a99afe60eff5cfd8f68daf1b35e0608a690494ef4b1d043bf90e00916acf5f0332c3ef3aa972eba960aa557dc165d1a3c726953fc637fe643a60543de4159f3bc09673cd054235ddb44769fa2d6edb61b6e71feff2662043418ac9d2337bce1df4b842fbf8f07395b44bb506e8955d22a12176e2fb8e25bc546d77a6f5049a09f3126c915f14979d8c7c0cf88425567c6b8a6865b78e6d76208a641cb0d0651a758d9afdd5e36b2dcf740a8a1e2b19ebb0bc8ad6ac032577f3b5d483e40d0c9a40aaf32cebc478c0962e1ac5f6c648f47665f0850054ab4caab6eca1a24242087387c96452ad72e76a42a175db6c69a2d8cbcd70759249b040a797894765385557e947875851cfe9734edc8b613cbb6bf40b41b762fa3bcbc6b59ecc66971fef9e8ed16d691702b224f0e2f8ad12577a943401f57334d3207b884a40ed472960f03e4cab61c98268b5a73b6372ab45a7a4", + "gasLimit" : "0x738409f3", + "gasPrice" : "0x1d", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0x7f3e3a6ac8834e68" + } + } +} diff --git a/tests/files/StateTests/RandomTests/st201506092032GO.json b/tests/files/StateTests/RandomTests/st201506092032GO.json new file mode 100644 index 000000000..5a354f71e --- /dev/null +++ b/tests/files/StateTests/RandomTests/st201506092032GO.json @@ -0,0 +1,71 @@ +{ + "randomStatetest" : { + "env" : { + "currentCoinbase" : "6d6e40885310545835a5b582dbc23ef026404bda", + "currentDifficulty" : "0x266dbce6", + "currentGasLimit" : "0x2b7fe66d", + "currentNumber" : "0x635fe35ae78fc1dc", + "currentTimestamp" : "0x775b1d0c", + "previousHash" : "a8228e05d900b890136bcc55628b479e172795042a90e18b673189b5f3a672fc" + }, + "logs" : [ + ], + "out" : "0x", + "post" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x070a217c02c8f2d4", + "code" : "0x6f823a02877cef7c1afb60663009def564608c557bad2ae05769b991313726edbfa0881d9cc955b0f5154751da315696ea7ce130184b64f2507582c502d450349ff24fb8aeb2a46146687b666bd7bd0364946cb720c76d483f5afea0049251fd9793c4b0376afbb4ebcdc42fdd42edcd4b619cec787638009cea26a1abe570e3186ab790b7dc7db36e4cda2570b0847adf6e39579c7c43a4ac976cd507d493cdfaebe09936078e31c71c4665d34a4b816b8004", + "nonce" : "0x75", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0x9740421ff0ff3ae3", + "code" : "0x", + "nonce" : "0x1d", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0xc1142f2b8e8eb058", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "postStateRoot" : "f95be1e4c7788641348454fd9ff7b21956f61a979e8d7f8e55cec444c5931e8c", + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x070a217c02c8f2d4", + "code" : "0x6f823a02877cef7c1afb60663009def564608c557bad2ae05769b991313726edbfa0881d9cc955b0f5154751da315696ea7ce130184b64f2507582c502d450349ff24fb8aeb2a46146687b666bd7bd0364946cb720c76d483f5afea0049251fd9793c4b0376afbb4ebcdc42fdd42edcd4b619cec787638009cea26a1abe570e3186ab790b7dc7db36e4cda2570b0847adf6e39579c7c43a4ac976cd507d493cdfaebe09936078e31c71c4665d34a4b816b8004", + "nonce" : "0x75", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0x9740421ff0ff3ae3", + "code" : "0x", + "nonce" : "0x1d", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0xc1142f2b8e8eb058", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0x64dd3e4e84676723342c1dfaf9af4ef3", + "gasLimit" : "0x4b75fb87", + "gasPrice" : "0x1c", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0x6d1dd024" + } + } +} diff --git a/tests/files/StateTests/RandomTests/st201506101359JS.json b/tests/files/StateTests/RandomTests/st201506101359JS.json new file mode 100644 index 000000000..58b2456e7 --- /dev/null +++ b/tests/files/StateTests/RandomTests/st201506101359JS.json @@ -0,0 +1,71 @@ +{ + "randomStatetest" : { + "env" : { + "currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5", + "currentDifficulty" : "0x051d6a3cd647", + "currentGasLimit" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "logs" : [ + ], + "out" : "0x", + "post" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x00", + "code" : "0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba46699913755", + "nonce" : "0x00", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0x52614e74", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b35502b1ba", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "341d35dcd68e14ed391c23300e89fb48d60096e473e4e8b84589df12381e8d0e", + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x00", + "code" : "0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba46699913755", + "nonce" : "0x00", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0x2e", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba466999137", + "gasLimit" : "0x52614e46", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0x377df0d4" + } + } +} diff --git a/tests/files/StateTests/RandomTests/st201506101754PYTHON.json b/tests/files/StateTests/RandomTests/st201506101754PYTHON.json deleted file mode 100644 index 011393c16..000000000 --- a/tests/files/StateTests/RandomTests/st201506101754PYTHON.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "randomStatetest" : { - "env" : { - "currentCoinbase" : "278a2477986e084e246f05773a2b5eacdb5dfc", - "currentDifficulty" : "0x4dd564b3cdda8bc3", - "currentGasLimit" : "0xa944edbd45fcf58f", - "currentNumber" : "0x1af631a7", - "currentTimestamp" : "0x7e5eac84", - "previousHash" : "a8bb55191478f88b4b7d9c24296b85e00bcc3c10f421f74f22796c3b803e9cc5" - }, - "logs" : [ - ], - "out" : "0x", - "post" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x181b2eb1", - "code" : "0x795be1b1880ba0d1ff0b50d115c416fb7ac36fc9d2bea9f9e7212f75048cdab5287d75095451ab1623b6739fc0b8ca326281557c68443e5185640a16e727e1156afd6dde85dfe895f090e713f5c281b37862dfa4720b60f87ef7cbadac8540d09aed76138387554911aadac3a5a8ebdf110a8fbaf47cab627cb65114dda0080882a9bbbf030996a6bfcce67b166c10f4ae8744f4c25364bedb62f5dc62dbcf737fb65c90032ac39f5bb9a7cc2514e0d24576223d88eb1da8f2b4d662e5a15a20917589492203838bb3da4b917ca7f4db012c632664718f646a961415e56ddd89e36658376506465fec9e7d7c65884f506eb9a9385b971a7aa53f041eded63eee1ba5dfc91027a2b61c7b248926f5d5039d4c105223f40d2d2206e87ffd20ec11f679aad21087997432d0d35f8b338cbc888a01fbaa553e3e3da7bb2c5071b8366c71f9a5c374d8346f1c29425e3b84286c512965910ed7aa6a926e886ddc626b578a7ef9a2afdced2885db4f5c5953f0bebe2c4e5ce2405da32bc2579f44f7b403e5608985624501126e4143161502c97b9d2ee4f4e8a13b52715cc40d365cd8918db8143a5a8c1acf8d143264272ba8779b76d98fce1bb89d91b147eccd26106d2beb74ef5020dd29ec84", - "nonce" : "0x1d", - "storage" : { - } - }, - "945304eb96065b2a98b57a48a06ae28d285a71b5" : { - "balance" : "0xd3e4b5453acbfee3", - "code" : "0x6da51aee682e4234c81890984b0e4b7b41f0e7c796b0bd1cd5f6e5e199baac038263421acbb851aa4c4b1b9f7a9b3b743b2c7f9c4642a2b61b9a55afb602222425e3e03108bf45b97fe81d94d612bd6c5b626248a3530a35dbe19d46044e5b50a38adb316c0febaa766c129cfe93c1461f410a35bf7809701c7efde846604b5f1075effca115d6fba575f6918a83642ae3c735cf58a5a8f5322e751ce466bc92605179f08205d6bb8faaaafe6c619f0204364f0d72561e1bba35f7e0c36bcd0e092e722f150afda0c66b987179c196beec8ae01caa69bff6aaa360fff671757cf9af3eb4fbb5b10330c5e10cbd4d84da6e17dda20b75c62a75a1f959488a4c89d945f2fb0fd62797585d9285634b9dc43b72256256186abb01e4ad78e35eb2ae11a2a472dd7bcb68c0379810f5cc347f5961983375bbadb7034dc615d4933c5b824f6b44287407ef71b438b0f39fcdf17db3ddfb24284cd59458622163965146a446ea6f8bc358fff16222a8d6d00c670633fafe256c51a31675894fa42c335b5b3b239aa98776ba0fcc228b87d5d4ce61c6f77030e85b0a8fb206752d948d9116534991cc7382c04771759c38e322ba9bc4895a60521ba3541967f768231cbc7195aa6eea9ff5ae8850b1702f812f01a13af9668c25c7b46583767c240520e9a31e63589468e2a5bd94659e04cf24b6ec8fbf51497b3a5b0b690c2bdde61fc1ebd12bc2628e8f037da55113486d5da4c1b64e3f0d0a8e79724ef44b4fb9b2eaab7a80375ccd7664ba17b5ee23666fa123abf5c9b9605a6bf55f6ae19c31cbc7362c13738e367f94c076160d0aff92873f678b65431d6f74dbbe5f3f14171a11a53e3b28bb929d71f9c76837fe2f2c39f7fb30791172d462f4127e2b40307a0f69eca60bae7872f4563273a71f52dca2de3e1457e26afbf4ae2d7136d555a5fb5c3361bdcaad6797a591344890676f977e2efe6dd16f70406761701172f778eff46e615579a150c06d09d65328174574c348cecce957c470c38799e56fcc6fc765988233b27667d742612910631d0ad368645ce3bf2f3f78126e02eaf6bdca5e4410a46a311b48f9e3e18224626964b62062cc15728c", - "nonce" : "0x1d", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x09ad523585c698f7", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - } - }, - "postStateRoot" : "18347b54b89250d51df639c5633c7d1b1e0a552e6a1b7611896d9266936c2760", - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x181b2eb1", - "code" : "0x795be1b1880ba0d1ff0b50d115c416fb7ac36fc9d2bea9f9e7212f75048cdab5287d75095451ab1623b6739fc0b8ca326281557c68443e5185640a16e727e1156afd6dde85dfe895f090e713f5c281b37862dfa4720b60f87ef7cbadac8540d09aed76138387554911aadac3a5a8ebdf110a8fbaf47cab627cb65114dda0080882a9bbbf030996a6bfcce67b166c10f4ae8744f4c25364bedb62f5dc62dbcf737fb65c90032ac39f5bb9a7cc2514e0d24576223d88eb1da8f2b4d662e5a15a20917589492203838bb3da4b917ca7f4db012c632664718f646a961415e56ddd89e36658376506465fec9e7d7c65884f506eb9a9385b971a7aa53f041eded63eee1ba5dfc91027a2b61c7b248926f5d5039d4c105223f40d2d2206e87ffd20ec11f679aad21087997432d0d35f8b338cbc888a01fbaa553e3e3da7bb2c5071b8366c71f9a5c374d8346f1c29425e3b84286c512965910ed7aa6a926e886ddc626b578a7ef9a2afdced2885db4f5c5953f0bebe2c4e5ce2405da32bc2579f44f7b403e5608985624501126e4143161502c97b9d2ee4f4e8a13b52715cc40d365cd8918db8143a5a8c1acf8d143264272ba8779b76d98fce1bb89d91b147eccd26106d2beb74ef5020dd29ec84", - "nonce" : "0x1d", - "storage" : { - } - }, - "945304eb96065b2a98b57a48a06ae28d285a71b5" : { - "balance" : "0xd3e4b5453acbfee3", - "code" : "0x6da51aee682e4234c81890984b0e4b7b41f0e7c796b0bd1cd5f6e5e199baac038263421acbb851aa4c4b1b9f7a9b3b743b2c7f9c4642a2b61b9a55afb602222425e3e03108bf45b97fe81d94d612bd6c5b626248a3530a35dbe19d46044e5b50a38adb316c0febaa766c129cfe93c1461f410a35bf7809701c7efde846604b5f1075effca115d6fba575f6918a83642ae3c735cf58a5a8f5322e751ce466bc92605179f08205d6bb8faaaafe6c619f0204364f0d72561e1bba35f7e0c36bcd0e092e722f150afda0c66b987179c196beec8ae01caa69bff6aaa360fff671757cf9af3eb4fbb5b10330c5e10cbd4d84da6e17dda20b75c62a75a1f959488a4c89d945f2fb0fd62797585d9285634b9dc43b72256256186abb01e4ad78e35eb2ae11a2a472dd7bcb68c0379810f5cc347f5961983375bbadb7034dc615d4933c5b824f6b44287407ef71b438b0f39fcdf17db3ddfb24284cd59458622163965146a446ea6f8bc358fff16222a8d6d00c670633fafe256c51a31675894fa42c335b5b3b239aa98776ba0fcc228b87d5d4ce61c6f77030e85b0a8fb206752d948d9116534991cc7382c04771759c38e322ba9bc4895a60521ba3541967f768231cbc7195aa6eea9ff5ae8850b1702f812f01a13af9668c25c7b46583767c240520e9a31e63589468e2a5bd94659e04cf24b6ec8fbf51497b3a5b0b690c2bdde61fc1ebd12bc2628e8f037da55113486d5da4c1b64e3f0d0a8e79724ef44b4fb9b2eaab7a80375ccd7664ba17b5ee23666fa123abf5c9b9605a6bf55f6ae19c31cbc7362c13738e367f94c076160d0aff92873f678b65431d6f74dbbe5f3f14171a11a53e3b28bb929d71f9c76837fe2f2c39f7fb30791172d462f4127e2b40307a0f69eca60bae7872f4563273a71f52dca2de3e1457e26afbf4ae2d7136d555a5fb5c3361bdcaad6797a591344890676f977e2efe6dd16f70406761701172f778eff46e615579a150c06d09d65328174574c348cecce957c470c38799e56fcc6fc765988233b27667d742612910631d0ad368645ce3bf2f3f78126e02eaf6bdca5e4410a46a311b48f9e3e18224626964b62062cc15728c", - "nonce" : "0x1d", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x09ad523585c698f7", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - } - }, - "transaction" : { - "data" : "0x", - "gasLimit" : "0x555ad932", - "gasPrice" : "0x1c", - "nonce" : "0x00", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "0x4bb3714f2cb3263d" - } - } -} diff --git a/tests/files/StateTests/stPrecompiledContractsTransaction.json b/tests/files/StateTests/stPrecompiledContractsTransaction.json new file mode 100644 index 000000000..afe63ad09 --- /dev/null +++ b/tests/files/StateTests/stPrecompiledContractsTransaction.json @@ -0,0 +1,1556 @@ +{ + "CallEcrecover0" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x7800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7638800", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "65ebea3d5e580a1ea587d73e5f783df701666286a974a3230be0b6530e559f34", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallEcrecover0_0input" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5dc0", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a240", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "476d2eea2fcd5a24716ccfa88be2d668c76e5ba1245ec7d598097cd3c7f93045", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallEcrecover0_gas3000" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x", + "logs" : [ + ], + "out" : "0x", + "post" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "postStateRoot" : "517f2cdf6adb1a644878c390ffab4e130f1bed4b498ef7ce58c5addd98d61018", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549", + "gasLimit" : "0x0bb8", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallEcrecover1" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x7800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7638800", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "65ebea3d5e580a1ea587d73e5f783df701666286a974a3230be0b6530e559f34", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000000173b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallEcrecover2" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x7744", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a76388bc", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "32eb8e38bf1b80b641adb042c1f02d63ce94f9adc137e49ab65a21c5a67fadc5", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c0073b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallEcrecover3" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x000000000000000000000000e4319f4b631c6d0fcfc84045dbcb676865fe5e13", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x7800", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7638800", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "65ebea3d5e580a1ea587d73e5f783df701666286a974a3230be0b6530e559f34", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9000000000000000000000000000000000000000000000000000000000000001b6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallEcrecover80" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000003f17f1962b36e491b30a40b2405849e597ba5fb5", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x7740", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a76388c0", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "8a39e97c686803fe972417eccf2876ea9eca2f7ee52482e57660367fb2f6b903", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x00" + } + }, + "CallIdentitiy_0" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000001", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x52da", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763ad26", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "c04e2f7920bb9af44403b9abe11dfcc44c8fe94e3a0460c1dc1e01fe5e428578", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "000000000000000000000000000000000000000000000000000000000000001", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallIdentitiy_1" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5217", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763ade9", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "d7708ed0b16c93b5c1441ab208f76f7f48ef296e7539c146d3ad22063d9c49de", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallIdentitiy_1_nonzeroValue" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x13", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5217", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763add6", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "53b8792df74157546486804eb0cf115252120c6cf1b79c9fa79dd23ec237efed", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x13" + } + }, + "CallIdentitiy_2" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000f34578907f", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x53f1", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763ac0f", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "a9cf0252a1984b4a8618f692c3df1386f2e2f92e9590f4e2397ed3af4ba04d4b", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0000000000000000000000000000000000000000000000000000000000000000f34578907f", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallIdentitiy_3" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x000000000000000000000000000000000000000000000000000000f34578907f0000000000", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x53f1", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763ac0f", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "a9cf0252a1984b4a8618f692c3df1386f2e2f92e9590f4e2397ed3af4ba04d4b", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "000000000000000000000000000000000000000000000000000000f34578907f0000000000", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallIdentitiy_4" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5a9a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a566", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "26d88956e24488d4aca78adf402dfb7bfc876decb343cbee56dad7042fafae81", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallIdentitiy_4_gas17" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x", + "logs" : [ + ], + "out" : "0x", + "post" : { + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5a88", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a578", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "83ca393c8b9cab5f8c84c31beeb22351796d703a2f03733e420bca97597de906", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "gasLimit" : "0x5a88", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallIdentitiy_5" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "#35659", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000004" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x029494", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7616b6c", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "4989c35b1e3c63ec64b9609233403c5d2801db0b80e67ff0020acce34f87e2dc", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000004", + "value" : "0x00" + } + }, + "CallRipemd160_0" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x000000000000000000000000ae387fcfeb723c3f5964509af111cf5a67f30661", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000003" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5598", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763aa68", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "4142e87e6faee33e5cb27673181220b5913f5472b456d4729df97c2c461d5f64", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "000000000000000000000000000000000000000000000000000000000000001", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000003", + "value" : "0x00" + } + }, + "CallRipemd160_1" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000003" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5460", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763aba0", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "e024631bdbee5ed624471c7b187275debb777717eb93c67b991fca1eff55f1f3", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000003", + "value" : "0x00" + } + }, + "CallRipemd160_2" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x000000000000000000000000dbc100f916bfbc53535573d98cf0cbb3a5b36124", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000003" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5724", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a8dc", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "6f0d0f570c3ea3dce57553555b4ef7347692a90c13f6520b36a6b5bf00c1c3ad", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0000000000000000000000000000000000000000000000000000000000000000f34578907f", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000003", + "value" : "0x00" + } + }, + "CallRipemd160_3" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x000000000000000000000000316750573f9be26bc17727b47cacedbd0ab3e6ca", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000003" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5724", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a8dc", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "6f0d0f570c3ea3dce57553555b4ef7347692a90c13f6520b36a6b5bf00c1c3ad", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "000000000000000000000000000000000000000000000000000000f34578907f0000000000", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000003", + "value" : "0x00" + } + }, + "CallRipemd160_4" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000001cf4e77f5966e13e109703cd8a0df7ceda7f3dc3", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000003" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5d58", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a2a8", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "ae3ed6ba314a058bcae04c9784bae9fb5189c8a587b5faf6f76a9641822721cb", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000003", + "value" : "0x00" + } + }, + "CallRipemd160_5" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x", + "logs" : [ + ], + "out" : "0x", + "post" : { + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x030d40", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a760f2c0", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "b09a08a79e7d94f0f602fd28335abba0a7a9596614c7165508eb829994fdef29", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000003", + "value" : "0x00" + } + }, + "CallSha256_0" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000002" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5310", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763acf0", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "eeca38e090fd543d6b0a98b29da4897668a938553f2f0635fd16f18aba9feb6e", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "000000000000000000000000000000000000000000000000000000000000001", + "gasLimit" : "0x0493e0", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000002", + "value" : "0x00" + } + }, + "CallSha256_1_nonzeroValue" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000002" : { + "balance" : "0x13", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5244", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763ada9", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "ee52cd49848866b9ed38c4842f4fbbd1861ba63a7242484d61001737485666fa", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000002", + "value" : "0x13" + } + }, + "CallSha256_2" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000002" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5430", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763abd0", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "ac7b1816d2da72ba4fbb4174393baf50044ec0fd48de527b68c5fe401722094c", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0000000000000000000000000000000000000000000000000000000000000000f34578907f", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000002", + "value" : "0x00" + } + }, + "CallSha256_3" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000002" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5430", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763abd0", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "ac7b1816d2da72ba4fbb4174393baf50044ec0fd48de527b68c5fe401722094c", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "000000000000000000000000000000000000000000000000000000f34578907f0000000000", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000002", + "value" : "0x00" + } + }, + "CallSha256_4" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000002" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x5ad0", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a763a530", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "558346ba263129da8c829daed548c281c17468424f9e050ffbd4e32f2649f6db", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000002", + "value" : "0x00" + } + }, + "CallSha256_5" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x989680", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x259911ec9f4b02b7975dfa3f5da78fc58b7066604bdaea66c4485c90f6f55bec", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000002" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x02bbf4", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a761440c", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "postStateRoot" : "7aed225ae51cb8558108fe3749adf375b1ee53f5cf2611adc33af187100138f7", + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit" : "0x030d40", + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000002", + "value" : "0x00" + } + }, + "callTxToPrecompiled_1" : { + "env" : { + "currentCoinbase" : "aa69d40e4ab383b25fa6c17560dd77b387480dd8", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "logs" : [ + ], + "out" : "0x", + "post" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x0a968163f0a57b400001", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aa69d40e4ab383b25fa6c17560dd77b387480dd8" : { + "balance" : "0x0354a6ba7a180000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cd2a3d9f938e13cd947ec05abc7fe734df8dd826" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x", + "nonce" : "0x32", + "storage" : { + } + } + }, + "postStateRoot" : "8d4497a68edae0264b8f36c9f508f625bd4cf980b1bf2946822287814537df96", + "pre" : { + "0000000000000000000000000000000000000001" : { + "balance" : "0x01", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aa69d40e4ab383b25fa6c17560dd77b387480dd8" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cd2a3d9f938e13cd947ec05abc7fe734df8dd826" : { + "balance" : "0x1fc3878078aaebd80000", + "code" : "0x", + "nonce" : "0x31", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "0x09965e", + "gasPrice" : "0x09184e72a000", + "nonce" : "0x31", + "secretKey" : "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", + "to" : "0000000000000000000000000000000000000001", + "value" : "0x0a968163f0a57b400000" + } + } +} \ No newline at end of file diff --git a/tests/files/VMTests/RandomTests/vm201506052232CPPJIT.json b/tests/files/VMTests/RandomTests/vm201506052232CPPJIT.json deleted file mode 100644 index 23dff8468..000000000 --- a/tests/files/VMTests/RandomTests/vm201506052232CPPJIT.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "randomVMTest" : { - "env" : { - "currentCoinbase" : "2a19049af61869dd2c46a9ee85c6662ab9fb1458", - "currentDifficulty" : "0xa580ed81be2ef840", - "currentGasLimit" : "0xf35d3ad90aa14c5c", - "currentNumber" : "0x7ff6bd68c54c031e", - "currentTimestamp" : "0x1b3cf4b5c24c6ecf", - "previousHash" : "2e1533355813afa2f1d0e6dbbd0310aeb0cd36aa66348fff9fbd6eb34c1ecacd" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "a8333c288c297fe274ecc7edd645184521802e53", - "code" : "0x786e80ee51f42664c295675108206cc067ed31e903b915360ff073ee0fa83f70b122d692e31a01dff3593131db74886741f68e9b67c9e30b678778fe65c891605f7d59771f14031bd5d1617fc5a380fd51f9b0ff0a8e850f030c9e5ee96b717f71d0e54365e9ee8f7ab8a494864c1a837dfab57c12194fa7e8e290cb976f57b2d1ab30edee6a7eba2b1a96717b7f2ada6765fdfea367668c6496cbe2c6bc6b166bf1cc2f16edea7a5a1537764f6eb0d092088df6cbfdc38f21e2e860c857b0643746e573322425fd5ac184b3fcebef7a01478c2687636363753c221569415eef55bee95837c985faff2f8fa63413307c4997f09f3535bae3c945c9048ef4610132d22fab681421b17df4e513b08d686dafc9add05f3c1c9e67aa9026c4c80e9162671ad819b3cb577296703876d00b55f0fe0cdd0397aebbda50d8776a2ab57767cfb29342525ab07db7a61afe3be57ea76387b38358b1a4849bedd12b96ede30fbaa67f917f27857d424f9bc7ec6444384e1b51837d2cf0ad5d9f168ef78c9faf89ab3b23de8561ace07f13a599ffccc1757e625ae802fac4090ea66b1081cd5f3b6368f566b58326439d6a1f7cee083baf4e2b338bff75e0f9df9b6b93b5f4f93e603dec176ae21ed1448737367e6c599af40bc33863dcdde9be9295cafc7d5e3a64d3d48f3bd676c8a5b916a970b4f9e1ce1bfaa9beaee29c156c42d87c027e6f7e825a69ad9f470dc95be137088dff8d3e83470a79181686af7705a21af376ac9212365948ba4b9b4080584d8cb49c5644cce1f7863372787f18084708f611439d3731659377c532a5d57611a0da65876997e113a59a172b089c544743b7295cd9897c79724aca53b2dab706cf0f24978e9248c810efebbb9597e4c84dba56166966d73c50f13b52995d4b7908ef6ccd9989eeed8262326eeb52bfbfefb06f63cd8cfb753c4f7128f85c7982b7274024f44b798ececa14833a746c1f22dd0b0e8b3fac838fb740987c1229beb42cd6657be2444022629f6893d90811f9bdd579b76995d77ab8902b2fed40ca67b021adb6b19a7010a174909136ecb5f288334837d5d3ffece95aba2f4aec886247c70e771ba1bb7b61644fb1820a5920f79c2b7284d649d93aad11526383f25a66660f5c96548ff45fa370e8502ccd980f63493fde0cc1d15140e3a36f8289606c9e969b9d04176a7b9611a6ec557d1bd9ef4a2026b2a984c4059256770b602f863bcc10543f7560fb6da0984e7fa7a7d1dcf42d13106d02af71f80463d4e4644c4e550bdc865cea601ac921e9e97bf4906dd9e3513cdddb479bf49965c1c639de0c5680dbdb66f8cc2d9b6901f0ea0804d48380c901616b626db25146fd8d1849f9ae81e378ba2e768c5544bad7b8f1fa092df1e8eb2c6aa92cfddf3c309f466a165725a98cd034cb19caef9670a16730dc9f35958d087dca07f0a5e743226442de788c4f077f07d7c75ab5dd8173da4c44b9d60a452435c09689706cab8bd8c5cf5c4184cb99722ea485c07c83e1e3b5179ecbfed644e4e1c90d0165847383e380cd61b88a645a849ad91c08", - "data" : "0x6c9e88e10a667b3c988590b7e4977bfc7c6fe83e72065b12020e88681ef360d8575f9a945e16ea892aead5745552de8c2c0997f98a55b933548bf73fb90c6cefe360387fe0764cf7a3e04d8a90212bb81b487e7d9148a4cf36e968be6686d1433d4bc5a36d313c62c4c210ef894920b1fc2b126beaa7d585feb9e8a332e19d2f77e65f28d3959701e333c005e157bdeba414db2894f19876c1631b7dbde067d64a91a083ec9e376b759f9652a8b2bde23d4c31ba725fa02532b023a4c6480163b9ecdfd1f655b4386886f6a48f4f878b85dd8c656c0c808acaac60fa675643bdf5a7262a9d74889473ede78cffe05a8068de215371508e34c97b2d7fb93550c36bbd4177d74da227ee3e9098aef548287a9fcfc4333d40f87f2f326d787814cbedd3aaae8ecbabee2d4107e6a67a6942c63e788b5b8167f6958156d33952a763121e11ca7d952315ec4124944a72e93ffbeac7f958480ca7d32830c35e510bd1b9bbc567a02dc4c510e7b6e060017c483eeef66d397ed1dfea752c7fd8ceca11059d83cb81191afdef0552c06e42d722d894fa394f64e84628395eef67094b74b4439920828d63beafd6e861903c55614f20714eee5f80e19967ec73ce5d0be3eb47215bed79604303854d69c0d401b04616d6de839011812a14a3b6c8357ac86ab39062a3f13e6da2dd1e837eb2517707baac4a3e54d7bbde47b078e6f444d6cd5a5fbd26ba61ab5153e5c384", - "gas" : "0xb44b0c6ba708e0d1", - "gasPrice" : "0x1c", - "origin" : "567f2d84e28d698cb2a8de521ffe23987de1859c", - "value" : "0x601add3c" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x37b29d44", - "code" : "0x786e80ee51f42664c295675108206cc067ed31e903b915360ff073ee0fa83f70b122d692e31a01dff3593131db74886741f68e9b67c9e30b678778fe65c891605f7d59771f14031bd5d1617fc5a380fd51f9b0ff0a8e850f030c9e5ee96b717f71d0e54365e9ee8f7ab8a494864c1a837dfab57c12194fa7e8e290cb976f57b2d1ab30edee6a7eba2b1a96717b7f2ada6765fdfea367668c6496cbe2c6bc6b166bf1cc2f16edea7a5a1537764f6eb0d092088df6cbfdc38f21e2e860c857b0643746e573322425fd5ac184b3fcebef7a01478c2687636363753c221569415eef55bee95837c985faff2f8fa63413307c4997f09f3535bae3c945c9048ef4610132d22fab681421b17df4e513b08d686dafc9add05f3c1c9e67aa9026c4c80e9162671ad819b3cb577296703876d00b55f0fe0cdd0397aebbda50d8776a2ab57767cfb29342525ab07db7a61afe3be57ea76387b38358b1a4849bedd12b96ede30fbaa67f917f27857d424f9bc7ec6444384e1b51837d2cf0ad5d9f168ef78c9faf89ab3b23de8561ace07f13a599ffccc1757e625ae802fac4090ea66b1081cd5f3b6368f566b58326439d6a1f7cee083baf4e2b338bff75e0f9df9b6b93b5f4f93e603dec176ae21ed1448737367e6c599af40bc33863dcdde9be9295cafc7d5e3a64d3d48f3bd676c8a5b916a970b4f9e1ce1bfaa9beaee29c156c42d87c027e6f7e825a69ad9f470dc95be137088dff8d3e83470a79181686af7705a21af376ac9212365948ba4b9b4080584d8cb49c5644cce1f7863372787f18084708f611439d3731659377c532a5d57611a0da65876997e113a59a172b089c544743b7295cd9897c79724aca53b2dab706cf0f24978e9248c810efebbb9597e4c84dba56166966d73c50f13b52995d4b7908ef6ccd9989eeed8262326eeb52bfbfefb06f63cd8cfb753c4f7128f85c7982b7274024f44b798ececa14833a746c1f22dd0b0e8b3fac838fb740987c1229beb42cd6657be2444022629f6893d90811f9bdd579b76995d77ab8902b2fed40ca67b021adb6b19a7010a174909136ecb5f288334837d5d3ffece95aba2f4aec886247c70e771ba1bb7b61644fb1820a5920f79c2b7284d649d93aad11526383f25a66660f5c96548ff45fa370e8502ccd980f63493fde0cc1d15140e3a36f8289606c9e969b9d04176a7b9611a6ec557d1bd9ef4a2026b2a984c4059256770b602f863bcc10543f7560fb6da0984e7fa7a7d1dcf42d13106d02af71f80463d4e4644c4e550bdc865cea601ac921e9e97bf4906dd9e3513cdddb479bf49965c1c639de0c5680dbdb66f8cc2d9b6901f0ea0804d48380c901616b626db25146fd8d1849f9ae81e378ba2e768c5544bad7b8f1fa092df1e8eb2c6aa92cfddf3c309f466a165725a98cd034cb19caef9670a16730dc9f35958d087dca07f0a5e743226442de788c4f077f07d7c75ab5dd8173da4c44b9d60a452435c09689706cab8bd8c5cf5c4184cb99722ea485c07c83e1e3b5179ecbfed644e4e1c90d0165847383e380cd61b88a645a849ad91c08", - "nonce" : "0xdf8278dd31cb2f9f", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506052232PYTHON.json b/tests/files/VMTests/RandomTests/vm201506052232PYTHON.json deleted file mode 100644 index a7ab156dc..000000000 --- a/tests/files/VMTests/RandomTests/vm201506052232PYTHON.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "randomVMTest" : { - "callcreates" : [ - ], - "env" : { - "currentCoinbase" : "0be8022b1ae5972ff97a26cc93a11b3c7a032051", - "currentDifficulty" : "0x03ee2ae29a756db1", - "currentGasLimit" : "0x0a2c82c727d04f35", - "currentNumber" : "0x8ae87d8b161c0815", - "currentTimestamp" : "0x3c528969", - "previousHash" : "59b8fbf3daf8e7b0b7861903ccac78df70a3597efc6a83e399df5f1ec66b3fca" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "2f957a4c7c7f0b66c79e12cccae139582a9f151a", - "code" : "0x7ef2d6d7b79440ef574194a59fed6c1c426b6af9f69da960a15643fdea890eed157e6ff60939c55c7d2888ce86eac4bd5432c79ae0ea7b8f3c9d13a9d76f29cc0b72e939c2be440936dfc4a25ce2f799f7ad3938c19065ce245402fef1547a2bc053a7b89ad18f28dc0ee57b67ec43af5f909b419b37a2bdd1ec7125cf4d08f58748cfde2aea18a0a0c6f5188f07", - "data" : "0x307b4badfcb3016a9d2b7ef4d134303d26d2e9a2abb1545e307ace7b028d7e65dcdaf6dcac4e47cd198ab2361759e480ec5b38b6a1fc076b055dbe94253261b55a683f20b0e44a6410277967a2e3f80a2b998ff66d99665ecb047566387545faa77e999478cfb57f3979453d4e7988a36dbac16de9ea674fa539b8b5f8aa197d7d2e0d1c03d02e4348a9509e5ee7e12ba09a634ea259c6266c49adae8e0177c51b5ebadea846aa62dc3491f00c8038eb7eaa172fb45f17799ea2e827c4dc525586cc26d2bfdf827a86aace51d3486097d96a6254f68771d0fafcac2feddd943074d5735d5c15805ee484347bab516727e58d4816d0b379b97ab544415fd9c53aee4e330b8806a7d77e685149446c89c4111c98df704476a33d3561a813a1f729b8cb44d395d105500763fabc3f366ce2b4daf22b376437e7514687506b80c077848f8018189676ed2d7c0394716c2a555bf5d66b3e2a121025bacec8714c1787676478d3a907796ce9f4f55f41b2d61210dbaab2c37f37854e1ce5768af80f19a370d843f0175f81629e0c4ea7e8510db964ad3b94c66224f4b286684d8a0b72d1b71ac5e7777096d55e05ed1248e018a72bc3dd22020290c8ad9fae0f5b639decb2db6393ab2f4b6e2a91b4a996844a2b3509e9ceea03026a9d4e5e230440ec3e633429946b7ea3a380537a1e7190ea161368a83aa8662f4aab43112036", - "gas" : "0x807e02307eb73db4", - "gasPrice" : "0x1d", - "origin" : "c034c75a8fbe48573a478426b124bf4b388f86f3", - "value" : "0xb6bc4cd2ce8fc6cd" - }, - "gas" : "0x807e02307eb73db4", - "logs" : [ - ], - "out" : "0x", - "post" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x55d1d81c", - "code" : "0x7ef2d6d7b79440ef574194a59fed6c1c426b6af9f69da960a15643fdea890eed157e6ff60939c55c7d2888ce86eac4bd5432c79ae0ea7b8f3c9d13a9d76f29cc0b72e939c2be440936dfc4a25ce2f799f7ad3938c19065ce245402fef1547a2bc053a7b89ad18f28dc0ee57b67ec43af5f909b419b37a2bdd1ec7125cf4d08f58748cfde2aea18a0a0c6f5188f07", - "nonce" : "0xa10eb3ed88a2d9d7", - "storage" : { - } - } - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x55d1d81c", - "code" : "0x7ef2d6d7b79440ef574194a59fed6c1c426b6af9f69da960a15643fdea890eed157e6ff60939c55c7d2888ce86eac4bd5432c79ae0ea7b8f3c9d13a9d76f29cc0b72e939c2be440936dfc4a25ce2f799f7ad3938c19065ce245402fef1547a2bc053a7b89ad18f28dc0ee57b67ec43af5f909b419b37a2bdd1ec7125cf4d08f58748cfde2aea18a0a0c6f5188f07", - "nonce" : "0xa10eb3ed88a2d9d7", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060003CPPJIT.json b/tests/files/VMTests/RandomTests/vm201506060003CPPJIT.json deleted file mode 100644 index 6171276b8..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060003CPPJIT.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "randomVMTest" : { - "env" : { - "currentCoinbase" : "0000000000000000000000000000000000000000", - "currentDifficulty" : "0x02993b26", - "currentGasLimit" : "0x5cf6486317fdb885", - "currentNumber" : "0x7d3c9c2de89b2de8", - "currentTimestamp" : "0xb841e027096ca4e2", - "previousHash" : "80a7432990555a8058fb2aeeb2c9a87c3fdcc9d8d3fd372cdb07a40fd56991e1" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "7b646fbc38356d7ef9275d8940dcfa08d73951fd", - "code" : "0x7a6bd87691782526a69d0e8b0660d2d1158903d5b7efc9636ab2ef037ab1ba18347fe3f9a4aec5538e8292a6bccc210453571f02a576eab0556980750dabe791355ade04720c6945461bab9f0146c92541b57ca9dcd1448a79a630fb6d8335571fc733b6f604dd4b9872265f940ac36ee4bb436a780b7ed4dbb81b7e9a28827f2f68b9f03392ac83d0b7e45a814a4b9decf445cac3ccffca647ff87e43453b09609968bd5936225a6196edba626e6a718769bfe5795c4a9ba98c60bb63d52beda40b7cd7ea7e766fe9c9e75bdfb2c5738dcced61111a8258dc764b53d910f7da607403718dfc6c5aa7db8b32d21fcdff0ee87721abc760616dfc91e76b77618207579a7dc31ea97c46d9cf868aaa1ccba2c76d0570c0435896a1a6a0037e82580d2af831d8a2", - "data" : "0x", - "gas" : "0x9606430e52c4d31a", - "gasPrice" : "0x1c", - "origin" : "14cb9f799b1b93210da7682ef34f28731d041637", - "value" : "0x23cb9da58e490f35" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x496e8fc2", - "code" : "0x7a6bd87691782526a69d0e8b0660d2d1158903d5b7efc9636ab2ef037ab1ba18347fe3f9a4aec5538e8292a6bccc210453571f02a576eab0556980750dabe791355ade04720c6945461bab9f0146c92541b57ca9dcd1448a79a630fb6d8335571fc733b6f604dd4b9872265f940ac36ee4bb436a780b7ed4dbb81b7e9a28827f2f68b9f03392ac83d0b7e45a814a4b9decf445cac3ccffca647ff87e43453b09609968bd5936225a6196edba626e6a718769bfe5795c4a9ba98c60bb63d52beda40b7cd7ea7e766fe9c9e75bdfb2c5738dcced61111a8258dc764b53d910f7da607403718dfc6c5aa7db8b32d21fcdff0ee87721abc760616dfc91e76b77618207579a7dc31ea97c46d9cf868aaa1ccba2c76d0570c0435896a1a6a0037e82580d2af831d8a2", - "nonce" : "0x30a3e8694ecb08fe", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060003PYTHON.json b/tests/files/VMTests/RandomTests/vm201506060003PYTHON.json deleted file mode 100644 index 5363cbf4d..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060003PYTHON.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "randomVMTest" : { - "callcreates" : [ - ], - "env" : { - "currentCoinbase" : "cf90bea4a39ca7a018beb203c84161b27c92813a", - "currentDifficulty" : "0xca27782e6f34fa0b", - "currentGasLimit" : "0xedb3a183d3febe2c", - "currentNumber" : "0xb17ec317aa876050", - "currentTimestamp" : "0x564ceda9b9662639", - "previousHash" : "2a778d568763caf8da3a5a243b1aa20bbd9597ee949b787d577e44243ca63136" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "a71dfcc90e7b90a0d9745c586f98f746d1e2790c", - "code" : "0x7d11f02e17bc84bc6cd96b4772835f489f3d239b32c4a66036f012569e6cfc6d893bfd55b1d2f0eada73b993708267b971033d30c37597724be6bb49508a4a5a3e5acc99c0e1599583cd2f6ddf92b6142fc8a7411082f38d19826d442a16a380c175f9f3b7a388528f6178e77a1e2c9c3fd334e06e3a5cebe5fa374cc7bacaa6b5b9183da85c4ba7799c6d52d857e4acb873d310255f995445d3cc0ac1a696fd4dec047b9eee68350e4c6f46206780eee6faa58911b17140b813f76fd4954f556e5a64beefa3cf9fc4b068a9fd4b9a927710088a9ecfbf32594a7ae942834b3da35f9bb0ddb819b7b072d8050cdba63c5d63646d87082e0c02b990064b75b33313b5d129e2ed35b666b5d09159a6d81aa66a25f47ecfef8f9b22a9be0d929ce9c5a3514689f9ae2a36b014a171191b5077b202d672c16221fe92040ce4acdaec661419675e15f9359e74613291b9bc2c7b98bac3c67fd269c467b97634e1f676d2ca314b1160325dcf51fbe6838016dc209ad3c2b7e0107d8ef1f6d0c74411a1a15cd79c237265d234a6b18dd9eae184c8fca5396ec09164643ed58dd16a7e403cd47f6cb7fdd556c7780431b7d95b5e1bcb854550f0b4a0c86129704d92737596d78b7c29f45f57f4fdf3f53b93958409036cb7fc873839a189a483fa6421035763355e3a6f7b368bad4b8f1b9f57987a46fbfe46a8047e164a3e4a9417036782ccd88560ae659217af196ba66791661ee7044ec0b579b69757e45ebc518c5bee224a4c677cd0312ad49a975c0ff992c26fa4e21409c508c3197feb40e7471e4ff67753c9cff00b0afc96489230708273084569d13930820ac42b7f901ea066121faef9c98e8039130c4eeb4212e4dab6399248b395739de01e9f7964ca5d25f8908760a37e4e4e94cbf378470a1b947f4dbf9fe1ade4e0c15697c6aafccff45520d5e82c6a95d94cea6f212e0fcc344d6ba6846f89d979e289b553aeb676160dc78e467df21bfaa6a55f89be01f726acba9a95b5e46911bb9a5aa8081ac6edb7710eaaf8e87ef307b310d0cb0666541086ee627b72021a9a3647728c2782927eec8a37449a5838f6d1d80f3d98b6e41a74ac98525dba7d24252c3020aab452947d89a671536b6696e7e41c9beeba717c9c19d850c36ff56737eb4a8669ede2dd2268f549138e6a27387bba7bb9400d59082c859d3593296f4f4f80fd24ef80144687590b839fa75876f497d02bf4dc08f675a48d9aadf4a1edd6c7265b88710c79b8d07d14dfacc61e95d2290c32f82a8d58a9b76520fe6afddaef70f797c29ad897f3f8c2bb3e40f7bf8746b48f7feaec9b9cbfb83add0a08ab742cdc4190821b074f1a443e1f4b6e9df0d1f710cb7088beaaa17c21a97965072e19898507d5fc106589fd7fbc08b46e4c75b137dafb7b509fe9a9ff018bbc05", - "data" : "0x76655643161db5cdec6073fce4e12c9913574503f154c80962cde5cf70921635bf8b0b91deec7f731db8ba0ce18b3744703af0c573d762a25ccc96ef230889018cad60b465aac2670237c568ea0592f6cecc571ed8784a6048707de2010a6356fd6315e6ad44d6a163b2ef4a45df4e7d2be19235b5ce5fbf709201c0065a713834469f80349639a69e4a6881c998614b8b65bcbb1b5b997875eb6c9625098135f3f64faa4a3895227cce74dea82aa76af8897b606c0fe048ae7fa47be9f5fa49a124451d6f5f756d0b91c2271e487e341ad48f1d2007dd3f79e7ee3159989344db2317ee0b28518aca787b056c93c5307105f36bc441a6e35147e1cc0eae204974e811ace43c6b49bd5da71b1f894442bdd18b7b476176d19a55a6f4670da12a60ea0f45c408ee7004d5fa0a37989d647e60c814547cd86623f56c7b9c9e5054a8d33e2eb547964268aeb4b6c7a5ae6a2f62dd6a7b8aabbb34492f75bf2bef79a53e76dd965c46fa6ad1ed4db321cc7232d2bed7157e4d14c6b366d2d26f4d55f8e17870576917ba17085af297fd4cfb6b26e64138cd384730d9313277054b7530c688ebcfc06ef8ad568f92d720b445cb12918c596b65796367c625eb52661d3c4c96", - "gas" : "0x439ee47c", - "gasPrice" : "0x1d", - "origin" : "71134870cb1a7f4e4235d2be6918cf43a68eec35", - "value" : "0xe74255e5d9cc1cd7" - }, - "gas" : "0x439ee47c", - "logs" : [ - ], - "out" : "0x", - "post" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x04667f01", - "code" : "0x7d11f02e17bc84bc6cd96b4772835f489f3d239b32c4a66036f012569e6cfc6d893bfd55b1d2f0eada73b993708267b971033d30c37597724be6bb49508a4a5a3e5acc99c0e1599583cd2f6ddf92b6142fc8a7411082f38d19826d442a16a380c175f9f3b7a388528f6178e77a1e2c9c3fd334e06e3a5cebe5fa374cc7bacaa6b5b9183da85c4ba7799c6d52d857e4acb873d310255f995445d3cc0ac1a696fd4dec047b9eee68350e4c6f46206780eee6faa58911b17140b813f76fd4954f556e5a64beefa3cf9fc4b068a9fd4b9a927710088a9ecfbf32594a7ae942834b3da35f9bb0ddb819b7b072d8050cdba63c5d63646d87082e0c02b990064b75b33313b5d129e2ed35b666b5d09159a6d81aa66a25f47ecfef8f9b22a9be0d929ce9c5a3514689f9ae2a36b014a171191b5077b202d672c16221fe92040ce4acdaec661419675e15f9359e74613291b9bc2c7b98bac3c67fd269c467b97634e1f676d2ca314b1160325dcf51fbe6838016dc209ad3c2b7e0107d8ef1f6d0c74411a1a15cd79c237265d234a6b18dd9eae184c8fca5396ec09164643ed58dd16a7e403cd47f6cb7fdd556c7780431b7d95b5e1bcb854550f0b4a0c86129704d92737596d78b7c29f45f57f4fdf3f53b93958409036cb7fc873839a189a483fa6421035763355e3a6f7b368bad4b8f1b9f57987a46fbfe46a8047e164a3e4a9417036782ccd88560ae659217af196ba66791661ee7044ec0b579b69757e45ebc518c5bee224a4c677cd0312ad49a975c0ff992c26fa4e21409c508c3197feb40e7471e4ff67753c9cff00b0afc96489230708273084569d13930820ac42b7f901ea066121faef9c98e8039130c4eeb4212e4dab6399248b395739de01e9f7964ca5d25f8908760a37e4e4e94cbf378470a1b947f4dbf9fe1ade4e0c15697c6aafccff45520d5e82c6a95d94cea6f212e0fcc344d6ba6846f89d979e289b553aeb676160dc78e467df21bfaa6a55f89be01f726acba9a95b5e46911bb9a5aa8081ac6edb7710eaaf8e87ef307b310d0cb0666541086ee627b72021a9a3647728c2782927eec8a37449a5838f6d1d80f3d98b6e41a74ac98525dba7d24252c3020aab452947d89a671536b6696e7e41c9beeba717c9c19d850c36ff56737eb4a8669ede2dd2268f549138e6a27387bba7bb9400d59082c859d3593296f4f4f80fd24ef80144687590b839fa75876f497d02bf4dc08f675a48d9aadf4a1edd6c7265b88710c79b8d07d14dfacc61e95d2290c32f82a8d58a9b76520fe6afddaef70f797c29ad897f3f8c2bb3e40f7bf8746b48f7feaec9b9cbfb83add0a08ab742cdc4190821b074f1a443e1f4b6e9df0d1f710cb7088beaaa17c21a97965072e19898507d5fc106589fd7fbc08b46e4c75b137dafb7b509fe9a9ff018bbc05", - "nonce" : "0xb75979942880750b", - "storage" : { - } - } - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x04667f01", - "code" : "0x7d11f02e17bc84bc6cd96b4772835f489f3d239b32c4a66036f012569e6cfc6d893bfd55b1d2f0eada73b993708267b971033d30c37597724be6bb49508a4a5a3e5acc99c0e1599583cd2f6ddf92b6142fc8a7411082f38d19826d442a16a380c175f9f3b7a388528f6178e77a1e2c9c3fd334e06e3a5cebe5fa374cc7bacaa6b5b9183da85c4ba7799c6d52d857e4acb873d310255f995445d3cc0ac1a696fd4dec047b9eee68350e4c6f46206780eee6faa58911b17140b813f76fd4954f556e5a64beefa3cf9fc4b068a9fd4b9a927710088a9ecfbf32594a7ae942834b3da35f9bb0ddb819b7b072d8050cdba63c5d63646d87082e0c02b990064b75b33313b5d129e2ed35b666b5d09159a6d81aa66a25f47ecfef8f9b22a9be0d929ce9c5a3514689f9ae2a36b014a171191b5077b202d672c16221fe92040ce4acdaec661419675e15f9359e74613291b9bc2c7b98bac3c67fd269c467b97634e1f676d2ca314b1160325dcf51fbe6838016dc209ad3c2b7e0107d8ef1f6d0c74411a1a15cd79c237265d234a6b18dd9eae184c8fca5396ec09164643ed58dd16a7e403cd47f6cb7fdd556c7780431b7d95b5e1bcb854550f0b4a0c86129704d92737596d78b7c29f45f57f4fdf3f53b93958409036cb7fc873839a189a483fa6421035763355e3a6f7b368bad4b8f1b9f57987a46fbfe46a8047e164a3e4a9417036782ccd88560ae659217af196ba66791661ee7044ec0b579b69757e45ebc518c5bee224a4c677cd0312ad49a975c0ff992c26fa4e21409c508c3197feb40e7471e4ff67753c9cff00b0afc96489230708273084569d13930820ac42b7f901ea066121faef9c98e8039130c4eeb4212e4dab6399248b395739de01e9f7964ca5d25f8908760a37e4e4e94cbf378470a1b947f4dbf9fe1ade4e0c15697c6aafccff45520d5e82c6a95d94cea6f212e0fcc344d6ba6846f89d979e289b553aeb676160dc78e467df21bfaa6a55f89be01f726acba9a95b5e46911bb9a5aa8081ac6edb7710eaaf8e87ef307b310d0cb0666541086ee627b72021a9a3647728c2782927eec8a37449a5838f6d1d80f3d98b6e41a74ac98525dba7d24252c3020aab452947d89a671536b6696e7e41c9beeba717c9c19d850c36ff56737eb4a8669ede2dd2268f549138e6a27387bba7bb9400d59082c859d3593296f4f4f80fd24ef80144687590b839fa75876f497d02bf4dc08f675a48d9aadf4a1edd6c7265b88710c79b8d07d14dfacc61e95d2290c32f82a8d58a9b76520fe6afddaef70f797c29ad897f3f8c2bb3e40f7bf8746b48f7feaec9b9cbfb83add0a08ab742cdc4190821b074f1a443e1f4b6e9df0d1f710cb7088beaaa17c21a97965072e19898507d5fc106589fd7fbc08b46e4c75b137dafb7b509fe9a9ff018bbc05", - "nonce" : "0xb75979942880750b", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060013CPPJIT.json b/tests/files/VMTests/RandomTests/vm201506060013CPPJIT.json deleted file mode 100644 index 82a2d5ac9..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060013CPPJIT.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "randomVMTest" : { - "env" : { - "currentCoinbase" : "189f58d5ef7bdb2935f8b8a698ef219e35994fe4", - "currentDifficulty" : "0x84876928e87b41a4", - "currentGasLimit" : "0x10cae8f1", - "currentNumber" : "0x76ab7073955627fc", - "currentTimestamp" : "0x166a82ef", - "previousHash" : "d07ee68dc9a390888a872f4514886620645d13b85963f7b40dca99d85cd89788" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "56447178c6607f47e0513e4d654e2bd0ec613a19", - "code" : "0x70f5879c3a83ab5da815c1047edaa5bc22907aac3e4e9fbaeb5638b8c998b8b940675abbc89ed4c047b214f512a1601a3768d07c8d5dbfcc381cbb54745f1c0c9255866cd322f5b9af41893abe83276235517501ecf5a723d3f1fd9bdef48b5232fbfed97171029561651baa3b4bc71773148918649129910c4ca9615a93890fc144f61ab66461cee1e12576d274d5dce2cb206c05952913d7afc397cdc3180f21cf277b858c7c2bd7b821d468d08b6f03abb80fe34e6410c8781271243d3c956db1a20cd1e0e64192dca8213c150d7083ccf229cd085864fe558c6241034cf4637ac3d8f2b81ab24a90a7e93e3318b4e39f02c601b326fed43e41e02c63059b80e870c78e76f59d901014065ae7f8be5a85d210765e9a831b82164ce142b66a2628d6be7a9a8f449983b9c86c9ae88505bfd5130bcdf4c4622b69419017ce7c34a7f563c98e74cb7b55cc61aea40c4494d3e0d65f01962794ec7881784a68fb3f96217484b8aa3c1f605201742d41bc492397e3ae55706943644354df3d1f433028c1074249673a70a2a82c0a9ef15da6731f1d68239f07d20c6a1bc3ea2778f3782a6416957d38dead3c6f2dfb6cd6ed320e51eba8bca67abc2c52f258c695a517d211e86aab95d1bd3adbb69c3fe11e7e9dfdb156fad3d14a05f4e31191fa253893c607a76eda74ddaf54b8a30b0dc4745e8b5b99e822e1c593252bed47c387c232d8f7d88e9767584cabbd6bc265fd6381c9f6547cfd7305a2a371775a32c40df6356c63cfe46accbde2daf2aecc0a03f9c4a16ea895096cd7b30aaa2ac8e24406ddfb758a7db7c49c21fdbae054fda8269018c8cbd7d50c215b7abc10298e7d51509b721708edfcc9af27bcf1f788fcc5f1b52f09c56dd606f0207ac699caa577905a8a457f96a22b3152b27cb2167fec2ca36f84ecd51ca27de671a3bbfc0aed77162771828464a199c252d16ec85521bfc95709b1befcfdba70035f907244b9c945bcd6ea44f8fcfbf28f9c812e1c5f8360a6708eadfb397fe607ca8cfcfe9ed315efcaa56aa190b3c98cc1a785633b376dce0a896b89a29dab2c6e94b7d0a4a37c5bbda4e5a0f7ed1726dab8dedc5dac3d90c375133b72a8ade13819525576024e5b29db3384b30b6bd069187f8f067d1f3ec7c7862a69d2ffde50dffb6e9508b6396c315149de11b60389feb1a8745c7eee7cf11881c6bb47b8ee636c41fbc733017c491d1e7f8bb97d1d891a63262f10", - "data" : "0x61cb407df7097f4d1829d111eb0926f0528b8452e6cf31a660affb3312ff289bfcbc6da9cdea6d1042b08af8e41225a3bb7d015e50b5d293cbf1b076a13f69c09544bd8857820780113c434fbdbaf298637fde5a7e732c71b043b46d6d73d0caf302761df34706d5e32167825ea37cc3167bd7635bb887a37355a18d8c957ae9a3061b2aa3aaf472ba54fdd6ef729c5d6522ce1d4ed40ac4edd2e4eac82deec3f774a58859461a08d0604da102a898d31b83a2a37f113675ab55413eb7c8906f3c090c383f322be7a19268fe27687d30df96d44b0a570809c0dba50c3b82dd53910c3bcf05c18256d59124c6f56c39dd9b7fca08ec41e1e3dfed3079cdd42869598b7f9dd1254c4b7b2231ffeda4eec8168da157e8586c3c15dcbddd3fbcc20a88be11829e7d30086ee73a1229f1bb5938e01efd193e2fac2301c688449c3f6d8372480f543638", - "gas" : "0x21df095c", - "gasPrice" : "0x2d", - "origin" : "228611f8ccc2a3dd9a67af6a43c8bea945d20f4d", - "value" : "0x6efa52132846ee54" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x6c80e7f0", - "code" : "0x70f5879c3a83ab5da815c1047edaa5bc22907aac3e4e9fbaeb5638b8c998b8b940675abbc89ed4c047b214f512a1601a3768d07c8d5dbfcc381cbb54745f1c0c9255866cd322f5b9af41893abe83276235517501ecf5a723d3f1fd9bdef48b5232fbfed97171029561651baa3b4bc71773148918649129910c4ca9615a93890fc144f61ab66461cee1e12576d274d5dce2cb206c05952913d7afc397cdc3180f21cf277b858c7c2bd7b821d468d08b6f03abb80fe34e6410c8781271243d3c956db1a20cd1e0e64192dca8213c150d7083ccf229cd085864fe558c6241034cf4637ac3d8f2b81ab24a90a7e93e3318b4e39f02c601b326fed43e41e02c63059b80e870c78e76f59d901014065ae7f8be5a85d210765e9a831b82164ce142b66a2628d6be7a9a8f449983b9c86c9ae88505bfd5130bcdf4c4622b69419017ce7c34a7f563c98e74cb7b55cc61aea40c4494d3e0d65f01962794ec7881784a68fb3f96217484b8aa3c1f605201742d41bc492397e3ae55706943644354df3d1f433028c1074249673a70a2a82c0a9ef15da6731f1d68239f07d20c6a1bc3ea2778f3782a6416957d38dead3c6f2dfb6cd6ed320e51eba8bca67abc2c52f258c695a517d211e86aab95d1bd3adbb69c3fe11e7e9dfdb156fad3d14a05f4e31191fa253893c607a76eda74ddaf54b8a30b0dc4745e8b5b99e822e1c593252bed47c387c232d8f7d88e9767584cabbd6bc265fd6381c9f6547cfd7305a2a371775a32c40df6356c63cfe46accbde2daf2aecc0a03f9c4a16ea895096cd7b30aaa2ac8e24406ddfb758a7db7c49c21fdbae054fda8269018c8cbd7d50c215b7abc10298e7d51509b721708edfcc9af27bcf1f788fcc5f1b52f09c56dd606f0207ac699caa577905a8a457f96a22b3152b27cb2167fec2ca36f84ecd51ca27de671a3bbfc0aed77162771828464a199c252d16ec85521bfc95709b1befcfdba70035f907244b9c945bcd6ea44f8fcfbf28f9c812e1c5f8360a6708eadfb397fe607ca8cfcfe9ed315efcaa56aa190b3c98cc1a785633b376dce0a896b89a29dab2c6e94b7d0a4a37c5bbda4e5a0f7ed1726dab8dedc5dac3d90c375133b72a8ade13819525576024e5b29db3384b30b6bd069187f8f067d1f3ec7c7862a69d2ffde50dffb6e9508b6396c315149de11b60389feb1a8745c7eee7cf11881c6bb47b8ee636c41fbc733017c491d1e7f8bb97d1d891a63262f10", - "nonce" : "0x0486acc99e8d8e01", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060035CPPJIT.json b/tests/files/VMTests/RandomTests/vm201506060035CPPJIT.json deleted file mode 100644 index bc5ff7f33..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060035CPPJIT.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "randomVMTest" : { - "env" : { - "currentCoinbase" : "440f21a735f6044e793c82153d442678cab2ce36", - "currentDifficulty" : "0x6b15fa4d", - "currentGasLimit" : "0x971ebab58cc2b443", - "currentNumber" : "0x8d5efc2e7a3c85dc", - "currentTimestamp" : "0xbec4e74640b38be4", - "previousHash" : "dc8601afcb064c13fdc1cf5a0391fc65420bd4857953c127a7a7a2cbb20a38e3" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "66bf911d91dc1ba1700804c109efc372301c98e9", - "code" : "0x6cc926325886186ecf81a653646473ac42f5c61aab60c7b73fbc4d1cb06ec4e31a1f0769fd0398a9e94e1b7b7384f079b46106f98a7b29e4dbca74d94232d4cf0e1c61617d5c732114097cdd54973f3c7d80e0761a27e6a13cbca9a468fb10e6d5ece49842d559b4556d50d24cf381b9bd6ed8cd1cba65657fe44f3bc0fdd47aa58ff410a4a76d17af486081e044ff35132cea133f30224daca0676afebf42d0e7195475e12166f3a944b314cc7957a0312d0666da67ce792b997ef05794f77ec7af6072c624c96d15de4a2a7876cc2e0a270aa5569b26c988ff7969a0a2a45856e1621a6d094178afa92792ae4530a8d0b650f2a875901554352a900184ddf606e799fea503286b9b17f41d7a3aecd3caa13b3356733593d23e4f9918a256cfc3fdbb71953b14036c9d044b487c3ca7d06b990a51497e3102b33087c80807a212ede2caa2f18bcf34a8f3d7113d7cb9872d8bc39744663a9cf57a32d2866225697e6dba301ae30546396651ca9abe615670266bc69fda17e692341a2b4adf9b1950908b", - "data" : "0x", - "gas" : "0x47d831c8", - "gasPrice" : "0x3b", - "origin" : "472101557e768143135d163cedf9c64855a0b395", - "value" : "0x2a1965380b144683" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x2e35b7f79ae995f8", - "code" : "0x6cc926325886186ecf81a653646473ac42f5c61aab60c7b73fbc4d1cb06ec4e31a1f0769fd0398a9e94e1b7b7384f079b46106f98a7b29e4dbca74d94232d4cf0e1c61617d5c732114097cdd54973f3c7d80e0761a27e6a13cbca9a468fb10e6d5ece49842d559b4556d50d24cf381b9bd6ed8cd1cba65657fe44f3bc0fdd47aa58ff410a4a76d17af486081e044ff35132cea133f30224daca0676afebf42d0e7195475e12166f3a944b314cc7957a0312d0666da67ce792b997ef05794f77ec7af6072c624c96d15de4a2a7876cc2e0a270aa5569b26c988ff7969a0a2a45856e1621a6d094178afa92792ae4530a8d0b650f2a875901554352a900184ddf606e799fea503286b9b17f41d7a3aecd3caa13b3356733593d23e4f9918a256cfc3fdbb71953b14036c9d044b487c3ca7d06b990a51497e3102b33087c80807a212ede2caa2f18bcf34a8f3d7113d7cb9872d8bc39744663a9cf57a32d2866225697e6dba301ae30546396651ca9abe615670266bc69fda17e692341a2b4adf9b1950908b", - "nonce" : "0x7b923a23", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060035PYTHON.json b/tests/files/VMTests/RandomTests/vm201506060035PYTHON.json deleted file mode 100644 index 5341b598d..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060035PYTHON.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "randomVMTest" : { - "callcreates" : [ - ], - "env" : { - "currentCoinbase" : "fa38b8ec5929d2c24aa648bccdd03a3867871620", - "currentDifficulty" : "0x3e2bdf94ca6c6349", - "currentGasLimit" : "0x0920c79d", - "currentNumber" : "0x157c9ea5", - "currentTimestamp" : "0x418566bae8925e78", - "previousHash" : "6a31eea78097b7b5ae2c76f4d678fdbf592715b352dcaa1ffb94686e303fa390" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "5968bf1b59120cb48b85cdcf1850a1765db4fcab", - "code" : "0x6d3c2e6b765b96c458393353fb22066c1dcddc92d4bfc44054134f93e1136b3dc88daaad669ed199b2d09a621f348b036be8d7782c74499d19ee65ba727218a8631b94849a2443bfcc27edf0ba784bf1780b7c76bacdbe1039bf537aea239e96b13270c335aefcb9ecc8639a62c1b67a6005077b46dac228cf1abb7c17a4b7fdc928fa3fed0dfcc672147181a91e70736a58451c96c8c181d92f768f7f74059e1d978c0f89401984d551ccc5354bf774c754e21a0c9a98c2ba4bd911a87cec3ec02a1c1b5ecaf1041792f86b4588b28752ba9949b5d1d40dab6f0d68a43f28c771ce0be37d7b8a138e4401a5579c17c6aac80507992bf774723f0db4eea2604a9df864217808f50e71aec0f1aee005d541408a6c58dc37c0b90fdd72eac1544372e1633b1ef44a63f452584d952b417d620d7e45d2b7cdbfb020ed0ee3665e368d0a747495bacd037d621e1033e37fd16479ad5a78e3e85b34b89ccff6ef949644c5b5847704fe4a87f2f3012440937cf91ac94b41a73e3181e8e25f580d5effa83439ae5679b8f0c39ea0a25d62ffc50f6d13e867bf91210417096eb058e19565707e56c1e0bc7f85a55d6b9c738f60943d67e8a9340ead3746a0d61f5cf1be9dcc4d01f2a312b17244bce171ef5d7ee012f3208af95e7c90e375649f659a2e29d7505a7a8376277aeebde83e8269425eb7bc751185f9d0aa619d3c241bb26355794418796a577a5c240a51ad751a8887140fe42a240eb9f6ba243468451ff132ab8eb8634269ef8a9923544ecdf3a8e172e2c762d9624574fee7d9d38ab1cf0d2b94a62e83707aaa40c8793b478a50e9e0581ba8692c757ebcf25a24d6f6d7b8b1f32d4d3b56e57673a3e3980a76c185e1017083a3ee466a6345f592a24fccdfe3d2816e9b0665455305f9a5c72d8f20e743e96eb1532828fc3b1e72e042f45d187a57728d81ad8fb98412ff6ffa1cce121878a8b5e6b27218bbbf90916bcb812f987df9b491b11cabcad16547417aa7fb226e4939c4b3070f37b10eb7f7accaee386db2a35ac83c0e2eea5e905097cd8f783382141a1b2e9716f0757e204458107b48bd20fa1d3f284f597e53542e9a66aec0dd8082ebc5249bfa8ec1b2a593a8d3f22f28ab4549da8a4c72cd79ec1828073916448e2d9e4ab2736f3a6baa7b5ac3804e4d6aadab16ed19a0582f7a175c1d9c505a5f145e81dc0eb4692a3534e18857bc925d88654096fca6695c7506d39ed253634790b4b7f2335cb2f81e4020ffacdd2a9f", - "data" : "0x78e3c689f5b8056f9d0dd109f4050bfb52fa5c532787dba38e1b6bf6b03d47848e896ab6a4d1356860a2a3fa34af8317d97b8cbfcb12357bd3ed72d1537a3dfa8e7e3e4183b34a4eccf8624f5a2b77205ef8085f13272ef155caa09f9aace0d91bafdb79e5b01aa36c2e6172ed576ffd47da0ae9ab717011a2495ceb915faed65af38e79447a6679557d1575ecde5c0c9874315ced476c94db0f64d904e17843afd82cf705f088a577c472a4cc29a3172a72594b7da2e712bbbb98e159897e34360576d46bfb9f2ddd458205ecd505e629f04a090bff0c36d04d35768ac97b60ae05f12b8bf2a1f84b883874bd2aace89dd0bf6834fcc23b68d7d84d207663aaafc9a3be46a23d5cdc6ce304f93486cf4453b0a24d6ba66e62d32e2ce9169193c0957e42b3e6ea2946274b01db1681a72bcdc95224a2611722fc5fe05c7f2c6619fe7285fbd79eeec55d2d98f76a2a24429d69ea6fc978be5763be77fa27f4cebab74a14afea06a916581003c65ef5e96ef647237f82761d6ad637e0e4e549087794363b04656c4746d1d91fe389ad1f2764468395c91baa827c6a9c8da1699a6365fc800db01d917e7682af4e41e95231d3db144c19e689684dbf82d0593320e7157c59216ab30a6c300329ce91b2601f6925a3404d407b529f2b685f29e70c7a745e91c4213e0e5671f0f8d9449d013febb2113887e9f55b78b79f376ab319f72d8a6c8bc85b231e64adf2a1c15065e891b1c572c976b20d4b533aa3de3a7c3e1adb18e36fd902ded6e2fa434560d470850d38beaac27fd64dc28e08c82d93301d658eb3c93790daf1", - "gas" : "0x08a436a67693cb35", - "gasPrice" : "0x1d", - "origin" : "488e0a1a60568f14ea731847716d7364750ad6c7", - "value" : "0x37ccf98d9e881ba3" - }, - "gas" : "0x08a436a67693cb35", - "logs" : [ - ], - "out" : "0x", - "post" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x436c0a01", - "code" : "0x6d3c2e6b765b96c458393353fb22066c1dcddc92d4bfc44054134f93e1136b3dc88daaad669ed199b2d09a621f348b036be8d7782c74499d19ee65ba727218a8631b94849a2443bfcc27edf0ba784bf1780b7c76bacdbe1039bf537aea239e96b13270c335aefcb9ecc8639a62c1b67a6005077b46dac228cf1abb7c17a4b7fdc928fa3fed0dfcc672147181a91e70736a58451c96c8c181d92f768f7f74059e1d978c0f89401984d551ccc5354bf774c754e21a0c9a98c2ba4bd911a87cec3ec02a1c1b5ecaf1041792f86b4588b28752ba9949b5d1d40dab6f0d68a43f28c771ce0be37d7b8a138e4401a5579c17c6aac80507992bf774723f0db4eea2604a9df864217808f50e71aec0f1aee005d541408a6c58dc37c0b90fdd72eac1544372e1633b1ef44a63f452584d952b417d620d7e45d2b7cdbfb020ed0ee3665e368d0a747495bacd037d621e1033e37fd16479ad5a78e3e85b34b89ccff6ef949644c5b5847704fe4a87f2f3012440937cf91ac94b41a73e3181e8e25f580d5effa83439ae5679b8f0c39ea0a25d62ffc50f6d13e867bf91210417096eb058e19565707e56c1e0bc7f85a55d6b9c738f60943d67e8a9340ead3746a0d61f5cf1be9dcc4d01f2a312b17244bce171ef5d7ee012f3208af95e7c90e375649f659a2e29d7505a7a8376277aeebde83e8269425eb7bc751185f9d0aa619d3c241bb26355794418796a577a5c240a51ad751a8887140fe42a240eb9f6ba243468451ff132ab8eb8634269ef8a9923544ecdf3a8e172e2c762d9624574fee7d9d38ab1cf0d2b94a62e83707aaa40c8793b478a50e9e0581ba8692c757ebcf25a24d6f6d7b8b1f32d4d3b56e57673a3e3980a76c185e1017083a3ee466a6345f592a24fccdfe3d2816e9b0665455305f9a5c72d8f20e743e96eb1532828fc3b1e72e042f45d187a57728d81ad8fb98412ff6ffa1cce121878a8b5e6b27218bbbf90916bcb812f987df9b491b11cabcad16547417aa7fb226e4939c4b3070f37b10eb7f7accaee386db2a35ac83c0e2eea5e905097cd8f783382141a1b2e9716f0757e204458107b48bd20fa1d3f284f597e53542e9a66aec0dd8082ebc5249bfa8ec1b2a593a8d3f22f28ab4549da8a4c72cd79ec1828073916448e2d9e4ab2736f3a6baa7b5ac3804e4d6aadab16ed19a0582f7a175c1d9c505a5f145e81dc0eb4692a3534e18857bc925d88654096fca6695c7506d39ed253634790b4b7f2335cb2f81e4020ffacdd2a9f", - "nonce" : "0x3a2068ac", - "storage" : { - "0x8376277aeebde83e8269425eb7bc751185f9d0aa619d3c241bb263" : "0x9a2e29d7505a" - } - } - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x436c0a01", - "code" : "0x6d3c2e6b765b96c458393353fb22066c1dcddc92d4bfc44054134f93e1136b3dc88daaad669ed199b2d09a621f348b036be8d7782c74499d19ee65ba727218a8631b94849a2443bfcc27edf0ba784bf1780b7c76bacdbe1039bf537aea239e96b13270c335aefcb9ecc8639a62c1b67a6005077b46dac228cf1abb7c17a4b7fdc928fa3fed0dfcc672147181a91e70736a58451c96c8c181d92f768f7f74059e1d978c0f89401984d551ccc5354bf774c754e21a0c9a98c2ba4bd911a87cec3ec02a1c1b5ecaf1041792f86b4588b28752ba9949b5d1d40dab6f0d68a43f28c771ce0be37d7b8a138e4401a5579c17c6aac80507992bf774723f0db4eea2604a9df864217808f50e71aec0f1aee005d541408a6c58dc37c0b90fdd72eac1544372e1633b1ef44a63f452584d952b417d620d7e45d2b7cdbfb020ed0ee3665e368d0a747495bacd037d621e1033e37fd16479ad5a78e3e85b34b89ccff6ef949644c5b5847704fe4a87f2f3012440937cf91ac94b41a73e3181e8e25f580d5effa83439ae5679b8f0c39ea0a25d62ffc50f6d13e867bf91210417096eb058e19565707e56c1e0bc7f85a55d6b9c738f60943d67e8a9340ead3746a0d61f5cf1be9dcc4d01f2a312b17244bce171ef5d7ee012f3208af95e7c90e375649f659a2e29d7505a7a8376277aeebde83e8269425eb7bc751185f9d0aa619d3c241bb26355794418796a577a5c240a51ad751a8887140fe42a240eb9f6ba243468451ff132ab8eb8634269ef8a9923544ecdf3a8e172e2c762d9624574fee7d9d38ab1cf0d2b94a62e83707aaa40c8793b478a50e9e0581ba8692c757ebcf25a24d6f6d7b8b1f32d4d3b56e57673a3e3980a76c185e1017083a3ee466a6345f592a24fccdfe3d2816e9b0665455305f9a5c72d8f20e743e96eb1532828fc3b1e72e042f45d187a57728d81ad8fb98412ff6ffa1cce121878a8b5e6b27218bbbf90916bcb812f987df9b491b11cabcad16547417aa7fb226e4939c4b3070f37b10eb7f7accaee386db2a35ac83c0e2eea5e905097cd8f783382141a1b2e9716f0757e204458107b48bd20fa1d3f284f597e53542e9a66aec0dd8082ebc5249bfa8ec1b2a593a8d3f22f28ab4549da8a4c72cd79ec1828073916448e2d9e4ab2736f3a6baa7b5ac3804e4d6aadab16ed19a0582f7a175c1d9c505a5f145e81dc0eb4692a3534e18857bc925d88654096fca6695c7506d39ed253634790b4b7f2335cb2f81e4020ffacdd2a9f", - "nonce" : "0x3a2068ac", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060134CPPJIT.json b/tests/files/VMTests/RandomTests/vm201506060134CPPJIT.json deleted file mode 100644 index c278a4e7f..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060134CPPJIT.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "randomVMTest" : { - "env" : { - "currentCoinbase" : "667a4c99d680c975191c982962621915870b4c02", - "currentDifficulty" : "0x268d8424", - "currentGasLimit" : "0xbb87562fd8f4c074", - "currentNumber" : "0x761251e4", - "currentTimestamp" : "0x0a7acf9a", - "previousHash" : "cd602c9a0d7e87aad15e07e107cfc1fcd8a64fc9400afee4a66827b94acf3ff3" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "70597f4d60a5a4d7db9e4f0632ee6603b077af81", - "code" : "0x7f16811f3a270fb6c92e9594ce76e78aeb88d06c12e7d03d8cfa870180b55f14bf69e47694e4d3ea0487d15b706f6d96508fa9a70a884eeea20d6e0c9b1a78bc031365bd1b96948f0bba6615e7c1bf760aad09745d4881d479704625f3a09138f626c01e5c4262d968d52d9825d634a6273dbc6ba015e8c0826216e22332cfe07da284284016ac7ee9b4e70be2e7a705c7e24b80c2d338cb8b3bffbefd9dc06430ddc3cc756c535ff0d3fc1101911f2d32853660526aa04516f4370b31ded4327279d6142eb272358d8b3ac3e573d4dfc8b91514f06eda141fe0feb57ccb0db6ed625f32e8a43a1bf6153709512d7b3e8b6fce2cac3bd94aa22861b49e7b9216ec84cffc1e0a014ba807bd272fab2f769963a3cd770271bf3c766efc90bb95fe348d436bb54762102c127d406c88cc5fcdf915416f7dbe81e2ee4ff71234f5081a5ab02577ed2c15099f737bb4b0d0062420576e57641f39b721b1f399e6f26c532b253d4629dea6a5e818a2327523889f051ffea10609c34c8fe009eac58f2ee9506beb68f7b590972f8fe86fe6789b25da2dcaf90dff52c1a8476b1381a7c4cad3d0248a18ca6263023fc4b77a8487fc0cbec291370bb1c97cd21b1a9c4d359ba58f076b11212c0ef16096753229ab680782f6d4386fec6e5b26d9d572bfe484fb5a0379349c3587b620cba4134809876e79d28aee7c4792b4d6f3d4da22649637ee8821077f0919ffa295605f122ec0a2ae678074aa93277deb3de2c1c0957d2e09b78b151a6040206aa7f05c1a71e552b3ebbcab67e1456b0fb8c88078a0", - "data" : "0x7b5e7e1696a18f82ec382e6557b86b36e8d8e55e5350ffb0dd5f701f336066a07e960114651da9da852239d33f188e2365b6cc07c065f6a1a89765f144dcb36d807ecbe0ff784c0cb26b58d79e0721ffbc08141b6e8c63b1ff16e062f731d946d266b38e91c46f723e77caff402d1473e1a945e722f37c9b411ad766957cc4b64e1873a9782dc73bd842c97e0db60512a831f37b4cba6a7d7faeb2748de4ffb52de98304417594a89ec86d858ba64942bbc39c1687fa77c74bc94f31886faf24a3d4b5d875b09a056b0125b2acb9777f2bce761cf888b863f0390654ba12b29ad9aa6e813ae2e1c07673c83d0a1a59bc63aad7882d650d01f82e64e976c765b2f68a0791199fae643bf972d2e8f64492fed053957066587cbdd331194f5268eec38620a3204c73908f39d115b19f0e65c95107ebdf340c0b17182b77892ccaffd93aa0db2339ed1b0def1e8fe1e1ccad08ad88f46df69a5204ed5f7d9bc14f5679d2d8762e70c43162e64dce385144912ed2b0c54a052a5b4c1e808e6ae30e9bb98b497edae2894a78693a94c0a71a036793f448d84f747f574cb529a33b5f46633b6caa262c13f078894fc5ca3909f56d43dac40a16761625fc5ad8aca6dd6d5ac0ccb60cc8419aae7d2b1141529373ede65a95351da64ca5c11bbb229c7b5facc791a9635e93f27678aa513a4936c64eae062af8575094226cfde23a1cad96cf9e393777cc7f958dc2fa7a7947b2bf8776c3261ef4195dd1cb3a40ad726615f434e010e77ff1f35d99058807d575af2b65bbcc7681072874e649cf4c16d71dae4a78ffde1512c8439471042001775faf37d9d515574c1637429b8eae30905566a530df1ee1fb62e6dfc17491db6bf33a510aef299805973eaea201c5362f9466621c0a0a79c5ed449fcc7a448d5db2da446911f4b2e11bb01c25ba2cf32a2c79b2054e2adf927ba679cd28e1a14f35ba8a5df97efc5b39c0e73a674d1248373869f39c6499e4a4f8147ac7a44ed49ccff7afc2362fdf4252cbefff96fce329e3eb6e2b85467249b6e52de9d60f3bcf25d99a539f66a373e0767a1d29531b6d27cba56928f19b7df858337de8b0050f132c470c2f796d9a74680adb61c6ff474ca39e4bfc6ad68739cdf0429bacc94f599f6c30c4266438a52ea2e84ea2c13e6121227f6ed215af17025e11598b5c1bc863dcc66b0424d012ad9f5a0270f18d1a657f6c683b5c3268da78c228cb71739560a8a596ad4d75217969951ff80590de6b77f0ee4236b46b1cd2d456cd75714e471f168383b2d4dc5f8a6c19af977583534efbb4610d6b65b2ba396760fc64cb654548047f521d3285d33cadd2ac9079f526d1c618114e0e33237d43e34a0d963b6084944a6987cc01e2075a1261d3337263b3f99cc1f11892f5e4045bedfbfc387d9cf48c77883714915e73b6349be0e2b3474b7fd1c9fb8b016f0758906c7d4bf326662769090f336791076d0771a1a8e10c17f941d4b7aa5c1f6d17dbff1f91e6a222dbce8876e4ed837e72b1139e5285277a23607f73a50dcd52a6aa225889729690eb80ed22f54dc16932930f855f81aa06b83d6e7b9add7b543f6018d34f221585d4646a6e45ba2ef59c71679c1bf36831046738ac0234fc1277f803ee75addc98f6c2caee0997eea715354e877e9389c9e96296c872794b53272a2f93fec7e6634e9fee048bfa6a0ddaf9e4b93f2f1e516f2d2baf327644605d1ec3ac82affeaaf4601f78e5a0fa7db95981f4ed7a9f41e41c9fd1b849f5b6ccbcf42b8d622988647a44f6f00db531c97d425a3715b3435112c26653ebec565572bbdeac9b", - "gas" : "0x6ad1cb41", - "gasPrice" : "0x1c", - "origin" : "89cbee220af96665792cb88e9c5d20e5d402f7bf", - "value" : "0x40be582c" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x76eb64c1377dd218", - "code" : "0x7f16811f3a270fb6c92e9594ce76e78aeb88d06c12e7d03d8cfa870180b55f14bf69e47694e4d3ea0487d15b706f6d96508fa9a70a884eeea20d6e0c9b1a78bc031365bd1b96948f0bba6615e7c1bf760aad09745d4881d479704625f3a09138f626c01e5c4262d968d52d9825d634a6273dbc6ba015e8c0826216e22332cfe07da284284016ac7ee9b4e70be2e7a705c7e24b80c2d338cb8b3bffbefd9dc06430ddc3cc756c535ff0d3fc1101911f2d32853660526aa04516f4370b31ded4327279d6142eb272358d8b3ac3e573d4dfc8b91514f06eda141fe0feb57ccb0db6ed625f32e8a43a1bf6153709512d7b3e8b6fce2cac3bd94aa22861b49e7b9216ec84cffc1e0a014ba807bd272fab2f769963a3cd770271bf3c766efc90bb95fe348d436bb54762102c127d406c88cc5fcdf915416f7dbe81e2ee4ff71234f5081a5ab02577ed2c15099f737bb4b0d0062420576e57641f39b721b1f399e6f26c532b253d4629dea6a5e818a2327523889f051ffea10609c34c8fe009eac58f2ee9506beb68f7b590972f8fe86fe6789b25da2dcaf90dff52c1a8476b1381a7c4cad3d0248a18ca6263023fc4b77a8487fc0cbec291370bb1c97cd21b1a9c4d359ba58f076b11212c0ef16096753229ab680782f6d4386fec6e5b26d9d572bfe484fb5a0379349c3587b620cba4134809876e79d28aee7c4792b4d6f3d4da22649637ee8821077f0919ffa295605f122ec0a2ae678074aa93277deb3de2c1c0957d2e09b78b151a6040206aa7f05c1a71e552b3ebbcab67e1456b0fb8c88078a0", - "nonce" : "0x366add988a39a9ad", - "storage" : { - } - } - } - } -} diff --git a/tests/files/VMTests/RandomTests/vm201506060134PYTHON.json b/tests/files/VMTests/RandomTests/vm201506060134PYTHON.json deleted file mode 100644 index 1f1313fe6..000000000 --- a/tests/files/VMTests/RandomTests/vm201506060134PYTHON.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "randomVMTest" : { - "callcreates" : [ - ], - "env" : { - "currentCoinbase" : "a1c240ebc8ee9ebdbd972e8edbb7461c380e8794", - "currentDifficulty" : "0x88a62ea1cc8be328", - "currentGasLimit" : "0xd43ea089079a926a", - "currentNumber" : "0x451067bb", - "currentTimestamp" : "0x18aae452", - "previousHash" : "14ba1a13166b56cf91cb29cbd3d1dbcf32ebf6066d237e34abb405378ec6a277" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "3616b971536b216fd6710a54ef30e1e3d3bd6c13", - "code" : "0x6c790eb25b10d55aefcef887e5dd7b0c8d2d3cda55a99a988e563d5ba5cbc54dac1282f775f3b0c43c37306d2212605536f2dca4aa862e6712d774d618146137e0c4ec6f880485707f913173b41181da66866588b4d728766d615e887fa448fada51b5e68b9c0b701a3e97a63d1fe25939a107b74fbeb794a57aa16acee29a63f5235e2c83172b629fd658b122a972568d88735395876ca0349e6f11dfc373bdd6c781556bec6e641bb4e8e5b1ff28401870c2f9de528b6fe37c4c27416974a9032d7e71762ba23122af89eab4961e59bb35f9fee35979c68fff82ef6cb5e66e56119aa924681f274edcfee02c4ce8c1ec7eeb813cc6d453db74a3fe1571627368af27ba22c61eb98cde4272b4ab4cd55a7bd0b5383b1445620b23d3666532f25b93be98efdccf0bdf37f0fecc5e61556370d3ebf3644a4717e604bdee16e1304ffce17ed6b567c70275df1e847cef48b65aa8221bdbb9d0b84a2ece25a72d3632c5ce7e8b03bc43d8093c4d5819acec0178d548094219e9e31e87ed8e02f42099c1c1699703393c0a4b55a33eac9a6f34185783af66a5972c6c1bb607a57af38063d18908367ca79ccdcd11bd5bd13c2703a19e67e36c9f2abc8770a60ecfb2e7b8c24e553070660698d1ec44a2a27fd82a02de187e46cb6a5fbbc7bcf24d593ed016fa07", - "data" : "0x69040ef607bae332ebef806fa4be76ba43516c5041e54c23976d382776bcdbccd68e29053a023742335c3487ab65fdd26569a1ee7662ed75d61ded9b7abf80fdd34fd054045e95778447aac663aa3593807c599c7bcc3326b1142a372117c4f31bd6c968b90d5d2436bb554835ca5d7b39e22af6bc5cc47aa376338fdc59cba9df637b8fc5ca1c3780a399dc67e29f17538255f3806adc03cd145c224fec14e18863795fa849897e72517a3973f445929a30ea8c82cf043c4cf0b9cb0b4d41f33a44533ff059376916fcff55b5388b440e667a41f4ad614a32778c9c2c12a2801acbe8b62db37556aa3635d8beae62978b417805a470402d1d4537372922e3c0400ab451f231fc8a1682ddb77ec720fa371410e195d02ba072adbd977ca4dea25fdd64e228db91b15771d13a7554da5aa1f6e44de211fea4e1d994f52d1ec5e36221106613c74205fb5f0d79afa459b98cc80740406eebae740b01b44245b1737dfb8ab7bef66a08e35f4e313bc59570e88965ca8f0dfdaac97b4c9929d1b380b8c87dc1965333f51de17367ed0c2e5cbfbcdf2753087c6449c274cebe7e840a673238828171ece98d2e6b14ea58f386467110e6616d8d7142a003290cb7556362081dc7d3a5a02303259d65f7452a91d19666ec5e55707b1fe074667ae446aabf10cfa1d2c42e04e66816e0d1f853a360d2667d5e5c1c1cc7de777af52536f722f9620d9740bc2952846d9021978d5d48e0b86808870ba75603a4777f61985976b20f088ec8fe8184b377aa409951df945f101ece22502a6d43d8e9bb0194945d476078b2b9797232b1812e8b26888d930253593383d57e6c451972db2437ae4e062e3ca19355864176c786dc69df9a663d4584e4baf2357a9d59857729567f57d3573c3d4dfc1bb8cede257c9dd2ca6e1bed0f6da7fb5b3877d067a2f43c90b6ab397bb6789910db655c5abb4ee964c606f126da8d11a46dea65f043f2c47a74aacce8328d25f220874fce72778249b9a4652eeee577728a200c51d6a12219c3abe36adc2d66e6b9f511394dcca46ca30efa46a1c370b92dfa5352246c33f512d7e501128dd572a4b3be68772f912f0dc78feea97f0a2a36c79ebf866931d1d864771c044a2531b493359105f797e70e7acb1a4da660c77033cd9d7045da5c935dcb833ca70735d1b0605d62c9e3af60f38e", - "gas" : "0x0ced02de", - "gasPrice" : "0x1d", - "origin" : "638eec7b45d4b2ea1682dfe5f6e64dfeeaa2d5ed", - "value" : "0x42aad51cf7f24ad7" - }, - "gas" : "0x0ced02de", - "logs" : [ - ], - "out" : "0x", - "post" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0xcbc9411f7d2c1c91", - "code" : "0x6c790eb25b10d55aefcef887e5dd7b0c8d2d3cda55a99a988e563d5ba5cbc54dac1282f775f3b0c43c37306d2212605536f2dca4aa862e6712d774d618146137e0c4ec6f880485707f913173b41181da66866588b4d728766d615e887fa448fada51b5e68b9c0b701a3e97a63d1fe25939a107b74fbeb794a57aa16acee29a63f5235e2c83172b629fd658b122a972568d88735395876ca0349e6f11dfc373bdd6c781556bec6e641bb4e8e5b1ff28401870c2f9de528b6fe37c4c27416974a9032d7e71762ba23122af89eab4961e59bb35f9fee35979c68fff82ef6cb5e66e56119aa924681f274edcfee02c4ce8c1ec7eeb813cc6d453db74a3fe1571627368af27ba22c61eb98cde4272b4ab4cd55a7bd0b5383b1445620b23d3666532f25b93be98efdccf0bdf37f0fecc5e61556370d3ebf3644a4717e604bdee16e1304ffce17ed6b567c70275df1e847cef48b65aa8221bdbb9d0b84a2ece25a72d3632c5ce7e8b03bc43d8093c4d5819acec0178d548094219e9e31e87ed8e02f42099c1c1699703393c0a4b55a33eac9a6f34185783af66a5972c6c1bb607a57af38063d18908367ca79ccdcd11bd5bd13c2703a19e67e36c9f2abc8770a60ecfb2e7b8c24e553070660698d1ec44a2a27fd82a02de187e46cb6a5fbbc7bcf24d593ed016fa07", - "nonce" : "0x045d0aa4", - "storage" : { - "0xa79ccdcd11bd5bd13c2703a19e67e36c9f2abc8770a60ecfb2e7b8c24e" : "0xd1890836" - } - } - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0xcbc9411f7d2c1c91", - "code" : "0x6c790eb25b10d55aefcef887e5dd7b0c8d2d3cda55a99a988e563d5ba5cbc54dac1282f775f3b0c43c37306d2212605536f2dca4aa862e6712d774d618146137e0c4ec6f880485707f913173b41181da66866588b4d728766d615e887fa448fada51b5e68b9c0b701a3e97a63d1fe25939a107b74fbeb794a57aa16acee29a63f5235e2c83172b629fd658b122a972568d88735395876ca0349e6f11dfc373bdd6c781556bec6e641bb4e8e5b1ff28401870c2f9de528b6fe37c4c27416974a9032d7e71762ba23122af89eab4961e59bb35f9fee35979c68fff82ef6cb5e66e56119aa924681f274edcfee02c4ce8c1ec7eeb813cc6d453db74a3fe1571627368af27ba22c61eb98cde4272b4ab4cd55a7bd0b5383b1445620b23d3666532f25b93be98efdccf0bdf37f0fecc5e61556370d3ebf3644a4717e604bdee16e1304ffce17ed6b567c70275df1e847cef48b65aa8221bdbb9d0b84a2ece25a72d3632c5ce7e8b03bc43d8093c4d5819acec0178d548094219e9e31e87ed8e02f42099c1c1699703393c0a4b55a33eac9a6f34185783af66a5972c6c1bb607a57af38063d18908367ca79ccdcd11bd5bd13c2703a19e67e36c9f2abc8770a60ecfb2e7b8c24e553070660698d1ec44a2a27fd82a02de187e46cb6a5fbbc7bcf24d593ed016fa07", - "nonce" : "0x045d0aa4", - "storage" : { - } - } - } - } -} From a9d6846f9218ef131ec4b3ca8d31284f64f1b8a5 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Tue, 16 Jun 2015 12:06:06 +0200 Subject: [PATCH 012/110] Update ethash Godep --- Godeps/Godeps.json | 4 +- .../github.com/ethereum/ethash/CMakeLists.txt | 7 - .../src/github.com/ethereum/ethash/ethash.go | 7 + .../ethash/src/libethash-cl/CMakeLists.txt | 47 - .../ethash/src/libethash-cl/bin2h.cmake | 86 - .../ethereum/ethash/src/libethash-cl/cl.hpp | 12906 ---------------- .../src/libethash-cl/ethash_cl_miner.cpp | 384 - .../ethash/src/libethash-cl/ethash_cl_miner.h | 57 - .../libethash-cl/ethash_cl_miner_kernel.cl | 460 - .../ethereum/ethash/src/libethash/endian.h | 3 + .../ethereum/ethash/src/libethash/internal.c | 13 +- .../ethereum/ethash/src/libethash/io.c | 21 +- .../ethereum/ethash/src/libethash/io.h | 17 + .../ethereum/ethash/src/libethash/io_posix.c | 9 + .../ethereum/ethash/src/libethash/io_win32.c | 4 +- .../ethereum/ethash/test/c/test.cpp | 9 +- 16 files changed, 76 insertions(+), 13958 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/bin2h.cmake delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/cl.hpp delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 4cbc73def..24905d0bb 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -21,8 +21,8 @@ }, { "ImportPath": "github.com/ethereum/ethash", - "Comment": "v23.1-206-gf0e6321", - "Rev": "f0e63218b721dc2f696920a92d5de1f6364e9bf7" + "Comment": "v23.1-222-g5cfdcba", + "Rev": "5cfdcba92e634db228d1ddb140e3b7a3c4b38177" }, { "ImportPath": "github.com/howeyc/fsnotify", diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt b/Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt index ea8c1849a..807c43e96 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt @@ -9,13 +9,6 @@ if (WIN32 AND WANT_CRYPTOPP) endif() add_subdirectory(src/libethash) -# bin2h.cmake doesn't work -if (NOT OpenCL_FOUND) - find_package(OpenCL) -endif() -if (OpenCL_FOUND) - add_subdirectory(src/libethash-cl) -endif() add_subdirectory(src/benchmark EXCLUDE_FROM_ALL) add_subdirectory(test/c) diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go index ce450d461..ee68ab95f 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go @@ -8,6 +8,7 @@ int ethashGoCallback_cgo(unsigned); import "C" import ( + "bytes" "errors" "fmt" "io/ioutil" @@ -119,6 +120,12 @@ func (l *Light) Verify(block pow.Block) bool { if !ret.success { return false } + + // avoid mixdigest malleability as it's not included in a block's "hashNononce" + if !bytes.Equal(block.MixDigest().Bytes(), C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))) { + return false + } + // Make sure cache is live until after the C call. // This is important because a GC might happen and execute // the finalizer before the call completes. diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt deleted file mode 100644 index 3cfe1644d..000000000 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set(LIBRARY ethash-cl) -set(CMAKE_BUILD_TYPE Release) - -include(bin2h.cmake) -bin2h(SOURCE_FILE ethash_cl_miner_kernel.cl - VARIABLE_NAME ethash_cl_miner_kernel - HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/ethash_cl_miner_kernel.h) - -if (NOT MSVC) - # Initialize CXXFLAGS for c++11 - set(CMAKE_CXX_FLAGS "-Wall -std=c++11") - set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") - set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") - - # Compiler-specific C++11 activation. - if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - execute_process( - COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) - message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") - endif () - elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - else () - message(FATAL_ERROR "Your C++ compiler does not support C++11.") - endif () -endif() - -set(OpenCL_FOUND TRUE) -set(OpenCL_INCLUDE_DIRS /usr/include/CL) -set(OpenCL_LIBRARIES -lOpenCL) - -if (NOT OpenCL_FOUND) - find_package(OpenCL) -endif() - -if (OpenCL_FOUND) - set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -Werror -pedantic -fPIC ${CMAKE_CXX_FLAGS}") - include_directories(${OpenCL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) - include_directories(..) - add_library(${LIBRARY} ethash_cl_miner.cpp ethash_cl_miner.h cl.hpp) - TARGET_LINK_LIBRARIES(${LIBRARY} ${OpenCL_LIBRARIES} ethash) -endif() diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/bin2h.cmake b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/bin2h.cmake deleted file mode 100644 index 90ca9cc5b..000000000 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/bin2h.cmake +++ /dev/null @@ -1,86 +0,0 @@ -# https://gist.github.com/sivachandran/3a0de157dccef822a230 -include(CMakeParseArguments) - -# Function to wrap a given string into multiple lines at the given column position. -# Parameters: -# VARIABLE - The name of the CMake variable holding the string. -# AT_COLUMN - The column position at which string will be wrapped. -function(WRAP_STRING) - set(oneValueArgs VARIABLE AT_COLUMN) - cmake_parse_arguments(WRAP_STRING "${options}" "${oneValueArgs}" "" ${ARGN}) - - string(LENGTH ${${WRAP_STRING_VARIABLE}} stringLength) - math(EXPR offset "0") - - while(stringLength GREATER 0) - - if(stringLength GREATER ${WRAP_STRING_AT_COLUMN}) - math(EXPR length "${WRAP_STRING_AT_COLUMN}") - else() - math(EXPR length "${stringLength}") - endif() - - string(SUBSTRING ${${WRAP_STRING_VARIABLE}} ${offset} ${length} line) - set(lines "${lines}\n${line}") - - math(EXPR stringLength "${stringLength} - ${length}") - math(EXPR offset "${offset} + ${length}") - endwhile() - - set(${WRAP_STRING_VARIABLE} "${lines}" PARENT_SCOPE) -endfunction() - -# Function to embed contents of a file as byte array in C/C++ header file(.h). The header file -# will contain a byte array and integer variable holding the size of the array. -# Parameters -# SOURCE_FILE - The path of source file whose contents will be embedded in the header file. -# VARIABLE_NAME - The name of the variable for the byte array. The string "_SIZE" will be append -# to this name and will be used a variable name for size variable. -# HEADER_FILE - The path of header file. -# APPEND - If specified appends to the header file instead of overwriting it -# NULL_TERMINATE - If specified a null byte(zero) will be append to the byte array. This will be -# useful if the source file is a text file and we want to use the file contents -# as string. But the size variable holds size of the byte array without this -# null byte. -# Usage: -# bin2h(SOURCE_FILE "Logo.png" HEADER_FILE "Logo.h" VARIABLE_NAME "LOGO_PNG") -function(BIN2H) - set(options APPEND NULL_TERMINATE) - set(oneValueArgs SOURCE_FILE VARIABLE_NAME HEADER_FILE) - cmake_parse_arguments(BIN2H "${options}" "${oneValueArgs}" "" ${ARGN}) - - # reads source file contents as hex string - file(READ ${BIN2H_SOURCE_FILE} hexString HEX) - string(LENGTH ${hexString} hexStringLength) - - # appends null byte if asked - if(BIN2H_NULL_TERMINATE) - set(hexString "${hexString}00") - endif() - - # wraps the hex string into multiple lines at column 32(i.e. 16 bytes per line) - wrap_string(VARIABLE hexString AT_COLUMN 32) - math(EXPR arraySize "${hexStringLength} / 2") - - # adds '0x' prefix and comma suffix before and after every byte respectively - string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " arrayValues ${hexString}) - # removes trailing comma - string(REGEX REPLACE ", $" "" arrayValues ${arrayValues}) - - # converts the variable name into proper C identifier - IF (${CMAKE_VERSION} GREATER 2.8.10) # fix for legacy cmake - string(MAKE_C_IDENTIFIER "${BIN2H_VARIABLE_NAME}" BIN2H_VARIABLE_NAME) - ENDIF() - string(TOUPPER "${BIN2H_VARIABLE_NAME}" BIN2H_VARIABLE_NAME) - - # declares byte array and the length variables - set(arrayDefinition "const unsigned char ${BIN2H_VARIABLE_NAME}[] = { ${arrayValues} };") - set(arraySizeDefinition "const size_t ${BIN2H_VARIABLE_NAME}_SIZE = ${arraySize};") - - set(declarations "${arrayDefinition}\n\n${arraySizeDefinition}\n\n") - if(BIN2H_APPEND) - file(APPEND ${BIN2H_HEADER_FILE} "${declarations}") - else() - file(WRITE ${BIN2H_HEADER_FILE} "${declarations}") - endif() -endfunction() diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/cl.hpp b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/cl.hpp deleted file mode 100644 index 5c9be5c5e..000000000 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/cl.hpp +++ /dev/null @@ -1,12906 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008-2015 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Materials. - * - * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - ******************************************************************************/ - -/*! \file - * - * \brief C++ bindings for OpenCL 1.0 (rev 48), OpenCL 1.1 (rev 33) and - * OpenCL 1.2 (rev 15) - * \author Benedict R. Gaster, Laurent Morichetti and Lee Howes - * - * Additions and fixes from: - * Brian Cole, March 3rd 2010 and April 2012 - * Matt Gruenke, April 2012. - * Bruce Merry, February 2013. - * Tom Deakin and Simon McIntosh-Smith, July 2013 - * - * \version 1.2.7 - * \date January 2015 - * - * Optional extension support - * - * cl - * cl_ext_device_fission - * #define USE_CL_DEVICE_FISSION - */ - -/*! \mainpage - * \section intro Introduction - * For many large applications C++ is the language of choice and so it seems - * reasonable to define C++ bindings for OpenCL. - * - * - * The interface is contained with a single C++ header file \em cl.hpp and all - * definitions are contained within the namespace \em cl. There is no additional - * requirement to include \em cl.h and to use either the C++ or original C - * bindings it is enough to simply include \em cl.hpp. - * - * The bindings themselves are lightweight and correspond closely to the - * underlying C API. Using the C++ bindings introduces no additional execution - * overhead. - * - * For detail documentation on the bindings see: - * - * The OpenCL C++ Wrapper API 1.2 (revision 09) - * http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf - * - * \section example Example - * - * The following example shows a general use case for the C++ - * bindings, including support for the optional exception feature and - * also the supplied vector and string classes, see following sections for - * decriptions of these features. - * - * \code - * #define __CL_ENABLE_EXCEPTIONS - * - * #if defined(__APPLE__) || defined(__MACOSX) - * #include - * #else - * #include - * #endif - * #include - * #include - * #include - * - * const char * helloStr = "__kernel void " - * "hello(void) " - * "{ " - * " " - * "} "; - * - * int - * main(void) - * { - * cl_int err = CL_SUCCESS; - * try { - * - * std::vector platforms; - * cl::Platform::get(&platforms); - * if (platforms.size() == 0) { - * std::cout << "Platform size 0\n"; - * return -1; - * } - * - * cl_context_properties properties[] = - * { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0}; - * cl::Context context(CL_DEVICE_TYPE_CPU, properties); - * - * std::vector devices = context.getInfo(); - * - * cl::Program::Sources source(1, - * std::make_pair(helloStr,strlen(helloStr))); - * cl::Program program_ = cl::Program(context, source); - * program_.build(devices); - * - * cl::Kernel kernel(program_, "hello", &err); - * - * cl::Event event; - * cl::CommandQueue queue(context, devices[0], 0, &err); - * queue.enqueueNDRangeKernel( - * kernel, - * cl::NullRange, - * cl::NDRange(4,4), - * cl::NullRange, - * NULL, - * &event); - * - * event.wait(); - * } - * catch (cl::Error err) { - * std::cerr - * << "ERROR: " - * << err.what() - * << "(" - * << err.err() - * << ")" - * << std::endl; - * } - * - * return EXIT_SUCCESS; - * } - * - * \endcode - * - */ -#ifndef CL_HPP_ -#define CL_HPP_ - -#ifdef _WIN32 - -#include - -#if defined(USE_DX_INTEROP) -#include -#include -#endif -#endif // _WIN32 - -#if defined(_MSC_VER) -#include -#endif // _MSC_VER - -// -#if defined(USE_CL_DEVICE_FISSION) -#include -#endif - -#if defined(__APPLE__) || defined(__MACOSX) -#include -#else -#include -#endif // !__APPLE__ - -#if (_MSC_VER >= 1700) || (__cplusplus >= 201103L) -#define CL_HPP_RVALUE_REFERENCES_SUPPORTED -#define CL_HPP_CPP11_ATOMICS_SUPPORTED -#include -#endif - -#if (__cplusplus >= 201103L) -#define CL_HPP_NOEXCEPT noexcept -#else -#define CL_HPP_NOEXCEPT -#endif - - -// To avoid accidentally taking ownership of core OpenCL types -// such as cl_kernel constructors are made explicit -// under OpenCL 1.2 -#if defined(CL_VERSION_1_2) && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) -#define __CL_EXPLICIT_CONSTRUCTORS explicit -#else // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) -#define __CL_EXPLICIT_CONSTRUCTORS -#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - -// Define deprecated prefixes and suffixes to ensure compilation -// in case they are not pre-defined -#if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED) -#define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED -#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED) -#if !defined(CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED) -#define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED -#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED) - -#if !defined(CL_CALLBACK) -#define CL_CALLBACK -#endif //CL_CALLBACK - -#include -#include -#include - -#if defined(__CL_ENABLE_EXCEPTIONS) -#include -#endif // #if defined(__CL_ENABLE_EXCEPTIONS) - -#if !defined(__NO_STD_VECTOR) -#include -#endif - -#if !defined(__NO_STD_STRING) -#include -#endif - -#if defined(__ANDROID__) || defined(linux) || defined(__APPLE__) || defined(__MACOSX) -#include -#endif // linux - -#include - - -/*! \namespace cl - * - * \brief The OpenCL C++ bindings are defined within this namespace. - * - */ -namespace cl { - -class Memory; - -/** - * Deprecated APIs for 1.2 - */ -#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) -#define __INIT_CL_EXT_FCN_PTR(name) \ - if(!pfn_##name) { \ - pfn_##name = (PFN_##name) \ - clGetExtensionFunctionAddress(#name); \ - if(!pfn_##name) { \ - } \ - } -#endif // #if defined(CL_VERSION_1_1) - -#if defined(CL_VERSION_1_2) -#define __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, name) \ - if(!pfn_##name) { \ - pfn_##name = (PFN_##name) \ - clGetExtensionFunctionAddressForPlatform(platform, #name); \ - if(!pfn_##name) { \ - } \ - } -#endif // #if defined(CL_VERSION_1_1) - -class Program; -class Device; -class Context; -class CommandQueue; -class Memory; -class Buffer; - -#if defined(__CL_ENABLE_EXCEPTIONS) -/*! \brief Exception class - * - * This may be thrown by API functions when __CL_ENABLE_EXCEPTIONS is defined. - */ -class Error : public std::exception -{ -private: - cl_int err_; - const char * errStr_; -public: - /*! \brief Create a new CL error exception for a given error code - * and corresponding message. - * - * \param err error code value. - * - * \param errStr a descriptive string that must remain in scope until - * handling of the exception has concluded. If set, it - * will be returned by what(). - */ - Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr) - {} - - ~Error() throw() {} - - /*! \brief Get error string associated with exception - * - * \return A memory pointer to the error message string. - */ - virtual const char * what() const throw () - { - if (errStr_ == NULL) { - return "empty"; - } - else { - return errStr_; - } - } - - /*! \brief Get error code associated with exception - * - * \return The error code. - */ - cl_int err(void) const { return err_; } -}; - -#define __ERR_STR(x) #x -#else -#define __ERR_STR(x) NULL -#endif // __CL_ENABLE_EXCEPTIONS - - -namespace detail -{ -#if defined(__CL_ENABLE_EXCEPTIONS) -static inline cl_int errHandler ( - cl_int err, - const char * errStr = NULL) -{ - if (err != CL_SUCCESS) { - throw Error(err, errStr); - } - return err; -} -#else -static inline cl_int errHandler (cl_int err, const char * errStr = NULL) -{ - (void) errStr; // suppress unused variable warning - return err; -} -#endif // __CL_ENABLE_EXCEPTIONS -} - - - -//! \cond DOXYGEN_DETAIL -#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) -#define __GET_DEVICE_INFO_ERR __ERR_STR(clGetDeviceInfo) -#define __GET_PLATFORM_INFO_ERR __ERR_STR(clGetPlatformInfo) -#define __GET_DEVICE_IDS_ERR __ERR_STR(clGetDeviceIDs) -#define __GET_PLATFORM_IDS_ERR __ERR_STR(clGetPlatformIDs) -#define __GET_CONTEXT_INFO_ERR __ERR_STR(clGetContextInfo) -#define __GET_EVENT_INFO_ERR __ERR_STR(clGetEventInfo) -#define __GET_EVENT_PROFILE_INFO_ERR __ERR_STR(clGetEventProfileInfo) -#define __GET_MEM_OBJECT_INFO_ERR __ERR_STR(clGetMemObjectInfo) -#define __GET_IMAGE_INFO_ERR __ERR_STR(clGetImageInfo) -#define __GET_SAMPLER_INFO_ERR __ERR_STR(clGetSamplerInfo) -#define __GET_KERNEL_INFO_ERR __ERR_STR(clGetKernelInfo) -#if defined(CL_VERSION_1_2) -#define __GET_KERNEL_ARG_INFO_ERR __ERR_STR(clGetKernelArgInfo) -#endif // #if defined(CL_VERSION_1_2) -#define __GET_KERNEL_WORK_GROUP_INFO_ERR __ERR_STR(clGetKernelWorkGroupInfo) -#define __GET_PROGRAM_INFO_ERR __ERR_STR(clGetProgramInfo) -#define __GET_PROGRAM_BUILD_INFO_ERR __ERR_STR(clGetProgramBuildInfo) -#define __GET_COMMAND_QUEUE_INFO_ERR __ERR_STR(clGetCommandQueueInfo) - -#define __CREATE_CONTEXT_ERR __ERR_STR(clCreateContext) -#define __CREATE_CONTEXT_FROM_TYPE_ERR __ERR_STR(clCreateContextFromType) -#define __GET_SUPPORTED_IMAGE_FORMATS_ERR __ERR_STR(clGetSupportedImageFormats) - -#define __CREATE_BUFFER_ERR __ERR_STR(clCreateBuffer) -#define __COPY_ERR __ERR_STR(cl::copy) -#define __CREATE_SUBBUFFER_ERR __ERR_STR(clCreateSubBuffer) -#define __CREATE_GL_BUFFER_ERR __ERR_STR(clCreateFromGLBuffer) -#define __CREATE_GL_RENDER_BUFFER_ERR __ERR_STR(clCreateFromGLBuffer) -#define __GET_GL_OBJECT_INFO_ERR __ERR_STR(clGetGLObjectInfo) -#if defined(CL_VERSION_1_2) -#define __CREATE_IMAGE_ERR __ERR_STR(clCreateImage) -#define __CREATE_GL_TEXTURE_ERR __ERR_STR(clCreateFromGLTexture) -#define __IMAGE_DIMENSION_ERR __ERR_STR(Incorrect image dimensions) -#endif // #if defined(CL_VERSION_1_2) -#define __CREATE_SAMPLER_ERR __ERR_STR(clCreateSampler) -#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback) - -#define __CREATE_USER_EVENT_ERR __ERR_STR(clCreateUserEvent) -#define __SET_USER_EVENT_STATUS_ERR __ERR_STR(clSetUserEventStatus) -#define __SET_EVENT_CALLBACK_ERR __ERR_STR(clSetEventCallback) -#define __WAIT_FOR_EVENTS_ERR __ERR_STR(clWaitForEvents) - -#define __CREATE_KERNEL_ERR __ERR_STR(clCreateKernel) -#define __SET_KERNEL_ARGS_ERR __ERR_STR(clSetKernelArg) -#define __CREATE_PROGRAM_WITH_SOURCE_ERR __ERR_STR(clCreateProgramWithSource) -#define __CREATE_PROGRAM_WITH_BINARY_ERR __ERR_STR(clCreateProgramWithBinary) -#if defined(CL_VERSION_1_2) -#define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR __ERR_STR(clCreateProgramWithBuiltInKernels) -#endif // #if defined(CL_VERSION_1_2) -#define __BUILD_PROGRAM_ERR __ERR_STR(clBuildProgram) -#if defined(CL_VERSION_1_2) -#define __COMPILE_PROGRAM_ERR __ERR_STR(clCompileProgram) -#define __LINK_PROGRAM_ERR __ERR_STR(clLinkProgram) -#endif // #if defined(CL_VERSION_1_2) -#define __CREATE_KERNELS_IN_PROGRAM_ERR __ERR_STR(clCreateKernelsInProgram) - -#define __CREATE_COMMAND_QUEUE_ERR __ERR_STR(clCreateCommandQueue) -#define __SET_COMMAND_QUEUE_PROPERTY_ERR __ERR_STR(clSetCommandQueueProperty) -#define __ENQUEUE_READ_BUFFER_ERR __ERR_STR(clEnqueueReadBuffer) -#define __ENQUEUE_READ_BUFFER_RECT_ERR __ERR_STR(clEnqueueReadBufferRect) -#define __ENQUEUE_WRITE_BUFFER_ERR __ERR_STR(clEnqueueWriteBuffer) -#define __ENQUEUE_WRITE_BUFFER_RECT_ERR __ERR_STR(clEnqueueWriteBufferRect) -#define __ENQEUE_COPY_BUFFER_ERR __ERR_STR(clEnqueueCopyBuffer) -#define __ENQEUE_COPY_BUFFER_RECT_ERR __ERR_STR(clEnqueueCopyBufferRect) -#define __ENQUEUE_FILL_BUFFER_ERR __ERR_STR(clEnqueueFillBuffer) -#define __ENQUEUE_READ_IMAGE_ERR __ERR_STR(clEnqueueReadImage) -#define __ENQUEUE_WRITE_IMAGE_ERR __ERR_STR(clEnqueueWriteImage) -#define __ENQUEUE_COPY_IMAGE_ERR __ERR_STR(clEnqueueCopyImage) -#define __ENQUEUE_FILL_IMAGE_ERR __ERR_STR(clEnqueueFillImage) -#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR __ERR_STR(clEnqueueCopyImageToBuffer) -#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR __ERR_STR(clEnqueueCopyBufferToImage) -#define __ENQUEUE_MAP_BUFFER_ERR __ERR_STR(clEnqueueMapBuffer) -#define __ENQUEUE_MAP_IMAGE_ERR __ERR_STR(clEnqueueMapImage) -#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR __ERR_STR(clEnqueueUnMapMemObject) -#define __ENQUEUE_NDRANGE_KERNEL_ERR __ERR_STR(clEnqueueNDRangeKernel) -#define __ENQUEUE_TASK_ERR __ERR_STR(clEnqueueTask) -#define __ENQUEUE_NATIVE_KERNEL __ERR_STR(clEnqueueNativeKernel) -#if defined(CL_VERSION_1_2) -#define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR __ERR_STR(clEnqueueMigrateMemObjects) -#endif // #if defined(CL_VERSION_1_2) - -#define __ENQUEUE_ACQUIRE_GL_ERR __ERR_STR(clEnqueueAcquireGLObjects) -#define __ENQUEUE_RELEASE_GL_ERR __ERR_STR(clEnqueueReleaseGLObjects) - - -#define __RETAIN_ERR __ERR_STR(Retain Object) -#define __RELEASE_ERR __ERR_STR(Release Object) -#define __FLUSH_ERR __ERR_STR(clFlush) -#define __FINISH_ERR __ERR_STR(clFinish) -#define __VECTOR_CAPACITY_ERR __ERR_STR(Vector capacity error) - -/** - * CL 1.2 version that uses device fission. - */ -#if defined(CL_VERSION_1_2) -#define __CREATE_SUB_DEVICES __ERR_STR(clCreateSubDevices) -#else -#define __CREATE_SUB_DEVICES __ERR_STR(clCreateSubDevicesEXT) -#endif // #if defined(CL_VERSION_1_2) - -/** - * Deprecated APIs for 1.2 - */ -#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) -#define __ENQUEUE_MARKER_ERR __ERR_STR(clEnqueueMarker) -#define __ENQUEUE_WAIT_FOR_EVENTS_ERR __ERR_STR(clEnqueueWaitForEvents) -#define __ENQUEUE_BARRIER_ERR __ERR_STR(clEnqueueBarrier) -#define __UNLOAD_COMPILER_ERR __ERR_STR(clUnloadCompiler) -#define __CREATE_GL_TEXTURE_2D_ERR __ERR_STR(clCreateFromGLTexture2D) -#define __CREATE_GL_TEXTURE_3D_ERR __ERR_STR(clCreateFromGLTexture3D) -#define __CREATE_IMAGE2D_ERR __ERR_STR(clCreateImage2D) -#define __CREATE_IMAGE3D_ERR __ERR_STR(clCreateImage3D) -#endif // #if defined(CL_VERSION_1_1) - -#endif // __CL_USER_OVERRIDE_ERROR_STRINGS -//! \endcond - -/** - * CL 1.2 marker and barrier commands - */ -#if defined(CL_VERSION_1_2) -#define __ENQUEUE_MARKER_WAIT_LIST_ERR __ERR_STR(clEnqueueMarkerWithWaitList) -#define __ENQUEUE_BARRIER_WAIT_LIST_ERR __ERR_STR(clEnqueueBarrierWithWaitList) -#endif // #if defined(CL_VERSION_1_2) - -#if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING) -typedef std::string STRING_CLASS; -#elif !defined(__USE_DEV_STRING) - -/*! \class string - * \brief Simple string class, that provides a limited subset of std::string - * functionality but avoids many of the issues that come with that class. - - * \note Deprecated. Please use std::string as default or - * re-define the string class to match the std::string - * interface by defining STRING_CLASS - */ -class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED string CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED -{ -private: - ::size_t size_; - char * str_; -public: - //! \brief Constructs an empty string, allocating no memory. - string(void) : size_(0), str_(NULL) - { - } - - /*! \brief Constructs a string populated from an arbitrary value of - * specified size. - * - * An extra '\0' is added, in case none was contained in str. - * - * \param str the initial value of the string instance. Note that '\0' - * characters receive no special treatment. If NULL, - * the string is left empty, with a size of 0. - * - * \param size the number of characters to copy from str. - */ - string(const char * str, ::size_t size) : - size_(size), - str_(NULL) - { - if( size > 0 ) { - str_ = new char[size_+1]; - if (str_ != NULL) { - memcpy(str_, str, size_ * sizeof(char)); - str_[size_] = '\0'; - } - else { - size_ = 0; - } - } - } - - /*! \brief Constructs a string populated from a null-terminated value. - * - * \param str the null-terminated initial value of the string instance. - * If NULL, the string is left empty, with a size of 0. - */ - string(const char * str) : - size_(0), - str_(NULL) - { - if( str ) { - size_= ::strlen(str); - } - if( size_ > 0 ) { - str_ = new char[size_ + 1]; - if (str_ != NULL) { - memcpy(str_, str, (size_ + 1) * sizeof(char)); - } - } - } - - void resize( ::size_t n ) - { - if( size_ == n ) { - return; - } - if (n == 0) { - if( str_ ) { - delete [] str_; - } - str_ = NULL; - size_ = 0; - } - else { - char *newString = new char[n + 1]; - ::size_t copySize = n; - if( size_ < n ) { - copySize = size_; - } - size_ = n; - - if(str_) { - memcpy(newString, str_, (copySize + 1) * sizeof(char)); - } - if( copySize < size_ ) { - memset(newString + copySize, 0, size_ - copySize); - } - newString[size_] = '\0'; - - delete [] str_; - str_ = newString; - } - } - - const char& operator[] ( ::size_t pos ) const - { - return str_[pos]; - } - - char& operator[] ( ::size_t pos ) - { - return str_[pos]; - } - - /*! \brief Copies the value of another string to this one. - * - * \param rhs the string to copy. - * - * \returns a reference to the modified instance. - */ - string& operator=(const string& rhs) - { - if (this == &rhs) { - return *this; - } - - if( str_ != NULL ) { - delete [] str_; - str_ = NULL; - size_ = 0; - } - - if (rhs.size_ == 0 || rhs.str_ == NULL) { - str_ = NULL; - size_ = 0; - } - else { - str_ = new char[rhs.size_ + 1]; - size_ = rhs.size_; - - if (str_ != NULL) { - memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char)); - } - else { - size_ = 0; - } - } - - return *this; - } - - /*! \brief Constructs a string by copying the value of another instance. - * - * \param rhs the string to copy. - */ - string(const string& rhs) : - size_(0), - str_(NULL) - { - *this = rhs; - } - - //! \brief Destructor - frees memory used to hold the current value. - ~string() - { - delete[] str_; - str_ = NULL; - } - - //! \brief Queries the length of the string, excluding any added '\0's. - ::size_t size(void) const { return size_; } - - //! \brief Queries the length of the string, excluding any added '\0's. - ::size_t length(void) const { return size(); } - - /*! \brief Returns a pointer to the private copy held by this instance, - * or "" if empty/unset. - */ - const char * c_str(void) const { return (str_) ? str_ : "";} -}; -typedef cl::string STRING_CLASS; -#endif // #elif !defined(__USE_DEV_STRING) - -#if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR) -#define VECTOR_CLASS std::vector -#elif !defined(__USE_DEV_VECTOR) -#define VECTOR_CLASS cl::vector - -#if !defined(__MAX_DEFAULT_VECTOR_SIZE) -#define __MAX_DEFAULT_VECTOR_SIZE 10 -#endif - -/*! \class vector - * \brief Fixed sized vector implementation that mirroring - * - * \note Deprecated. Please use std::vector as default or - * re-define the vector class to match the std::vector - * interface by defining VECTOR_CLASS - - * \note Not recommended for use with custom objects as - * current implementation will construct N elements - * - * std::vector functionality. - * \brief Fixed sized vector compatible with std::vector. - * - * \note - * This differs from std::vector<> not just in memory allocation, - * but also in terms of when members are constructed, destroyed, - * and assigned instead of being copy constructed. - * - * \param T type of element contained in the vector. - * - * \param N maximum size of the vector. - */ -template -class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED vector -{ -private: - T data_[N]; - unsigned int size_; - -public: - //! \brief Constructs an empty vector with no memory allocated. - vector() : - size_(static_cast(0)) - {} - - //! \brief Deallocates the vector's memory and destroys all of its elements. - ~vector() - { - clear(); - } - - //! \brief Returns the number of elements currently contained. - unsigned int size(void) const - { - return size_; - } - - /*! \brief Empties the vector of all elements. - * \note - * This does not deallocate memory but will invoke destructors - * on contained elements. - */ - void clear() - { - while(!empty()) { - pop_back(); - } - } - - /*! \brief Appends an element after the last valid element. - * Calling this on a vector that has reached capacity will throw an - * exception if exceptions are enabled. - */ - void push_back (const T& x) - { - if (size() < N) { - new (&data_[size_]) T(x); - size_++; - } else { - detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR); - } - } - - /*! \brief Removes the last valid element from the vector. - * Calling this on an empty vector will throw an exception - * if exceptions are enabled. - */ - void pop_back(void) - { - if (size_ != 0) { - --size_; - data_[size_].~T(); - } else { - detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR); - } - } - - /*! \brief Constructs with a value copied from another. - * - * \param vec the vector to copy. - */ - vector(const vector& vec) : - size_(vec.size_) - { - if (size_ != 0) { - assign(vec.begin(), vec.end()); - } - } - - /*! \brief Constructs with a specified number of initial elements. - * - * \param size number of initial elements. - * - * \param val value of initial elements. - */ - vector(unsigned int size, const T& val = T()) : - size_(0) - { - for (unsigned int i = 0; i < size; i++) { - push_back(val); - } - } - - /*! \brief Overwrites the current content with that copied from another - * instance. - * - * \param rhs vector to copy. - * - * \returns a reference to this. - */ - vector& operator=(const vector& rhs) - { - if (this == &rhs) { - return *this; - } - - if (rhs.size_ != 0) { - assign(rhs.begin(), rhs.end()); - } else { - clear(); - } - - return *this; - } - - /*! \brief Tests equality against another instance. - * - * \param vec the vector against which to compare. - */ - bool operator==(vector &vec) - { - if (size() != vec.size()) { - return false; - } - - for( unsigned int i = 0; i < size(); ++i ) { - if( operator[](i) != vec[i] ) { - return false; - } - } - return true; - } - - //! \brief Conversion operator to T*. - operator T* () { return data_; } - - //! \brief Conversion operator to const T*. - operator const T* () const { return data_; } - - //! \brief Tests whether this instance has any elements. - bool empty (void) const - { - return size_==0; - } - - //! \brief Returns the maximum number of elements this instance can hold. - unsigned int max_size (void) const - { - return N; - } - - //! \brief Returns the maximum number of elements this instance can hold. - unsigned int capacity () const - { - return N; - } - - //! \brief Resizes the vector to the given size - void resize(unsigned int newSize, T fill = T()) - { - if (newSize > N) - { - detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR); - } - else - { - while (size_ < newSize) - { - new (&data_[size_]) T(fill); - size_++; - } - while (size_ > newSize) - { - --size_; - data_[size_].~T(); - } - } - } - - /*! \brief Returns a reference to a given element. - * - * \param index which element to access. * - * \note - * The caller is responsible for ensuring index is >= 0 and < size(). - */ - T& operator[](int index) - { - return data_[index]; - } - - /*! \brief Returns a const reference to a given element. - * - * \param index which element to access. - * - * \note - * The caller is responsible for ensuring index is >= 0 and < size(). - */ - const T& operator[](int index) const - { - return data_[index]; - } - - /*! \brief Assigns elements of the vector based on a source iterator range. - * - * \param start Beginning iterator of source range - * \param end Enditerator of source range - * - * \note - * Will throw an exception if exceptions are enabled and size exceeded. - */ - template - void assign(I start, I end) - { - clear(); - while(start != end) { - push_back(*start); - start++; - } - } - - /*! \class iterator - * \brief Const iterator class for vectors - */ - class iterator - { - private: - const vector *vec_; - int index_; - - /** - * Internal iterator constructor to capture reference - * to the vector it iterates over rather than taking - * the vector by copy. - */ - iterator (const vector &vec, int index) : - vec_(&vec) - { - if( !vec.empty() ) { - index_ = index; - } else { - index_ = -1; - } - } - - public: - iterator(void) : - index_(-1), - vec_(NULL) - { - } - - iterator(const iterator& rhs) : - vec_(rhs.vec_), - index_(rhs.index_) - { - } - - ~iterator(void) {} - - static iterator begin(const cl::vector &vec) - { - iterator i(vec, 0); - - return i; - } - - static iterator end(const cl::vector &vec) - { - iterator i(vec, vec.size()); - - return i; - } - - bool operator==(iterator i) - { - return ((vec_ == i.vec_) && - (index_ == i.index_)); - } - - bool operator!=(iterator i) - { - return (!(*this==i)); - } - - iterator& operator++() - { - ++index_; - return *this; - } - - iterator operator++(int) - { - iterator retVal(*this); - ++index_; - return retVal; - } - - iterator& operator--() - { - --index_; - return *this; - } - - iterator operator--(int) - { - iterator retVal(*this); - --index_; - return retVal; - } - - const T& operator *() const - { - return (*vec_)[index_]; - } - }; - - iterator begin(void) - { - return iterator::begin(*this); - } - - iterator begin(void) const - { - return iterator::begin(*this); - } - - iterator end(void) - { - return iterator::end(*this); - } - - iterator end(void) const - { - return iterator::end(*this); - } - - T& front(void) - { - return data_[0]; - } - - T& back(void) - { - return data_[size_]; - } - - const T& front(void) const - { - return data_[0]; - } - - const T& back(void) const - { - return data_[size_-1]; - } -} CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; -#endif // #if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR) - - - - - -namespace detail { -#define __DEFAULT_NOT_INITIALIZED 1 -#define __DEFAULT_BEING_INITIALIZED 2 -#define __DEFAULT_INITIALIZED 4 - - /* - * Compare and exchange primitives are needed for handling of defaults - */ - -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED - inline int compare_exchange(std::atomic * dest, int exchange, int comparand) -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED - inline int compare_exchange(volatile int * dest, int exchange, int comparand) -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED - { -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED - std::atomic_compare_exchange_strong(dest, &comparand, exchange); - return comparand; -#elif _MSC_VER - return (int)(_InterlockedCompareExchange( - (volatile long*)dest, - (long)exchange, - (long)comparand)); -#else // !_MSC_VER && !CL_HPP_CPP11_ATOMICS_SUPPORTED - return (__sync_val_compare_and_swap( - dest, - comparand, - exchange)); -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED - } - - inline void fence() { -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED - std::atomic_thread_fence(std::memory_order_seq_cst); -#elif _MSC_VER // !CL_HPP_CPP11_ATOMICS_SUPPORTED - _ReadWriteBarrier(); -#else // !_MSC_VER && !CL_HPP_CPP11_ATOMICS_SUPPORTED - __sync_synchronize(); -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED - } -} // namespace detail - - -/*! \brief class used to interface between C++ and - * OpenCL C calls that require arrays of size_t values, whose - * size is known statically. - */ -template -class size_t -{ -private: - ::size_t data_[N]; - -public: - //! \brief Initialize size_t to all 0s - size_t() - { - for( int i = 0; i < N; ++i ) { - data_[i] = 0; - } - } - - ::size_t& operator[](int index) - { - return data_[index]; - } - - const ::size_t& operator[](int index) const - { - return data_[index]; - } - - //! \brief Conversion operator to T*. - operator ::size_t* () { return data_; } - - //! \brief Conversion operator to const T*. - operator const ::size_t* () const { return data_; } -}; - -namespace detail { - -// Generic getInfoHelper. The final parameter is used to guide overload -// resolution: the actual parameter passed is an int, which makes this -// a worse conversion sequence than a specialization that declares the -// parameter as an int. -template -inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long) -{ - return f(name, sizeof(T), param, NULL); -} - -// Specialized getInfoHelper for VECTOR_CLASS params -template -inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS* param, long) -{ - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - T* value = (T*) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - param->assign(&value[0], &value[required/sizeof(T)]); - return CL_SUCCESS; -} - -/* Specialization for reference-counted types. This depends on the - * existence of Wrapper::cl_type, and none of the other types having the - * cl_type member. Note that simplify specifying the parameter as Wrapper - * does not work, because when using a derived type (e.g. Context) the generic - * template will provide a better match. - */ -template -inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS* param, int, typename T::cl_type = 0) -{ - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - typename T::cl_type * value = (typename T::cl_type *) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - ::size_t elements = required / sizeof(typename T::cl_type); - param->assign(&value[0], &value[elements]); - for (::size_t i = 0; i < elements; i++) - { - if (value[i] != NULL) - { - err = (*param)[i].retain(); - if (err != CL_SUCCESS) { - return err; - } - } - } - return CL_SUCCESS; -} - -// Specialized for getInfo -template -inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS* param, int) -{ - cl_int err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL); - - if (err != CL_SUCCESS) { - return err; - } - - return CL_SUCCESS; -} - -// Specialized GetInfoHelper for STRING_CLASS params -template -inline cl_int getInfoHelper(Func f, cl_uint name, STRING_CLASS* param, long) -{ - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - // std::string has a constant data member - // a char vector does not - VECTOR_CLASS value(required); - err = f(name, required, value.data(), NULL); - if (err != CL_SUCCESS) { - return err; - } - if (param) { - param->assign(value.begin(), value.end()); - } - return CL_SUCCESS; -} - -// Specialized GetInfoHelper for cl::size_t params -template -inline cl_int getInfoHelper(Func f, cl_uint name, size_t* param, long) -{ - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - ::size_t* value = (::size_t*) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - for(int i = 0; i < N; ++i) { - (*param)[i] = value[i]; - } - - return CL_SUCCESS; -} - -template struct ReferenceHandler; - -/* Specialization for reference-counted types. This depends on the - * existence of Wrapper::cl_type, and none of the other types having the - * cl_type member. Note that simplify specifying the parameter as Wrapper - * does not work, because when using a derived type (e.g. Context) the generic - * template will provide a better match. - */ -template -inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0) -{ - typename T::cl_type value; - cl_int err = f(name, sizeof(value), &value, NULL); - if (err != CL_SUCCESS) { - return err; - } - *param = value; - if (value != NULL) - { - err = param->retain(); - if (err != CL_SUCCESS) { - return err; - } - } - return CL_SUCCESS; -} - -#define __PARAM_NAME_INFO_1_0(F) \ - F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \ - \ - F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \ - F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \ - F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \ - F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \ - F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \ - F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \ - F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \ - F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \ - F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \ - F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \ - F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \ - F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \ - F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \ - F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \ - \ - F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \ - F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS) \ - F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS) \ - \ - F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \ - F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \ - F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \ - F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \ - \ - F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \ - \ - F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \ - F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \ - F(cl_mem_info, CL_MEM_SIZE, ::size_t) \ - F(cl_mem_info, CL_MEM_HOST_PTR, void*) \ - F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \ - F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \ - F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \ - \ - F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \ - F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \ - F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \ - F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \ - F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \ - F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \ - F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \ - \ - F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \ - F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \ - F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_addressing_mode) \ - F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_filter_mode) \ - F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_bool) \ - \ - F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \ - F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \ - F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \ - F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS) \ - F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \ - F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \ - F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS) \ - \ - F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \ - F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \ - F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \ - \ - F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \ - F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \ - F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \ - F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \ - F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \ - \ - F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \ - F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \ - F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \ - \ - F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \ - F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \ - F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \ - F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties) - -#if defined(CL_VERSION_1_1) -#define __PARAM_NAME_INFO_1_1(F) \ - F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \ - F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, STRING_CLASS) \ - \ - F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \ - F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \ - \ - F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \ - F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \ - \ - F(cl_event_info, CL_EVENT_CONTEXT, cl::Context) -#endif // CL_VERSION_1_1 - - -#if defined(CL_VERSION_1_2) -#define __PARAM_NAME_INFO_1_2(F) \ - F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer) \ - \ - F(cl_program_info, CL_PROGRAM_NUM_KERNELS, ::size_t) \ - F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, STRING_CLASS) \ - \ - F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \ - \ - F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, STRING_CLASS) \ - \ - F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \ - F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \ - F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, STRING_CLASS) \ - F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, STRING_CLASS) \ - \ - F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl_device_id) \ - F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_PARTITION_TYPE, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, ::size_t) \ - F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \ - F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, STRING_CLASS) -#endif // #if defined(CL_VERSION_1_2) - -#if defined(USE_CL_DEVICE_FISSION) -#define __PARAM_NAME_DEVICE_FISSION(F) \ - F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \ - F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \ - F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS) -#endif // USE_CL_DEVICE_FISSION - -template -struct param_traits {}; - -#define __CL_DECLARE_PARAM_TRAITS(token, param_name, T) \ -struct token; \ -template<> \ -struct param_traits \ -{ \ - enum { value = param_name }; \ - typedef T param_type; \ -}; - -__PARAM_NAME_INFO_1_0(__CL_DECLARE_PARAM_TRAITS) -#if defined(CL_VERSION_1_1) -__PARAM_NAME_INFO_1_1(__CL_DECLARE_PARAM_TRAITS) -#endif // CL_VERSION_1_1 -#if defined(CL_VERSION_1_2) -__PARAM_NAME_INFO_1_2(__CL_DECLARE_PARAM_TRAITS) -#endif // CL_VERSION_1_1 - -#if defined(USE_CL_DEVICE_FISSION) -__PARAM_NAME_DEVICE_FISSION(__CL_DECLARE_PARAM_TRAITS); -#endif // USE_CL_DEVICE_FISSION - -#ifdef CL_PLATFORM_ICD_SUFFIX_KHR -__CL_DECLARE_PARAM_TRAITS(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, STRING_CLASS) -#endif - -#ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong) -#endif - -#ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, VECTOR_CLASS< ::size_t>) -#endif -#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_SIMD_WIDTH_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint) -#endif -#ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint) -#endif - -#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint) -#endif -#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint) -#endif -#ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint) -#endif -#ifdef CL_DEVICE_WARP_SIZE_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint) -#endif -#ifdef CL_DEVICE_GPU_OVERLAP_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool) -#endif -#ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool) -#endif -#ifdef CL_DEVICE_INTEGRATED_MEMORY_NV -__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool) -#endif - -// Convenience functions - -template -inline cl_int -getInfo(Func f, cl_uint name, T* param) -{ - return getInfoHelper(f, name, param, 0); -} - -template -struct GetInfoFunctor0 -{ - Func f_; const Arg0& arg0_; - cl_int operator ()( - cl_uint param, ::size_t size, void* value, ::size_t* size_ret) - { return f_(arg0_, param, size, value, size_ret); } -}; - -template -struct GetInfoFunctor1 -{ - Func f_; const Arg0& arg0_; const Arg1& arg1_; - cl_int operator ()( - cl_uint param, ::size_t size, void* value, ::size_t* size_ret) - { return f_(arg0_, arg1_, param, size, value, size_ret); } -}; - -template -inline cl_int -getInfo(Func f, const Arg0& arg0, cl_uint name, T* param) -{ - GetInfoFunctor0 f0 = { f, arg0 }; - return getInfoHelper(f0, name, param, 0); -} - -template -inline cl_int -getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param) -{ - GetInfoFunctor1 f0 = { f, arg0, arg1 }; - return getInfoHelper(f0, name, param, 0); -} - -template -struct ReferenceHandler -{ }; - -#if defined(CL_VERSION_1_2) -/** - * OpenCL 1.2 devices do have retain/release. - */ -template <> -struct ReferenceHandler -{ - /** - * Retain the device. - * \param device A valid device created using createSubDevices - * \return - * CL_SUCCESS if the function executed successfully. - * CL_INVALID_DEVICE if device was not a valid subdevice - * CL_OUT_OF_RESOURCES - * CL_OUT_OF_HOST_MEMORY - */ - static cl_int retain(cl_device_id device) - { return ::clRetainDevice(device); } - /** - * Retain the device. - * \param device A valid device created using createSubDevices - * \return - * CL_SUCCESS if the function executed successfully. - * CL_INVALID_DEVICE if device was not a valid subdevice - * CL_OUT_OF_RESOURCES - * CL_OUT_OF_HOST_MEMORY - */ - static cl_int release(cl_device_id device) - { return ::clReleaseDevice(device); } -}; -#else // #if defined(CL_VERSION_1_2) -/** - * OpenCL 1.1 devices do not have retain/release. - */ -template <> -struct ReferenceHandler -{ - // cl_device_id does not have retain(). - static cl_int retain(cl_device_id) - { return CL_SUCCESS; } - // cl_device_id does not have release(). - static cl_int release(cl_device_id) - { return CL_SUCCESS; } -}; -#endif // #if defined(CL_VERSION_1_2) - -template <> -struct ReferenceHandler -{ - // cl_platform_id does not have retain(). - static cl_int retain(cl_platform_id) - { return CL_SUCCESS; } - // cl_platform_id does not have release(). - static cl_int release(cl_platform_id) - { return CL_SUCCESS; } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_context context) - { return ::clRetainContext(context); } - static cl_int release(cl_context context) - { return ::clReleaseContext(context); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_command_queue queue) - { return ::clRetainCommandQueue(queue); } - static cl_int release(cl_command_queue queue) - { return ::clReleaseCommandQueue(queue); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_mem memory) - { return ::clRetainMemObject(memory); } - static cl_int release(cl_mem memory) - { return ::clReleaseMemObject(memory); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_sampler sampler) - { return ::clRetainSampler(sampler); } - static cl_int release(cl_sampler sampler) - { return ::clReleaseSampler(sampler); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_program program) - { return ::clRetainProgram(program); } - static cl_int release(cl_program program) - { return ::clReleaseProgram(program); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_kernel kernel) - { return ::clRetainKernel(kernel); } - static cl_int release(cl_kernel kernel) - { return ::clReleaseKernel(kernel); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_event event) - { return ::clRetainEvent(event); } - static cl_int release(cl_event event) - { return ::clReleaseEvent(event); } -}; - - -// Extracts version number with major in the upper 16 bits, minor in the lower 16 -static cl_uint getVersion(const char *versionInfo) -{ - int highVersion = 0; - int lowVersion = 0; - int index = 7; - while(versionInfo[index] != '.' ) { - highVersion *= 10; - highVersion += versionInfo[index]-'0'; - ++index; - } - ++index; - while(versionInfo[index] != ' ' && versionInfo[index] != '\0') { - lowVersion *= 10; - lowVersion += versionInfo[index]-'0'; - ++index; - } - return (highVersion << 16) | lowVersion; -} - -static cl_uint getPlatformVersion(cl_platform_id platform) -{ - ::size_t size = 0; - clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL, &size); - char *versionInfo = (char *) alloca(size); - clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, &versionInfo[0], &size); - return getVersion(versionInfo); -} - -static cl_uint getDevicePlatformVersion(cl_device_id device) -{ - cl_platform_id platform; - clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL); - return getPlatformVersion(platform); -} - -#if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) -static cl_uint getContextPlatformVersion(cl_context context) -{ - // The platform cannot be queried directly, so we first have to grab a - // device and obtain its context - ::size_t size = 0; - clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size); - if (size == 0) - return 0; - cl_device_id *devices = (cl_device_id *) alloca(size); - clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices, NULL); - return getDevicePlatformVersion(devices[0]); -} -#endif // #if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - -template -class Wrapper -{ -public: - typedef T cl_type; - -protected: - cl_type object_; - -public: - Wrapper() : object_(NULL) { } - - Wrapper(const cl_type &obj) : object_(obj) { } - - ~Wrapper() - { - if (object_ != NULL) { release(); } - } - - Wrapper(const Wrapper& rhs) - { - object_ = rhs.object_; - if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - Wrapper(Wrapper&& rhs) CL_HPP_NOEXCEPT - { - object_ = rhs.object_; - rhs.object_ = NULL; - } -#endif - - Wrapper& operator = (const Wrapper& rhs) - { - if (this != &rhs) { - if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } - object_ = rhs.object_; - if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } - } - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - Wrapper& operator = (Wrapper&& rhs) - { - if (this != &rhs) { - if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } - object_ = rhs.object_; - rhs.object_ = NULL; - } - return *this; - } -#endif - - Wrapper& operator = (const cl_type &rhs) - { - if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } - object_ = rhs; - return *this; - } - - cl_type operator ()() const { return object_; } - - cl_type& operator ()() { return object_; } - -protected: - template - friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type); - - cl_int retain() const - { - return ReferenceHandler::retain(object_); - } - - cl_int release() const - { - return ReferenceHandler::release(object_); - } -}; - -template <> -class Wrapper -{ -public: - typedef cl_device_id cl_type; - -protected: - cl_type object_; - bool referenceCountable_; - - static bool isReferenceCountable(cl_device_id device) - { - bool retVal = false; - if (device != NULL) { - int version = getDevicePlatformVersion(device); - if(version > ((1 << 16) + 1)) { - retVal = true; - } - } - return retVal; - } - -public: - Wrapper() : object_(NULL), referenceCountable_(false) - { - } - - Wrapper(const cl_type &obj) : object_(obj), referenceCountable_(false) - { - referenceCountable_ = isReferenceCountable(obj); - } - - ~Wrapper() - { - if (object_ != NULL) { release(); } - } - - Wrapper(const Wrapper& rhs) - { - object_ = rhs.object_; - referenceCountable_ = isReferenceCountable(object_); - if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - Wrapper(Wrapper&& rhs) CL_HPP_NOEXCEPT - { - object_ = rhs.object_; - referenceCountable_ = rhs.referenceCountable_; - rhs.object_ = NULL; - rhs.referenceCountable_ = false; - } -#endif - - Wrapper& operator = (const Wrapper& rhs) - { - if (this != &rhs) { - if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } - object_ = rhs.object_; - referenceCountable_ = rhs.referenceCountable_; - if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } - } - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - Wrapper& operator = (Wrapper&& rhs) - { - if (this != &rhs) { - if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } - object_ = rhs.object_; - referenceCountable_ = rhs.referenceCountable_; - rhs.object_ = NULL; - rhs.referenceCountable_ = false; - } - return *this; - } -#endif - - Wrapper& operator = (const cl_type &rhs) - { - if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } - object_ = rhs; - referenceCountable_ = isReferenceCountable(object_); - return *this; - } - - cl_type operator ()() const { return object_; } - - cl_type& operator ()() { return object_; } - -protected: - template - friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type); - - template - friend inline cl_int getInfoHelper(Func, cl_uint, VECTOR_CLASS*, int, typename U::cl_type); - - cl_int retain() const - { - if( referenceCountable_ ) { - return ReferenceHandler::retain(object_); - } - else { - return CL_SUCCESS; - } - } - - cl_int release() const - { - if( referenceCountable_ ) { - return ReferenceHandler::release(object_); - } - else { - return CL_SUCCESS; - } - } -}; - -} // namespace detail -//! \endcond - -/*! \stuct ImageFormat - * \brief Adds constructors and member functions for cl_image_format. - * - * \see cl_image_format - */ -struct ImageFormat : public cl_image_format -{ - //! \brief Default constructor - performs no initialization. - ImageFormat(){} - - //! \brief Initializing constructor. - ImageFormat(cl_channel_order order, cl_channel_type type) - { - image_channel_order = order; - image_channel_data_type = type; - } - - //! \brief Assignment operator. - ImageFormat& operator = (const ImageFormat& rhs) - { - if (this != &rhs) { - this->image_channel_data_type = rhs.image_channel_data_type; - this->image_channel_order = rhs.image_channel_order; - } - return *this; - } -}; - -/*! \brief Class interface for cl_device_id. - * - * \note Copies of these objects are inexpensive, since they don't 'own' - * any underlying resources or data structures. - * - * \see cl_device_id - */ -class Device : public detail::Wrapper -{ -public: - //! \brief Default constructor - initializes to NULL. - Device() : detail::Wrapper() { } - - /*! \brief Constructor from cl_device_id. - * - * This simply copies the device ID value, which is an inexpensive operation. - */ - __CL_EXPLICIT_CONSTRUCTORS Device(const cl_device_id &device) : detail::Wrapper(device) { } - - /*! \brief Returns the first device on the default context. - * - * \see Context::getDefault() - */ - static Device getDefault(cl_int * err = NULL); - - /*! \brief Assignment operator from cl_device_id. - * - * This simply copies the device ID value, which is an inexpensive operation. - */ - Device& operator = (const cl_device_id& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Device(const Device& dev) : detail::Wrapper(dev) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Device& operator = (const Device &dev) - { - detail::Wrapper::operator=(dev); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Device(Device&& dev) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(dev)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Device& operator = (Device &&dev) - { - detail::Wrapper::operator=(std::move(dev)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - //! \brief Wrapper for clGetDeviceInfo(). - template - cl_int getInfo(cl_device_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetDeviceInfo, object_, name, param), - __GET_DEVICE_INFO_ERR); - } - - //! \brief Wrapper for clGetDeviceInfo() that returns by value. - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_device_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - /** - * CL 1.2 version - */ -#if defined(CL_VERSION_1_2) - //! \brief Wrapper for clCreateSubDevicesEXT(). - cl_int createSubDevices( - const cl_device_partition_property * properties, - VECTOR_CLASS* devices) - { - cl_uint n = 0; - cl_int err = clCreateSubDevices(object_, properties, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = clCreateSubDevices(object_, properties, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif // #if defined(CL_VERSION_1_2) - -/** - * CL 1.1 version that uses device fission. - */ -#if defined(CL_VERSION_1_1) -#if defined(USE_CL_DEVICE_FISSION) - cl_int createSubDevices( - const cl_device_partition_property_ext * properties, - VECTOR_CLASS* devices) - { - typedef CL_API_ENTRY cl_int - ( CL_API_CALL * PFN_clCreateSubDevicesEXT)( - cl_device_id /*in_device*/, - const cl_device_partition_property_ext * /* properties */, - cl_uint /*num_entries*/, - cl_device_id * /*out_devices*/, - cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL; - __INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT); - - cl_uint n = 0; - cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif // #if defined(USE_CL_DEVICE_FISSION) -#endif // #if defined(CL_VERSION_1_1) -}; - -/*! \brief Class interface for cl_platform_id. - * - * \note Copies of these objects are inexpensive, since they don't 'own' - * any underlying resources or data structures. - * - * \see cl_platform_id - */ -class Platform : public detail::Wrapper -{ -public: - //! \brief Default constructor - initializes to NULL. - Platform() : detail::Wrapper() { } - - /*! \brief Constructor from cl_platform_id. - * - * This simply copies the platform ID value, which is an inexpensive operation. - */ - __CL_EXPLICIT_CONSTRUCTORS Platform(const cl_platform_id &platform) : detail::Wrapper(platform) { } - - /*! \brief Assignment operator from cl_platform_id. - * - * This simply copies the platform ID value, which is an inexpensive operation. - */ - Platform& operator = (const cl_platform_id& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - //! \brief Wrapper for clGetPlatformInfo(). - cl_int getInfo(cl_platform_info name, STRING_CLASS* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetPlatformInfo, object_, name, param), - __GET_PLATFORM_INFO_ERR); - } - - //! \brief Wrapper for clGetPlatformInfo() that returns by value. - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_platform_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - /*! \brief Gets a list of devices for this platform. - * - * Wraps clGetDeviceIDs(). - */ - cl_int getDevices( - cl_device_type type, - VECTOR_CLASS* devices) const - { - cl_uint n = 0; - if( devices == NULL ) { - return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR); - } - cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = ::clGetDeviceIDs(object_, type, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } - -#if defined(USE_DX_INTEROP) - /*! \brief Get the list of available D3D10 devices. - * - * \param d3d_device_source. - * - * \param d3d_object. - * - * \param d3d_device_set. - * - * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device - * values returned in devices can be used to identify a specific OpenCL - * device. If \a devices argument is NULL, this argument is ignored. - * - * \return One of the following values: - * - CL_SUCCESS if the function is executed successfully. - * - * The application can query specific capabilities of the OpenCL device(s) - * returned by cl::getDevices. This can be used by the application to - * determine which device(s) to use. - * - * \note In the case that exceptions are enabled and a return value - * other than CL_SUCCESS is generated, then cl::Error exception is - * generated. - */ - cl_int getDevices( - cl_d3d10_device_source_khr d3d_device_source, - void * d3d_object, - cl_d3d10_device_set_khr d3d_device_set, - VECTOR_CLASS* devices) const - { - typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)( - cl_platform_id platform, - cl_d3d10_device_source_khr d3d_device_source, - void * d3d_object, - cl_d3d10_device_set_khr d3d_device_set, - cl_uint num_entries, - cl_device_id * devices, - cl_uint* num_devices); - - if( devices == NULL ) { - return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR); - } - - static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL; - __INIT_CL_EXT_FCN_PTR_PLATFORM(object_, clGetDeviceIDsFromD3D10KHR); - - cl_uint n = 0; - cl_int err = pfn_clGetDeviceIDsFromD3D10KHR( - object_, - d3d_device_source, - d3d_object, - d3d_device_set, - 0, - NULL, - &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = pfn_clGetDeviceIDsFromD3D10KHR( - object_, - d3d_device_source, - d3d_object, - d3d_device_set, - n, - ids, - NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif - - /*! \brief Gets a list of available platforms. - * - * Wraps clGetPlatformIDs(). - */ - static cl_int get( - VECTOR_CLASS* platforms) - { - cl_uint n = 0; - - if( platforms == NULL ) { - return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR); - } - - cl_int err = ::clGetPlatformIDs(0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - cl_platform_id* ids = (cl_platform_id*) alloca( - n * sizeof(cl_platform_id)); - err = ::clGetPlatformIDs(n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - platforms->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } - - /*! \brief Gets the first available platform. - * - * Wraps clGetPlatformIDs(), returning the first result. - */ - static cl_int get( - Platform * platform) - { - cl_uint n = 0; - - if( platform == NULL ) { - return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR); - } - - cl_int err = ::clGetPlatformIDs(0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - cl_platform_id* ids = (cl_platform_id*) alloca( - n * sizeof(cl_platform_id)); - err = ::clGetPlatformIDs(n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - *platform = ids[0]; - return CL_SUCCESS; - } - - /*! \brief Gets the first available platform, returning it by value. - * - * Wraps clGetPlatformIDs(), returning the first result. - */ - static Platform get( - cl_int * errResult = NULL) - { - Platform platform; - cl_uint n = 0; - cl_int err = ::clGetPlatformIDs(0, NULL, &n); - if (err != CL_SUCCESS) { - detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - if (errResult != NULL) { - *errResult = err; - } - return Platform(); - } - - cl_platform_id* ids = (cl_platform_id*) alloca( - n * sizeof(cl_platform_id)); - err = ::clGetPlatformIDs(n, ids, NULL); - - if (err != CL_SUCCESS) { - detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - if (errResult != NULL) { - *errResult = err; - } - return Platform(); - } - - - return Platform(ids[0]); - } - - static Platform getDefault( - cl_int *errResult = NULL ) - { - return get(errResult); - } - - -#if defined(CL_VERSION_1_2) - //! \brief Wrapper for clUnloadCompiler(). - cl_int - unloadCompiler() - { - return ::clUnloadPlatformCompiler(object_); - } -#endif // #if defined(CL_VERSION_1_2) -}; // class Platform - -/** - * Deprecated APIs for 1.2 - */ -#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) -/** - * Unload the OpenCL compiler. - * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead. - */ -inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int -UnloadCompiler() CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; -inline cl_int -UnloadCompiler() -{ - return ::clUnloadCompiler(); -} -#endif // #if defined(CL_VERSION_1_1) - -/*! \brief Class interface for cl_context. - * - * \note Copies of these objects are shallow, meaning that the copy will refer - * to the same underlying cl_context as the original. For details, see - * clRetainContext() and clReleaseContext(). - * - * \see cl_context - */ -class Context - : public detail::Wrapper -{ -private: - -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED - static std::atomic default_initialized_; -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED - static volatile int default_initialized_; -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED - static Context default_; - static volatile cl_int default_error_; -public: - /*! \brief Constructs a context including a list of specified devices. - * - * Wraps clCreateContext(). - */ - Context( - const VECTOR_CLASS& devices, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - - ::size_t numDevices = devices.size(); - cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); - for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { - deviceIDs[deviceIndex] = (devices[deviceIndex])(); - } - - object_ = ::clCreateContext( - properties, (cl_uint) numDevices, - deviceIDs, - notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_ERR); - if (err != NULL) { - *err = error; - } - } - - Context( - const Device& device, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - - cl_device_id deviceID = device(); - - object_ = ::clCreateContext( - properties, 1, - &deviceID, - notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_ERR); - if (err != NULL) { - *err = error; - } - } - - /*! \brief Constructs a context including all or a subset of devices of a specified type. - * - * Wraps clCreateContextFromType(). - */ - Context( - cl_device_type type, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - -#if !defined(__APPLE__) && !defined(__MACOS) - cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 }; - - if (properties == NULL) { - // Get a valid platform ID as we cannot send in a blank one - VECTOR_CLASS platforms; - error = Platform::get(&platforms); - if (error != CL_SUCCESS) { - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - return; - } - - // Check the platforms we found for a device of our specified type - cl_context_properties platform_id = 0; - for (unsigned int i = 0; i < platforms.size(); i++) { - - VECTOR_CLASS devices; - -#if defined(__CL_ENABLE_EXCEPTIONS) - try { -#endif - - error = platforms[i].getDevices(type, &devices); - -#if defined(__CL_ENABLE_EXCEPTIONS) - } catch (Error) {} - // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type - // We do error checking next anyway, and can throw there if needed -#endif - - // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND - if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) { - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - } - - if (devices.size() > 0) { - platform_id = (cl_context_properties)platforms[i](); - break; - } - } - - if (platform_id == 0) { - detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = CL_DEVICE_NOT_FOUND; - } - return; - } - - prop[1] = platform_id; - properties = &prop[0]; - } -#endif - object_ = ::clCreateContextFromType( - properties, type, notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Context(const Context& ctx) : detail::Wrapper(ctx) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Context& operator = (const Context &ctx) - { - detail::Wrapper::operator=(ctx); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Context(Context&& ctx) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(ctx)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Context& operator = (Context &&ctx) - { - detail::Wrapper::operator=(std::move(ctx)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT. - * - * \note All calls to this function return the same cl_context as the first. - */ - static Context getDefault(cl_int * err = NULL) - { - int state = detail::compare_exchange( - &default_initialized_, - __DEFAULT_BEING_INITIALIZED, __DEFAULT_NOT_INITIALIZED); - - if (state & __DEFAULT_INITIALIZED) { - if (err != NULL) { - *err = default_error_; - } - return default_; - } - - if (state & __DEFAULT_BEING_INITIALIZED) { - // Assume writes will propagate eventually... - while(default_initialized_ != __DEFAULT_INITIALIZED) { - detail::fence(); - } - - if (err != NULL) { - *err = default_error_; - } - return default_; - } - - cl_int error; - default_ = Context( - CL_DEVICE_TYPE_DEFAULT, - NULL, - NULL, - NULL, - &error); - - detail::fence(); - - default_error_ = error; - // Assume writes will propagate eventually... - default_initialized_ = __DEFAULT_INITIALIZED; - - detail::fence(); - - if (err != NULL) { - *err = default_error_; - } - return default_; - - } - - //! \brief Default constructor - initializes to NULL. - Context() : detail::Wrapper() { } - - /*! \brief Constructor from cl_context - takes ownership. - * - * This effectively transfers ownership of a refcount on the cl_context - * into the new Context object. - */ - __CL_EXPLICIT_CONSTRUCTORS Context(const cl_context& context) : detail::Wrapper(context) { } - - /*! \brief Assignment operator from cl_context - takes ownership. - * - * This effectively transfers ownership of a refcount on the rhs and calls - * clReleaseContext() on the value previously held by this instance. - */ - Context& operator = (const cl_context& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - //! \brief Wrapper for clGetContextInfo(). - template - cl_int getInfo(cl_context_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetContextInfo, object_, name, param), - __GET_CONTEXT_INFO_ERR); - } - - //! \brief Wrapper for clGetContextInfo() that returns by value. - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_context_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - /*! \brief Gets a list of supported image formats. - * - * Wraps clGetSupportedImageFormats(). - */ - cl_int getSupportedImageFormats( - cl_mem_flags flags, - cl_mem_object_type type, - VECTOR_CLASS* formats) const - { - cl_uint numEntries; - cl_int err = ::clGetSupportedImageFormats( - object_, - flags, - type, - 0, - NULL, - &numEntries); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); - } - - ImageFormat* value = (ImageFormat*) - alloca(numEntries * sizeof(ImageFormat)); - err = ::clGetSupportedImageFormats( - object_, - flags, - type, - numEntries, - (cl_image_format*) value, - NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); - } - - formats->assign(&value[0], &value[numEntries]); - return CL_SUCCESS; - } -}; - -inline Device Device::getDefault(cl_int * err) -{ - cl_int error; - Device device; - - Context context = Context::getDefault(&error); - detail::errHandler(error, __CREATE_CONTEXT_ERR); - - if (error != CL_SUCCESS) { - if (err != NULL) { - *err = error; - } - } - else { - device = context.getInfo()[0]; - if (err != NULL) { - *err = CL_SUCCESS; - } - } - - return device; -} - - -#ifdef _WIN32 -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED -__declspec(selectany) std::atomic Context::default_initialized_; -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__declspec(selectany) volatile int Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED; -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__declspec(selectany) Context Context::default_; -__declspec(selectany) volatile cl_int Context::default_error_ = CL_SUCCESS; -#else // !_WIN32 -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED -__attribute__((weak)) std::atomic Context::default_initialized_; -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__attribute__((weak)) volatile int Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED; -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__attribute__((weak)) Context Context::default_; -__attribute__((weak)) volatile cl_int Context::default_error_ = CL_SUCCESS; -#endif // !_WIN32 - -/*! \brief Class interface for cl_event. - * - * \note Copies of these objects are shallow, meaning that the copy will refer - * to the same underlying cl_event as the original. For details, see - * clRetainEvent() and clReleaseEvent(). - * - * \see cl_event - */ -class Event : public detail::Wrapper -{ -public: - //! \brief Default constructor - initializes to NULL. - Event() : detail::Wrapper() { } - - /*! \brief Constructor from cl_event - takes ownership. - * - * This effectively transfers ownership of a refcount on the cl_event - * into the new Event object. - */ - __CL_EXPLICIT_CONSTRUCTORS Event(const cl_event& event) : detail::Wrapper(event) { } - - /*! \brief Assignment operator from cl_event - takes ownership. - * - * This effectively transfers ownership of a refcount on the rhs and calls - * clReleaseEvent() on the value previously held by this instance. - */ - Event& operator = (const cl_event& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - //! \brief Wrapper for clGetEventInfo(). - template - cl_int getInfo(cl_event_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetEventInfo, object_, name, param), - __GET_EVENT_INFO_ERR); - } - - //! \brief Wrapper for clGetEventInfo() that returns by value. - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_event_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - //! \brief Wrapper for clGetEventProfilingInfo(). - template - cl_int getProfilingInfo(cl_profiling_info name, T* param) const - { - return detail::errHandler(detail::getInfo( - &::clGetEventProfilingInfo, object_, name, param), - __GET_EVENT_PROFILE_INFO_ERR); - } - - //! \brief Wrapper for clGetEventProfilingInfo() that returns by value. - template typename - detail::param_traits::param_type - getProfilingInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_profiling_info, name>::param_type param; - cl_int result = getProfilingInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - /*! \brief Blocks the calling thread until this event completes. - * - * Wraps clWaitForEvents(). - */ - cl_int wait() const - { - return detail::errHandler( - ::clWaitForEvents(1, &object_), - __WAIT_FOR_EVENTS_ERR); - } - -#if defined(CL_VERSION_1_1) - /*! \brief Registers a user callback function for a specific command execution status. - * - * Wraps clSetEventCallback(). - */ - cl_int setCallback( - cl_int type, - void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *), - void * user_data = NULL) - { - return detail::errHandler( - ::clSetEventCallback( - object_, - type, - pfn_notify, - user_data), - __SET_EVENT_CALLBACK_ERR); - } -#endif - - /*! \brief Blocks the calling thread until every event specified is complete. - * - * Wraps clWaitForEvents(). - */ - static cl_int - waitForEvents(const VECTOR_CLASS& events) - { - return detail::errHandler( - ::clWaitForEvents( - (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : NULL), - __WAIT_FOR_EVENTS_ERR); - } -}; - -#if defined(CL_VERSION_1_1) -/*! \brief Class interface for user events (a subset of cl_event's). - * - * See Event for details about copy semantics, etc. - */ -class UserEvent : public Event -{ -public: - /*! \brief Constructs a user event on a given context. - * - * Wraps clCreateUserEvent(). - */ - UserEvent( - const Context& context, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateUserEvent( - context(), - &error); - - detail::errHandler(error, __CREATE_USER_EVENT_ERR); - if (err != NULL) { - *err = error; - } - } - - //! \brief Default constructor - initializes to NULL. - UserEvent() : Event() { } - - /*! \brief Sets the execution status of a user event object. - * - * Wraps clSetUserEventStatus(). - */ - cl_int setStatus(cl_int status) - { - return detail::errHandler( - ::clSetUserEventStatus(object_,status), - __SET_USER_EVENT_STATUS_ERR); - } -}; -#endif - -/*! \brief Blocks the calling thread until every event specified is complete. - * - * Wraps clWaitForEvents(). - */ -inline static cl_int -WaitForEvents(const VECTOR_CLASS& events) -{ - return detail::errHandler( - ::clWaitForEvents( - (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : NULL), - __WAIT_FOR_EVENTS_ERR); -} - -/*! \brief Class interface for cl_mem. - * - * \note Copies of these objects are shallow, meaning that the copy will refer - * to the same underlying cl_mem as the original. For details, see - * clRetainMemObject() and clReleaseMemObject(). - * - * \see cl_mem - */ -class Memory : public detail::Wrapper -{ -public: - //! \brief Default constructor - initializes to NULL. - Memory() : detail::Wrapper() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * This effectively transfers ownership of a refcount on the cl_mem - * into the new Memory object. - */ - __CL_EXPLICIT_CONSTRUCTORS Memory(const cl_mem& memory) : detail::Wrapper(memory) { } - - /*! \brief Assignment operator from cl_mem - takes ownership. - * - * This effectively transfers ownership of a refcount on the rhs and calls - * clReleaseMemObject() on the value previously held by this instance. - */ - Memory& operator = (const cl_mem& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Memory(const Memory& mem) : detail::Wrapper(mem) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Memory& operator = (const Memory &mem) - { - detail::Wrapper::operator=(mem); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Memory(Memory&& mem) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(mem)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Memory& operator = (Memory &&mem) - { - detail::Wrapper::operator=(std::move(mem)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - //! \brief Wrapper for clGetMemObjectInfo(). - template - cl_int getInfo(cl_mem_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetMemObjectInfo, object_, name, param), - __GET_MEM_OBJECT_INFO_ERR); - } - - //! \brief Wrapper for clGetMemObjectInfo() that returns by value. - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_mem_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - -#if defined(CL_VERSION_1_1) - /*! \brief Registers a callback function to be called when the memory object - * is no longer needed. - * - * Wraps clSetMemObjectDestructorCallback(). - * - * Repeated calls to this function, for a given cl_mem value, will append - * to the list of functions called (in reverse order) when memory object's - * resources are freed and the memory object is deleted. - * - * \note - * The registered callbacks are associated with the underlying cl_mem - * value - not the Memory class instance. - */ - cl_int setDestructorCallback( - void (CL_CALLBACK * pfn_notify)(cl_mem, void *), - void * user_data = NULL) - { - return detail::errHandler( - ::clSetMemObjectDestructorCallback( - object_, - pfn_notify, - user_data), - __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR); - } -#endif - -}; - -// Pre-declare copy functions -class Buffer; -template< typename IteratorType > -cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ); -template< typename IteratorType > -cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ); -template< typename IteratorType > -cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ); -template< typename IteratorType > -cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ); - - -/*! \brief Class interface for Buffer Memory Objects. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class Buffer : public Memory -{ -public: - - /*! \brief Constructs a Buffer in a specified context. - * - * Wraps clCreateBuffer(). - * - * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was - * specified. Note alignment & exclusivity requirements. - */ - Buffer( - const Context& context, - cl_mem_flags flags, - ::size_t size, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error); - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - /*! \brief Constructs a Buffer in the default context. - * - * Wraps clCreateBuffer(). - * - * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was - * specified. Note alignment & exclusivity requirements. - * - * \see Context::getDefault() - */ - Buffer( - cl_mem_flags flags, - ::size_t size, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - - Context context = Context::getDefault(err); - - object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error); - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - /*! - * \brief Construct a Buffer from a host container via iterators. - * IteratorType must be random access. - * If useHostPtr is specified iterators must represent contiguous data. - */ - template< typename IteratorType > - Buffer( - IteratorType startIterator, - IteratorType endIterator, - bool readOnly, - bool useHostPtr = false, - cl_int* err = NULL) - { - typedef typename std::iterator_traits::value_type DataType; - cl_int error; - - cl_mem_flags flags = 0; - if( readOnly ) { - flags |= CL_MEM_READ_ONLY; - } - else { - flags |= CL_MEM_READ_WRITE; - } - if( useHostPtr ) { - flags |= CL_MEM_USE_HOST_PTR; - } - - ::size_t size = sizeof(DataType)*(endIterator - startIterator); - - Context context = Context::getDefault(err); - - if( useHostPtr ) { - object_ = ::clCreateBuffer(context(), flags, size, static_cast(&*startIterator), &error); - } else { - object_ = ::clCreateBuffer(context(), flags, size, 0, &error); - } - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - - if( !useHostPtr ) { - error = cl::copy(startIterator, endIterator, *this); - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - } - - /*! - * \brief Construct a Buffer from a host container via iterators using a specified context. - * IteratorType must be random access. - * If useHostPtr is specified iterators must represent contiguous data. - */ - template< typename IteratorType > - Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator, - bool readOnly, bool useHostPtr = false, cl_int* err = NULL); - - /*! - * \brief Construct a Buffer from a host container via iterators using a specified queue. - * If useHostPtr is specified iterators must represent contiguous data. - */ - template< typename IteratorType > - Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, - bool readOnly, bool useHostPtr = false, cl_int* err = NULL); - - //! \brief Default constructor - initializes to NULL. - Buffer() : Memory() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Buffer(const cl_mem& buffer) : Memory(buffer) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Buffer& operator = (const cl_mem& rhs) - { - Memory::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Buffer(const Buffer& buf) : Memory(buf) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Buffer& operator = (const Buffer &buf) - { - Memory::operator=(buf); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Buffer(Buffer&& buf) CL_HPP_NOEXCEPT : Memory(std::move(buf)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Buffer& operator = (Buffer &&buf) - { - Memory::operator=(std::move(buf)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - -#if defined(CL_VERSION_1_1) - /*! \brief Creates a new buffer object from this. - * - * Wraps clCreateSubBuffer(). - */ - Buffer createSubBuffer( - cl_mem_flags flags, - cl_buffer_create_type buffer_create_type, - const void * buffer_create_info, - cl_int * err = NULL) - { - Buffer result; - cl_int error; - result.object_ = ::clCreateSubBuffer( - object_, - flags, - buffer_create_type, - buffer_create_info, - &error); - - detail::errHandler(error, __CREATE_SUBBUFFER_ERR); - if (err != NULL) { - *err = error; - } - - return result; - } -#endif -}; - -#if defined (USE_DX_INTEROP) -/*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's. - * - * This is provided to facilitate interoperability with Direct3D. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class BufferD3D10 : public Buffer -{ -public: - typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)( - cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer, - cl_int* errcode_ret); - - /*! \brief Constructs a BufferD3D10, in a specified context, from a - * given ID3D10Buffer. - * - * Wraps clCreateFromD3D10BufferKHR(). - */ - BufferD3D10( - const Context& context, - cl_mem_flags flags, - ID3D10Buffer* bufobj, - cl_int * err = NULL) - { - static PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR = NULL; - -#if defined(CL_VERSION_1_2) - vector props = context.getInfo(); - cl_platform platform = -1; - for( int i = 0; i < props.size(); ++i ) { - if( props[i] == CL_CONTEXT_PLATFORM ) { - platform = props[i+1]; - } - } - __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clCreateFromD3D10BufferKHR); -#endif -#if defined(CL_VERSION_1_1) - __INIT_CL_EXT_FCN_PTR(clCreateFromD3D10BufferKHR); -#endif - - cl_int error; - object_ = pfn_clCreateFromD3D10BufferKHR( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - //! \brief Default constructor - initializes to NULL. - BufferD3D10() : Buffer() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS BufferD3D10(const cl_mem& buffer) : Buffer(buffer) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - BufferD3D10& operator = (const cl_mem& rhs) - { - Buffer::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - BufferD3D10(const BufferD3D10& buf) : Buffer(buf) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - BufferD3D10& operator = (const BufferD3D10 &buf) - { - Buffer::operator=(buf); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - BufferD3D10(BufferD3D10&& buf) CL_HPP_NOEXCEPT : Buffer(std::move(buf)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - BufferD3D10& operator = (BufferD3D10 &&buf) - { - Buffer::operator=(std::move(buf)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; -#endif - -/*! \brief Class interface for GL Buffer Memory Objects. - * - * This is provided to facilitate interoperability with OpenGL. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class BufferGL : public Buffer -{ -public: - /*! \brief Constructs a BufferGL in a specified context, from a given - * GL buffer. - * - * Wraps clCreateFromGLBuffer(). - */ - BufferGL( - const Context& context, - cl_mem_flags flags, - cl_GLuint bufobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLBuffer( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - //! \brief Default constructor - initializes to NULL. - BufferGL() : Buffer() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS BufferGL(const cl_mem& buffer) : Buffer(buffer) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - BufferGL& operator = (const cl_mem& rhs) - { - Buffer::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - BufferGL(const BufferGL& buf) : Buffer(buf) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - BufferGL& operator = (const BufferGL &buf) - { - Buffer::operator=(buf); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - BufferGL(BufferGL&& buf) CL_HPP_NOEXCEPT : Buffer(std::move(buf)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - BufferGL& operator = (BufferGL &&buf) - { - Buffer::operator=(std::move(buf)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - //! \brief Wrapper for clGetGLObjectInfo(). - cl_int getObjectInfo( - cl_gl_object_type *type, - cl_GLuint * gl_object_name) - { - return detail::errHandler( - ::clGetGLObjectInfo(object_,type,gl_object_name), - __GET_GL_OBJECT_INFO_ERR); - } -}; - -/*! \brief C++ base class for Image Memory objects. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class Image : public Memory -{ -protected: - //! \brief Default constructor - initializes to NULL. - Image() : Memory() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Image(const cl_mem& image) : Memory(image) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Image& operator = (const cl_mem& rhs) - { - Memory::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image(const Image& img) : Memory(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image& operator = (const Image &img) - { - Memory::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image(Image&& img) CL_HPP_NOEXCEPT : Memory(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image& operator = (Image &&img) - { - Memory::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - -public: - //! \brief Wrapper for clGetImageInfo(). - template - cl_int getImageInfo(cl_image_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetImageInfo, object_, name, param), - __GET_IMAGE_INFO_ERR); - } - - //! \brief Wrapper for clGetImageInfo() that returns by value. - template typename - detail::param_traits::param_type - getImageInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_image_info, name>::param_type param; - cl_int result = getImageInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -}; - -#if defined(CL_VERSION_1_2) -/*! \brief Class interface for 1D Image Memory objects. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class Image1D : public Image -{ -public: - /*! \brief Constructs a 1D Image in a specified context. - * - * Wraps clCreateImage(). - */ - Image1D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - cl_image_desc desc = - { - CL_MEM_OBJECT_IMAGE1D, - width, - 0, 0, 0, 0, 0, 0, 0, 0 - }; - object_ = ::clCreateImage( - context(), - flags, - &format, - &desc, - host_ptr, - &error); - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - } - - //! \brief Default constructor - initializes to NULL. - Image1D() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Image1D(const cl_mem& image1D) : Image(image1D) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Image1D& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image1D(const Image1D& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image1D& operator = (const Image1D &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image1D(Image1D&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image1D& operator = (Image1D &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; - -/*! \class Image1DBuffer - * \brief Image interface for 1D buffer images. - */ -class Image1DBuffer : public Image -{ -public: - Image1DBuffer( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - const Buffer &buffer, - cl_int* err = NULL) - { - cl_int error; - cl_image_desc desc = - { - CL_MEM_OBJECT_IMAGE1D_BUFFER, - width, - 0, 0, 0, 0, 0, 0, 0, - buffer() - }; - object_ = ::clCreateImage( - context(), - flags, - &format, - &desc, - NULL, - &error); - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - } - - Image1DBuffer() { } - - __CL_EXPLICIT_CONSTRUCTORS Image1DBuffer(const cl_mem& image1D) : Image(image1D) { } - - Image1DBuffer& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image1DBuffer(const Image1DBuffer& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image1DBuffer& operator = (const Image1DBuffer &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image1DBuffer(Image1DBuffer&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image1DBuffer& operator = (Image1DBuffer &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; - -/*! \class Image1DArray - * \brief Image interface for arrays of 1D images. - */ -class Image1DArray : public Image -{ -public: - Image1DArray( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t arraySize, - ::size_t width, - ::size_t rowPitch, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - cl_image_desc desc = - { - CL_MEM_OBJECT_IMAGE1D_ARRAY, - width, - 0, 0, // height, depth (unused) - arraySize, - rowPitch, - 0, 0, 0, 0 - }; - object_ = ::clCreateImage( - context(), - flags, - &format, - &desc, - host_ptr, - &error); - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - } - - Image1DArray() { } - - __CL_EXPLICIT_CONSTRUCTORS Image1DArray(const cl_mem& imageArray) : Image(imageArray) { } - - Image1DArray& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image1DArray(const Image1DArray& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image1DArray& operator = (const Image1DArray &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image1DArray(Image1DArray&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image1DArray& operator = (Image1DArray &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; -#endif // #if defined(CL_VERSION_1_2) - - -/*! \brief Class interface for 2D Image Memory objects. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class Image2D : public Image -{ -public: - /*! \brief Constructs a 1D Image in a specified context. - * - * Wraps clCreateImage(). - */ - Image2D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - ::size_t height, - ::size_t row_pitch = 0, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - bool useCreateImage; - -#if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - // Run-time decision based on the actual platform - { - cl_uint version = detail::getContextPlatformVersion(context()); - useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above - } -#elif defined(CL_VERSION_1_2) - useCreateImage = true; -#else - useCreateImage = false; -#endif - -#if defined(CL_VERSION_1_2) - if (useCreateImage) - { - cl_image_desc desc = - { - CL_MEM_OBJECT_IMAGE2D, - width, - height, - 0, 0, // depth, array size (unused) - row_pitch, - 0, 0, 0, 0 - }; - object_ = ::clCreateImage( - context(), - flags, - &format, - &desc, - host_ptr, - &error); - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - } -#endif // #if defined(CL_VERSION_1_2) -#if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - if (!useCreateImage) - { - object_ = ::clCreateImage2D( - context(), flags,&format, width, height, row_pitch, host_ptr, &error); - - detail::errHandler(error, __CREATE_IMAGE2D_ERR); - if (err != NULL) { - *err = error; - } - } -#endif // #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - } - - //! \brief Default constructor - initializes to NULL. - Image2D() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Image2D(const cl_mem& image2D) : Image(image2D) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Image2D& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image2D(const Image2D& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image2D& operator = (const Image2D &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image2D(Image2D&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image2D& operator = (Image2D &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; - - -#if !defined(CL_VERSION_1_2) -/*! \brief Class interface for GL 2D Image Memory objects. - * - * This is provided to facilitate interoperability with OpenGL. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - * \note Deprecated for OpenCL 1.2. Please use ImageGL instead. - */ -class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED Image2DGL CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED : public Image2D -{ -public: - /*! \brief Constructs an Image2DGL in a specified context, from a given - * GL Texture. - * - * Wraps clCreateFromGLTexture2D(). - */ - Image2DGL( - const Context& context, - cl_mem_flags flags, - cl_GLenum target, - cl_GLint miplevel, - cl_GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture2D( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR); - if (err != NULL) { - *err = error; - } - - } - - //! \brief Default constructor - initializes to NULL. - Image2DGL() : Image2D() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Image2DGL(const cl_mem& image) : Image2D(image) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Image2DGL& operator = (const cl_mem& rhs) - { - Image2D::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image2DGL(const Image2DGL& img) : Image2D(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image2DGL& operator = (const Image2DGL &img) - { - Image2D::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image2DGL(Image2DGL&& img) CL_HPP_NOEXCEPT : Image2D(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image2DGL& operator = (Image2DGL &&img) - { - Image2D::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; -#endif // #if !defined(CL_VERSION_1_2) - -#if defined(CL_VERSION_1_2) -/*! \class Image2DArray - * \brief Image interface for arrays of 2D images. - */ -class Image2DArray : public Image -{ -public: - Image2DArray( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t arraySize, - ::size_t width, - ::size_t height, - ::size_t rowPitch, - ::size_t slicePitch, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - cl_image_desc desc = - { - CL_MEM_OBJECT_IMAGE2D_ARRAY, - width, - height, - 0, // depth (unused) - arraySize, - rowPitch, - slicePitch, - 0, 0, 0 - }; - object_ = ::clCreateImage( - context(), - flags, - &format, - &desc, - host_ptr, - &error); - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - } - - Image2DArray() { } - - __CL_EXPLICIT_CONSTRUCTORS Image2DArray(const cl_mem& imageArray) : Image(imageArray) { } - - Image2DArray& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image2DArray(const Image2DArray& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image2DArray& operator = (const Image2DArray &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image2DArray(Image2DArray&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image2DArray& operator = (Image2DArray &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; -#endif // #if defined(CL_VERSION_1_2) - -/*! \brief Class interface for 3D Image Memory objects. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class Image3D : public Image -{ -public: - /*! \brief Constructs a 3D Image in a specified context. - * - * Wraps clCreateImage(). - */ - Image3D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - ::size_t height, - ::size_t depth, - ::size_t row_pitch = 0, - ::size_t slice_pitch = 0, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - bool useCreateImage; - -#if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - // Run-time decision based on the actual platform - { - cl_uint version = detail::getContextPlatformVersion(context()); - useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above - } -#elif defined(CL_VERSION_1_2) - useCreateImage = true; -#else - useCreateImage = false; -#endif - -#if defined(CL_VERSION_1_2) - if (useCreateImage) - { - cl_image_desc desc = - { - CL_MEM_OBJECT_IMAGE3D, - width, - height, - depth, - 0, // array size (unused) - row_pitch, - slice_pitch, - 0, 0, 0 - }; - object_ = ::clCreateImage( - context(), - flags, - &format, - &desc, - host_ptr, - &error); - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - } -#endif // #if defined(CL_VERSION_1_2) -#if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - if (!useCreateImage) - { - object_ = ::clCreateImage3D( - context(), flags, &format, width, height, depth, row_pitch, - slice_pitch, host_ptr, &error); - - detail::errHandler(error, __CREATE_IMAGE3D_ERR); - if (err != NULL) { - *err = error; - } - } -#endif // #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) - } - - //! \brief Default constructor - initializes to NULL. - Image3D() : Image() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Image3D(const cl_mem& image3D) : Image(image3D) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Image3D& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image3D(const Image3D& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image3D& operator = (const Image3D &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image3D(Image3D&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image3D& operator = (Image3D &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; - -#if !defined(CL_VERSION_1_2) -/*! \brief Class interface for GL 3D Image Memory objects. - * - * This is provided to facilitate interoperability with OpenGL. - * - * See Memory for details about copy semantics, etc. - * - * \see Memory - */ -class Image3DGL : public Image3D -{ -public: - /*! \brief Constructs an Image3DGL in a specified context, from a given - * GL Texture. - * - * Wraps clCreateFromGLTexture3D(). - */ - Image3DGL( - const Context& context, - cl_mem_flags flags, - cl_GLenum target, - cl_GLint miplevel, - cl_GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture3D( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR); - if (err != NULL) { - *err = error; - } - } - - //! \brief Default constructor - initializes to NULL. - Image3DGL() : Image3D() { } - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ - __CL_EXPLICIT_CONSTRUCTORS Image3DGL(const cl_mem& image) : Image3D(image) { } - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - Image3DGL& operator = (const cl_mem& rhs) - { - Image3D::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image3DGL(const Image3DGL& img) : Image3D(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Image3DGL& operator = (const Image3DGL &img) - { - Image3D::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Image3DGL(Image3DGL&& img) CL_HPP_NOEXCEPT : Image3D(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Image3DGL& operator = (Image3DGL &&img) - { - Image3D::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; -#endif // #if !defined(CL_VERSION_1_2) - -#if defined(CL_VERSION_1_2) -/*! \class ImageGL - * \brief general image interface for GL interop. - * We abstract the 2D and 3D GL images into a single instance here - * that wraps all GL sourced images on the grounds that setup information - * was performed by OpenCL anyway. - */ -class ImageGL : public Image -{ -public: - ImageGL( - const Context& context, - cl_mem_flags flags, - cl_GLenum target, - cl_GLint miplevel, - cl_GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_TEXTURE_ERR); - if (err != NULL) { - *err = error; - } - } - - ImageGL() : Image() { } - - __CL_EXPLICIT_CONSTRUCTORS ImageGL(const cl_mem& image) : Image(image) { } - - ImageGL& operator = (const cl_mem& rhs) - { - Image::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - ImageGL(const ImageGL& img) : Image(img) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - ImageGL& operator = (const ImageGL &img) - { - Image::operator=(img); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - ImageGL(ImageGL&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - ImageGL& operator = (ImageGL &&img) - { - Image::operator=(std::move(img)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) -}; -#endif // #if defined(CL_VERSION_1_2) - -/*! \brief Class interface for GL Render Buffer Memory Objects. -* -* This is provided to facilitate interoperability with OpenGL. -* -* See Memory for details about copy semantics, etc. -* -* \see Memory -*/ -class BufferRenderGL : -#if defined(CL_VERSION_1_2) - public ImageGL -#else // #if defined(CL_VERSION_1_2) - public Image2DGL -#endif //#if defined(CL_VERSION_1_2) -{ -public: - /*! \brief Constructs a BufferRenderGL in a specified context, from a given - * GL Renderbuffer. - * - * Wraps clCreateFromGLRenderbuffer(). - */ - BufferRenderGL( - const Context& context, - cl_mem_flags flags, - cl_GLuint bufobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLRenderbuffer( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - //! \brief Default constructor - initializes to NULL. -#if defined(CL_VERSION_1_2) - BufferRenderGL() : ImageGL() {}; -#else // #if defined(CL_VERSION_1_2) - BufferRenderGL() : Image2DGL() {}; -#endif //#if defined(CL_VERSION_1_2) - - /*! \brief Constructor from cl_mem - takes ownership. - * - * See Memory for further details. - */ -#if defined(CL_VERSION_1_2) - __CL_EXPLICIT_CONSTRUCTORS BufferRenderGL(const cl_mem& buffer) : ImageGL(buffer) { } -#else // #if defined(CL_VERSION_1_2) - __CL_EXPLICIT_CONSTRUCTORS BufferRenderGL(const cl_mem& buffer) : Image2DGL(buffer) { } -#endif //#if defined(CL_VERSION_1_2) - - - /*! \brief Assignment from cl_mem - performs shallow copy. - * - * See Memory for further details. - */ - BufferRenderGL& operator = (const cl_mem& rhs) - { -#if defined(CL_VERSION_1_2) - ImageGL::operator=(rhs); -#else // #if defined(CL_VERSION_1_2) - Image2DGL::operator=(rhs); -#endif //#if defined(CL_VERSION_1_2) - - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ -#if defined(CL_VERSION_1_2) - BufferRenderGL(const BufferRenderGL& buf) : ImageGL(buf) {} -#else // #if defined(CL_VERSION_1_2) - BufferRenderGL(const BufferRenderGL& buf) : Image2DGL(buf) {} -#endif //#if defined(CL_VERSION_1_2) - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - BufferRenderGL& operator = (const BufferRenderGL &rhs) - { -#if defined(CL_VERSION_1_2) - ImageGL::operator=(rhs); -#else // #if defined(CL_VERSION_1_2) - Image2DGL::operator=(rhs); -#endif //#if defined(CL_VERSION_1_2) - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ -#if defined(CL_VERSION_1_2) - BufferRenderGL(BufferRenderGL&& buf) CL_HPP_NOEXCEPT : ImageGL(std::move(buf)) {} -#else // #if defined(CL_VERSION_1_2) - BufferRenderGL(BufferRenderGL&& buf) CL_HPP_NOEXCEPT : Image2DGL(std::move(buf)) {} -#endif //#if defined(CL_VERSION_1_2) - - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - BufferRenderGL& operator = (BufferRenderGL &&buf) - { -#if defined(CL_VERSION_1_2) - ImageGL::operator=(std::move(buf)); -#else // #if defined(CL_VERSION_1_2) - Image2DGL::operator=(std::move(buf)); -#endif //#if defined(CL_VERSION_1_2) - - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - //! \brief Wrapper for clGetGLObjectInfo(). - cl_int getObjectInfo( - cl_gl_object_type *type, - cl_GLuint * gl_object_name) - { - return detail::errHandler( - ::clGetGLObjectInfo(object_, type, gl_object_name), - __GET_GL_OBJECT_INFO_ERR); - } -}; - -/*! \brief Class interface for cl_sampler. - * - * \note Copies of these objects are shallow, meaning that the copy will refer - * to the same underlying cl_sampler as the original. For details, see - * clRetainSampler() and clReleaseSampler(). - * - * \see cl_sampler - */ -class Sampler : public detail::Wrapper -{ -public: - //! \brief Default constructor - initializes to NULL. - Sampler() { } - - /*! \brief Constructs a Sampler in a specified context. - * - * Wraps clCreateSampler(). - */ - Sampler( - const Context& context, - cl_bool normalized_coords, - cl_addressing_mode addressing_mode, - cl_filter_mode filter_mode, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateSampler( - context(), - normalized_coords, - addressing_mode, - filter_mode, - &error); - - detail::errHandler(error, __CREATE_SAMPLER_ERR); - if (err != NULL) { - *err = error; - } - } - - /*! \brief Constructor from cl_sampler - takes ownership. - * - * This effectively transfers ownership of a refcount on the cl_sampler - * into the new Sampler object. - */ - __CL_EXPLICIT_CONSTRUCTORS Sampler(const cl_sampler& sampler) : detail::Wrapper(sampler) { } - - /*! \brief Assignment operator from cl_sampler - takes ownership. - * - * This effectively transfers ownership of a refcount on the rhs and calls - * clReleaseSampler() on the value previously held by this instance. - */ - Sampler& operator = (const cl_sampler& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Sampler(const Sampler& sam) : detail::Wrapper(sam) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Sampler& operator = (const Sampler &sam) - { - detail::Wrapper::operator=(sam); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Sampler(Sampler&& sam) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(sam)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Sampler& operator = (Sampler &&sam) - { - detail::Wrapper::operator=(std::move(sam)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - //! \brief Wrapper for clGetSamplerInfo(). - template - cl_int getInfo(cl_sampler_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetSamplerInfo, object_, name, param), - __GET_SAMPLER_INFO_ERR); - } - - //! \brief Wrapper for clGetSamplerInfo() that returns by value. - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_sampler_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -}; - -class Program; -class CommandQueue; -class Kernel; - -//! \brief Class interface for specifying NDRange values. -class NDRange -{ -private: - size_t<3> sizes_; - cl_uint dimensions_; - -public: - //! \brief Default constructor - resulting range has zero dimensions. - NDRange() - : dimensions_(0) - { } - - //! \brief Constructs one-dimensional range. - NDRange(::size_t size0) - : dimensions_(1) - { - sizes_[0] = size0; - } - - //! \brief Constructs two-dimensional range. - NDRange(::size_t size0, ::size_t size1) - : dimensions_(2) - { - sizes_[0] = size0; - sizes_[1] = size1; - } - - //! \brief Constructs three-dimensional range. - NDRange(::size_t size0, ::size_t size1, ::size_t size2) - : dimensions_(3) - { - sizes_[0] = size0; - sizes_[1] = size1; - sizes_[2] = size2; - } - - /*! \brief Conversion operator to const ::size_t *. - * - * \returns a pointer to the size of the first dimension. - */ - operator const ::size_t*() const { - return (const ::size_t*) sizes_; - } - - //! \brief Queries the number of dimensions in the range. - ::size_t dimensions() const { return dimensions_; } -}; - -//! \brief A zero-dimensional range. -static const NDRange NullRange; - -//! \brief Local address wrapper for use with Kernel::setArg -struct LocalSpaceArg -{ - ::size_t size_; -}; - -namespace detail { - -template -struct KernelArgumentHandler -{ - static ::size_t size(const T&) { return sizeof(T); } - static const T* ptr(const T& value) { return &value; } -}; - -template <> -struct KernelArgumentHandler -{ - static ::size_t size(const LocalSpaceArg& value) { return value.size_; } - static const void* ptr(const LocalSpaceArg&) { return NULL; } -}; - -} -//! \endcond - -/*! __local - * \brief Helper function for generating LocalSpaceArg objects. - * Deprecated. Replaced with Local. - */ -inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED LocalSpaceArg -__local(::size_t size) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; -inline LocalSpaceArg -__local(::size_t size) -{ - LocalSpaceArg ret = { size }; - return ret; -} - -/*! Local - * \brief Helper function for generating LocalSpaceArg objects. - */ -inline LocalSpaceArg -Local(::size_t size) -{ - LocalSpaceArg ret = { size }; - return ret; -} - -//class KernelFunctor; - -/*! \brief Class interface for cl_kernel. - * - * \note Copies of these objects are shallow, meaning that the copy will refer - * to the same underlying cl_kernel as the original. For details, see - * clRetainKernel() and clReleaseKernel(). - * - * \see cl_kernel - */ -class Kernel : public detail::Wrapper -{ -public: - inline Kernel(const Program& program, const char* name, cl_int* err = NULL); - - //! \brief Default constructor - initializes to NULL. - Kernel() { } - - /*! \brief Constructor from cl_kernel - takes ownership. - * - * This effectively transfers ownership of a refcount on the cl_kernel - * into the new Kernel object. - */ - __CL_EXPLICIT_CONSTRUCTORS Kernel(const cl_kernel& kernel) : detail::Wrapper(kernel) { } - - /*! \brief Assignment operator from cl_kernel - takes ownership. - * - * This effectively transfers ownership of a refcount on the rhs and calls - * clReleaseKernel() on the value previously held by this instance. - */ - Kernel& operator = (const cl_kernel& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Kernel(const Kernel& kernel) : detail::Wrapper(kernel) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Kernel& operator = (const Kernel &kernel) - { - detail::Wrapper::operator=(kernel); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Kernel(Kernel&& kernel) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(kernel)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Kernel& operator = (Kernel &&kernel) - { - detail::Wrapper::operator=(std::move(kernel)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - template - cl_int getInfo(cl_kernel_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetKernelInfo, object_, name, param), - __GET_KERNEL_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - -#if defined(CL_VERSION_1_2) - template - cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param), - __GET_KERNEL_ARG_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getArgInfo(cl_uint argIndex, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_arg_info, name>::param_type param; - cl_int result = getArgInfo(argIndex, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -#endif // #if defined(CL_VERSION_1_2) - - template - cl_int getWorkGroupInfo( - const Device& device, cl_kernel_work_group_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetKernelWorkGroupInfo, object_, device(), name, param), - __GET_KERNEL_WORK_GROUP_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getWorkGroupInfo(const Device& device, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_work_group_info, name>::param_type param; - cl_int result = getWorkGroupInfo(device, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int setArg(cl_uint index, const T &value) - { - return detail::errHandler( - ::clSetKernelArg( - object_, - index, - detail::KernelArgumentHandler::size(value), - detail::KernelArgumentHandler::ptr(value)), - __SET_KERNEL_ARGS_ERR); - } - - cl_int setArg(cl_uint index, ::size_t size, const void* argPtr) - { - return detail::errHandler( - ::clSetKernelArg(object_, index, size, argPtr), - __SET_KERNEL_ARGS_ERR); - } -}; - -/*! \class Program - * \brief Program interface that implements cl_program. - */ -class Program : public detail::Wrapper -{ -public: - typedef VECTOR_CLASS > Binaries; - typedef VECTOR_CLASS > Sources; - - Program( - const STRING_CLASS& source, - bool build = false, - cl_int* err = NULL) - { - cl_int error; - - const char * strings = source.c_str(); - const ::size_t length = source.size(); - - Context context = Context::getDefault(err); - - object_ = ::clCreateProgramWithSource( - context(), (cl_uint)1, &strings, &length, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); - - if (error == CL_SUCCESS && build) { - - error = ::clBuildProgram( - object_, - 0, - NULL, - "", - NULL, - NULL); - - detail::errHandler(error, __BUILD_PROGRAM_ERR); - } - - if (err != NULL) { - *err = error; - } - } - - Program( - const Context& context, - const STRING_CLASS& source, - bool build = false, - cl_int* err = NULL) - { - cl_int error; - - const char * strings = source.c_str(); - const ::size_t length = source.size(); - - object_ = ::clCreateProgramWithSource( - context(), (cl_uint)1, &strings, &length, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); - - if (error == CL_SUCCESS && build) { - - error = ::clBuildProgram( - object_, - 0, - NULL, - "", - NULL, - NULL); - - detail::errHandler(error, __BUILD_PROGRAM_ERR); - } - - if (err != NULL) { - *err = error; - } - } - - Program( - const Context& context, - const Sources& sources, - cl_int* err = NULL) - { - cl_int error; - - const ::size_t n = (::size_t)sources.size(); - ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t)); - const char** strings = (const char**) alloca(n * sizeof(const char*)); - - for (::size_t i = 0; i < n; ++i) { - strings[i] = sources[(int)i].first; - lengths[i] = sources[(int)i].second; - } - - object_ = ::clCreateProgramWithSource( - context(), (cl_uint)n, strings, lengths, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); - if (err != NULL) { - *err = error; - } - } - - /** - * Construct a program object from a list of devices and a per-device list of binaries. - * \param context A valid OpenCL context in which to construct the program. - * \param devices A vector of OpenCL device objects for which the program will be created. - * \param binaries A vector of pairs of a pointer to a binary object and its length. - * \param binaryStatus An optional vector that on completion will be resized to - * match the size of binaries and filled with values to specify if each binary - * was successfully loaded. - * Set to CL_SUCCESS if the binary was successfully loaded. - * Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is NULL. - * Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device. - * \param err if non-NULL will be set to CL_SUCCESS on successful operation or one of the following errors: - * CL_INVALID_CONTEXT if context is not a valid context. - * CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices; - * or if any entry in binaries is NULL or has length 0. - * CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context. - * CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device. - * CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host. - */ - Program( - const Context& context, - const VECTOR_CLASS& devices, - const Binaries& binaries, - VECTOR_CLASS* binaryStatus = NULL, - cl_int* err = NULL) - { - cl_int error; - - const ::size_t numDevices = devices.size(); - - // Catch size mismatch early and return - if(binaries.size() != numDevices) { - error = CL_INVALID_VALUE; - detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); - if (err != NULL) { - *err = error; - } - return; - } - - ::size_t* lengths = (::size_t*) alloca(numDevices * sizeof(::size_t)); - const unsigned char** images = (const unsigned char**) alloca(numDevices * sizeof(const unsigned char**)); - - for (::size_t i = 0; i < numDevices; ++i) { - images[i] = (const unsigned char*)binaries[i].first; - lengths[i] = binaries[(int)i].second; - } - - cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); - for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { - deviceIDs[deviceIndex] = (devices[deviceIndex])(); - } - - if(binaryStatus) { - binaryStatus->resize(numDevices); - } - - object_ = ::clCreateProgramWithBinary( - context(), (cl_uint) devices.size(), - deviceIDs, - lengths, images, (binaryStatus != NULL && numDevices > 0) - ? &binaryStatus->front() - : NULL, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); - if (err != NULL) { - *err = error; - } - } - - -#if defined(CL_VERSION_1_2) - /** - * Create program using builtin kernels. - * \param kernelNames Semi-colon separated list of builtin kernel names - */ - Program( - const Context& context, - const VECTOR_CLASS& devices, - const STRING_CLASS& kernelNames, - cl_int* err = NULL) - { - cl_int error; - - - ::size_t numDevices = devices.size(); - cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); - for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { - deviceIDs[deviceIndex] = (devices[deviceIndex])(); - } - - object_ = ::clCreateProgramWithBuiltInKernels( - context(), - (cl_uint) devices.size(), - deviceIDs, - kernelNames.c_str(), - &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR); - if (err != NULL) { - *err = error; - } - } -#endif // #if defined(CL_VERSION_1_2) - - Program() { } - - __CL_EXPLICIT_CONSTRUCTORS Program(const cl_program& program) : detail::Wrapper(program) { } - - Program& operator = (const cl_program& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - Program(const Program& program) : detail::Wrapper(program) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - Program& operator = (const Program &program) - { - detail::Wrapper::operator=(program); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - Program(Program&& program) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(program)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - Program& operator = (Program &&program) - { - detail::Wrapper::operator=(std::move(program)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - cl_int build( - const VECTOR_CLASS& devices, - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL) const - { - ::size_t numDevices = devices.size(); - cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); - for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { - deviceIDs[deviceIndex] = (devices[deviceIndex])(); - } - - return detail::errHandler( - ::clBuildProgram( - object_, - (cl_uint) - devices.size(), - deviceIDs, - options, - notifyFptr, - data), - __BUILD_PROGRAM_ERR); - } - - cl_int build( - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL) const - { - return detail::errHandler( - ::clBuildProgram( - object_, - 0, - NULL, - options, - notifyFptr, - data), - __BUILD_PROGRAM_ERR); - } - -#if defined(CL_VERSION_1_2) - cl_int compile( - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL) const - { - return detail::errHandler( - ::clCompileProgram( - object_, - 0, - NULL, - options, - 0, - NULL, - NULL, - notifyFptr, - data), - __COMPILE_PROGRAM_ERR); - } -#endif - - template - cl_int getInfo(cl_program_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetProgramInfo, object_, name, param), - __GET_PROGRAM_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_program_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getBuildInfo( - const Device& device, cl_program_build_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetProgramBuildInfo, object_, device(), name, param), - __GET_PROGRAM_BUILD_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getBuildInfo(const Device& device, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_program_build_info, name>::param_type param; - cl_int result = getBuildInfo(device, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int createKernels(VECTOR_CLASS* kernels) - { - cl_uint numKernels; - cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); - } - - Kernel* value = (Kernel*) alloca(numKernels * sizeof(Kernel)); - err = ::clCreateKernelsInProgram( - object_, numKernels, (cl_kernel*) value, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); - } - - kernels->assign(&value[0], &value[numKernels]); - return CL_SUCCESS; - } -}; - -#if defined(CL_VERSION_1_2) -inline Program linkProgram( - Program input1, - Program input2, - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL, - cl_int* err = NULL) -{ - cl_int error_local = CL_SUCCESS; - - cl_program programs[2] = { input1(), input2() }; - - Context ctx = input1.getInfo(&error_local); - if(error_local!=CL_SUCCESS) { - detail::errHandler(error_local, __LINK_PROGRAM_ERR); - } - - cl_program prog = ::clLinkProgram( - ctx(), - 0, - NULL, - options, - 2, - programs, - notifyFptr, - data, - &error_local); - - detail::errHandler(error_local,__COMPILE_PROGRAM_ERR); - if (err != NULL) { - *err = error_local; - } - - return Program(prog); -} - -inline Program linkProgram( - VECTOR_CLASS inputPrograms, - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL, - cl_int* err = NULL) -{ - cl_int error_local = CL_SUCCESS; - - cl_program * programs = (cl_program*) alloca(inputPrograms.size() * sizeof(cl_program)); - - if (programs != NULL) { - for (unsigned int i = 0; i < inputPrograms.size(); i++) { - programs[i] = inputPrograms[i](); - } - } - - Context ctx; - if(inputPrograms.size() > 0) { - ctx = inputPrograms[0].getInfo(&error_local); - if(error_local!=CL_SUCCESS) { - detail::errHandler(error_local, __LINK_PROGRAM_ERR); - } - } - cl_program prog = ::clLinkProgram( - ctx(), - 0, - NULL, - options, - (cl_uint)inputPrograms.size(), - programs, - notifyFptr, - data, - &error_local); - - detail::errHandler(error_local,__COMPILE_PROGRAM_ERR); - if (err != NULL) { - *err = error_local; - } - - return Program(prog); -} -#endif - -template<> -inline VECTOR_CLASS cl::Program::getInfo(cl_int* err) const -{ - VECTOR_CLASS< ::size_t> sizes = getInfo(); - VECTOR_CLASS binaries; - for (VECTOR_CLASS< ::size_t>::iterator s = sizes.begin(); s != sizes.end(); ++s) - { - char *ptr = NULL; - if (*s != 0) - ptr = new char[*s]; - binaries.push_back(ptr); - } - - cl_int result = getInfo(CL_PROGRAM_BINARIES, &binaries); - if (err != NULL) { - *err = result; - } - return binaries; -} - -inline Kernel::Kernel(const Program& program, const char* name, cl_int* err) -{ - cl_int error; - - object_ = ::clCreateKernel(program(), name, &error); - detail::errHandler(error, __CREATE_KERNEL_ERR); - - if (err != NULL) { - *err = error; - } - -} - -/*! \class CommandQueue - * \brief CommandQueue interface for cl_command_queue. - */ -class CommandQueue : public detail::Wrapper -{ -private: -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED - static std::atomic default_initialized_; -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED - static volatile int default_initialized_; -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED - static CommandQueue default_; - static volatile cl_int default_error_; -public: - CommandQueue( - cl_command_queue_properties properties, - cl_int* err = NULL) - { - cl_int error; - - Context context = Context::getDefault(&error); - detail::errHandler(error, __CREATE_CONTEXT_ERR); - - if (error != CL_SUCCESS) { - if (err != NULL) { - *err = error; - } - } - else { - Device device = context.getInfo()[0]; - - object_ = ::clCreateCommandQueue( - context(), device(), properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } - } - } - /*! - * \brief Constructs a CommandQueue for an implementation defined device in the given context - */ - explicit CommandQueue( - const Context& context, - cl_command_queue_properties properties = 0, - cl_int* err = NULL) - { - cl_int error; - VECTOR_CLASS devices; - error = context.getInfo(CL_CONTEXT_DEVICES, &devices); - - detail::errHandler(error, __CREATE_CONTEXT_ERR); - - if (error != CL_SUCCESS) - { - if (err != NULL) { - *err = error; - } - return; - } - - object_ = ::clCreateCommandQueue(context(), devices[0](), properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - - if (err != NULL) { - *err = error; - } - - } - - CommandQueue( - const Context& context, - const Device& device, - cl_command_queue_properties properties = 0, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateCommandQueue( - context(), device(), properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } - } - - /*! \brief Copy constructor to forward copy to the superclass correctly. - * Required for MSVC. - */ - CommandQueue(const CommandQueue& queue) : detail::Wrapper(queue) {} - - /*! \brief Copy assignment to forward copy to the superclass correctly. - * Required for MSVC. - */ - CommandQueue& operator = (const CommandQueue &queue) - { - detail::Wrapper::operator=(queue); - return *this; - } - -#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - /*! \brief Move constructor to forward move to the superclass correctly. - * Required for MSVC. - */ - CommandQueue(CommandQueue&& queue) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(queue)) {} - - /*! \brief Move assignment to forward move to the superclass correctly. - * Required for MSVC. - */ - CommandQueue& operator = (CommandQueue &&queue) - { - detail::Wrapper::operator=(std::move(queue)); - return *this; - } -#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) - - static CommandQueue getDefault(cl_int * err = NULL) - { - int state = detail::compare_exchange( - &default_initialized_, - __DEFAULT_BEING_INITIALIZED, __DEFAULT_NOT_INITIALIZED); - - if (state & __DEFAULT_INITIALIZED) { - if (err != NULL) { - *err = default_error_; - } - return default_; - } - - if (state & __DEFAULT_BEING_INITIALIZED) { - // Assume writes will propagate eventually... - while(default_initialized_ != __DEFAULT_INITIALIZED) { - detail::fence(); - } - - if (err != NULL) { - *err = default_error_; - } - return default_; - } - - cl_int error; - - Context context = Context::getDefault(&error); - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - - if (error != CL_SUCCESS) { - if (err != NULL) { - *err = error; - } - } - else { - Device device = context.getInfo()[0]; - - default_ = CommandQueue(context, device, 0, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } - } - - detail::fence(); - - default_error_ = error; - // Assume writes will propagate eventually... - default_initialized_ = __DEFAULT_INITIALIZED; - - detail::fence(); - - if (err != NULL) { - *err = default_error_; - } - return default_; - - } - - CommandQueue() { } - - __CL_EXPLICIT_CONSTRUCTORS CommandQueue(const cl_command_queue& commandQueue) : detail::Wrapper(commandQueue) { } - - CommandQueue& operator = (const cl_command_queue& rhs) - { - detail::Wrapper::operator=(rhs); - return *this; - } - - template - cl_int getInfo(cl_command_queue_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetCommandQueueInfo, object_, name, param), - __GET_COMMAND_QUEUE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_command_queue_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int enqueueReadBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueReadBuffer( - object_, buffer(), blocking, offset, size, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_READ_BUFFER_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueWriteBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - const void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueWriteBuffer( - object_, buffer(), blocking, offset, size, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_WRITE_BUFFER_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueCopyBuffer( - const Buffer& src, - const Buffer& dst, - ::size_t src_offset, - ::size_t dst_offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueCopyBuffer( - object_, src(), dst(), src_offset, dst_offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQEUE_COPY_BUFFER_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueReadBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueReadBufferRect( - object_, - buffer(), - blocking, - (const ::size_t *)buffer_offset, - (const ::size_t *)host_offset, - (const ::size_t *)region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_READ_BUFFER_RECT_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueWriteBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueWriteBufferRect( - object_, - buffer(), - blocking, - (const ::size_t *)buffer_offset, - (const ::size_t *)host_offset, - (const ::size_t *)region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_WRITE_BUFFER_RECT_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueCopyBufferRect( - const Buffer& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - ::size_t src_row_pitch, - ::size_t src_slice_pitch, - ::size_t dst_row_pitch, - ::size_t dst_slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueCopyBufferRect( - object_, - src(), - dst(), - (const ::size_t *)src_origin, - (const ::size_t *)dst_origin, - (const ::size_t *)region, - src_row_pitch, - src_slice_pitch, - dst_row_pitch, - dst_slice_pitch, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQEUE_COPY_BUFFER_RECT_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - -#if defined(CL_VERSION_1_2) - /** - * Enqueue a command to fill a buffer object with a pattern - * of a given size. The pattern is specified a as vector. - * \tparam PatternType The datatype of the pattern field. - * The pattern type must be an accepted OpenCL data type. - */ - template - cl_int enqueueFillBuffer( - const Buffer& buffer, - PatternType pattern, - ::size_t offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueFillBuffer( - object_, - buffer(), - static_cast(&pattern), - sizeof(PatternType), - offset, - size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_FILL_BUFFER_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } -#endif // #if defined(CL_VERSION_1_2) - - cl_int enqueueReadImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueReadImage( - object_, image(), blocking, (const ::size_t *) origin, - (const ::size_t *) region, row_pitch, slice_pitch, ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_READ_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueWriteImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueWriteImage( - object_, image(), blocking, (const ::size_t *) origin, - (const ::size_t *) region, row_pitch, slice_pitch, ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_WRITE_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueCopyImage( - const Image& src, - const Image& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueCopyImage( - object_, src(), dst(), (const ::size_t *) src_origin, - (const ::size_t *)dst_origin, (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_COPY_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - -#if defined(CL_VERSION_1_2) - /** - * Enqueue a command to fill an image object with a specified color. - * \param fillColor is the color to use to fill the image. - * This is a four component RGBA floating-point color value if - * the image channel data type is not an unnormalized signed or - * unsigned data type. - */ - cl_int enqueueFillImage( - const Image& image, - cl_float4 fillColor, - const size_t<3>& origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueFillImage( - object_, - image(), - static_cast(&fillColor), - (const ::size_t *) origin, - (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_FILL_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - /** - * Enqueue a command to fill an image object with a specified color. - * \param fillColor is the color to use to fill the image. - * This is a four component RGBA signed integer color value if - * the image channel data type is an unnormalized signed integer - * type. - */ - cl_int enqueueFillImage( - const Image& image, - cl_int4 fillColor, - const size_t<3>& origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueFillImage( - object_, - image(), - static_cast(&fillColor), - (const ::size_t *) origin, - (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_FILL_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - /** - * Enqueue a command to fill an image object with a specified color. - * \param fillColor is the color to use to fill the image. - * This is a four component RGBA unsigned integer color value if - * the image channel data type is an unnormalized unsigned integer - * type. - */ - cl_int enqueueFillImage( - const Image& image, - cl_uint4 fillColor, - const size_t<3>& origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueFillImage( - object_, - image(), - static_cast(&fillColor), - (const ::size_t *) origin, - (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_FILL_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } -#endif // #if defined(CL_VERSION_1_2) - - cl_int enqueueCopyImageToBuffer( - const Image& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& region, - ::size_t dst_offset, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueCopyImageToBuffer( - object_, src(), dst(), (const ::size_t *) src_origin, - (const ::size_t *) region, dst_offset, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueCopyBufferToImage( - const Buffer& src, - const Image& dst, - ::size_t src_offset, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueCopyBufferToImage( - object_, src(), dst(), src_offset, - (const ::size_t *) dst_origin, (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - void* enqueueMapBuffer( - const Buffer& buffer, - cl_bool blocking, - cl_map_flags flags, - ::size_t offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) const - { - cl_event tmp; - cl_int error; - void * result = ::clEnqueueMapBuffer( - object_, buffer(), blocking, flags, offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - if (event != NULL && error == CL_SUCCESS) - *event = tmp; - - return result; - } - - void* enqueueMapImage( - const Image& buffer, - cl_bool blocking, - cl_map_flags flags, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t * row_pitch, - ::size_t * slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) const - { - cl_event tmp; - cl_int error; - void * result = ::clEnqueueMapImage( - object_, buffer(), blocking, flags, - (const ::size_t *) origin, (const ::size_t *) region, - row_pitch, slice_pitch, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - if (event != NULL && error == CL_SUCCESS) - *event = tmp; - return result; - } - - cl_int enqueueUnmapMemObject( - const Memory& memory, - void* mapped_ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueUnmapMemObject( - object_, memory(), mapped_ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_UNMAP_MEM_OBJECT_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - -#if defined(CL_VERSION_1_2) - /** - * Enqueues a marker command which waits for either a list of events to complete, - * or all previously enqueued commands to complete. - * - * Enqueues a marker command which waits for either a list of events to complete, - * or if the list is empty it waits for all commands previously enqueued in command_queue - * to complete before it completes. This command returns an event which can be waited on, - * i.e. this event can be waited on to insure that all events either in the event_wait_list - * or all previously enqueued commands, queued before this command to command_queue, - * have completed. - */ - cl_int enqueueMarkerWithWaitList( - const VECTOR_CLASS *events = 0, - Event *event = 0) - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueMarkerWithWaitList( - object_, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_MARKER_WAIT_LIST_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - /** - * A synchronization point that enqueues a barrier operation. - * - * Enqueues a barrier command which waits for either a list of events to complete, - * or if the list is empty it waits for all commands previously enqueued in command_queue - * to complete before it completes. This command blocks command execution, that is, any - * following commands enqueued after it do not execute until it completes. This command - * returns an event which can be waited on, i.e. this event can be waited on to insure that - * all events either in the event_wait_list or all previously enqueued commands, queued - * before this command to command_queue, have completed. - */ - cl_int enqueueBarrierWithWaitList( - const VECTOR_CLASS *events = 0, - Event *event = 0) - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueBarrierWithWaitList( - object_, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_BARRIER_WAIT_LIST_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - /** - * Enqueues a command to indicate with which device a set of memory objects - * should be associated. - */ - cl_int enqueueMigrateMemObjects( - const VECTOR_CLASS &memObjects, - cl_mem_migration_flags flags, - const VECTOR_CLASS* events = NULL, - Event* event = NULL - ) - { - cl_event tmp; - - cl_mem* localMemObjects = static_cast(alloca(memObjects.size() * sizeof(cl_mem))); - for( int i = 0; i < (int)memObjects.size(); ++i ) { - localMemObjects[i] = memObjects[i](); - } - - - cl_int err = detail::errHandler( - ::clEnqueueMigrateMemObjects( - object_, - (cl_uint)memObjects.size(), - static_cast(localMemObjects), - flags, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_UNMAP_MEM_OBJECT_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } -#endif // #if defined(CL_VERSION_1_2) - - cl_int enqueueNDRangeKernel( - const Kernel& kernel, - const NDRange& offset, - const NDRange& global, - const NDRange& local = NullRange, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueNDRangeKernel( - object_, kernel(), (cl_uint) global.dimensions(), - offset.dimensions() != 0 ? (const ::size_t*) offset : NULL, - (const ::size_t*) global, - local.dimensions() != 0 ? (const ::size_t*) local : NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_NDRANGE_KERNEL_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueTask( - const Kernel& kernel, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueTask( - object_, kernel(), - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_TASK_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueNativeKernel( - void (CL_CALLBACK *userFptr)(void *), - std::pair args, - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* mem_locs = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_mem * mems = (mem_objects != NULL && mem_objects->size() > 0) - ? (cl_mem*) alloca(mem_objects->size() * sizeof(cl_mem)) - : NULL; - - if (mems != NULL) { - for (unsigned int i = 0; i < mem_objects->size(); i++) { - mems[i] = ((*mem_objects)[i])(); - } - } - - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueNativeKernel( - object_, userFptr, args.first, args.second, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - mems, - (mem_locs != NULL && mem_locs->size() > 0) ? (const void **) &mem_locs->front() : NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_NATIVE_KERNEL); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - -/** - * Deprecated APIs for 1.2 - */ -#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) - CL_EXT_PREFIX__VERSION_1_1_DEPRECATED - cl_int enqueueMarker(Event* event = NULL) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueMarker( - object_, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_MARKER_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - CL_EXT_PREFIX__VERSION_1_1_DEPRECATED - cl_int enqueueWaitForEvents(const VECTOR_CLASS& events) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED - { - return detail::errHandler( - ::clEnqueueWaitForEvents( - object_, - (cl_uint) events.size(), - events.size() > 0 ? (const cl_event*) &events.front() : NULL), - __ENQUEUE_WAIT_FOR_EVENTS_ERR); - } -#endif // #if defined(CL_VERSION_1_1) - - cl_int enqueueAcquireGLObjects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueAcquireGLObjects( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_ACQUIRE_GL_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueReleaseGLObjects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueReleaseGLObjects( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_RELEASE_GL_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - -#if defined (USE_DX_INTEROP) -typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)( - cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event); -typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)( - cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event); - - cl_int enqueueAcquireD3D10Objects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL; -#if defined(CL_VERSION_1_2) - cl_context context = getInfo(); - cl::Device device(getInfo()); - cl_platform_id platform = device.getInfo(); - __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clEnqueueAcquireD3D10ObjectsKHR); -#endif -#if defined(CL_VERSION_1_1) - __INIT_CL_EXT_FCN_PTR(clEnqueueAcquireD3D10ObjectsKHR); -#endif - - cl_event tmp; - cl_int err = detail::errHandler( - pfn_clEnqueueAcquireD3D10ObjectsKHR( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_ACQUIRE_GL_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } - - cl_int enqueueReleaseD3D10Objects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL; -#if defined(CL_VERSION_1_2) - cl_context context = getInfo(); - cl::Device device(getInfo()); - cl_platform_id platform = device.getInfo(); - __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clEnqueueReleaseD3D10ObjectsKHR); -#endif // #if defined(CL_VERSION_1_2) -#if defined(CL_VERSION_1_1) - __INIT_CL_EXT_FCN_PTR(clEnqueueReleaseD3D10ObjectsKHR); -#endif // #if defined(CL_VERSION_1_1) - - cl_event tmp; - cl_int err = detail::errHandler( - pfn_clEnqueueReleaseD3D10ObjectsKHR( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_RELEASE_GL_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; - } -#endif - -/** - * Deprecated APIs for 1.2 - */ -#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) - CL_EXT_PREFIX__VERSION_1_1_DEPRECATED - cl_int enqueueBarrier() const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED - { - return detail::errHandler( - ::clEnqueueBarrier(object_), - __ENQUEUE_BARRIER_ERR); - } -#endif // #if defined(CL_VERSION_1_1) - - cl_int flush() const - { - return detail::errHandler(::clFlush(object_), __FLUSH_ERR); - } - - cl_int finish() const - { - return detail::errHandler(::clFinish(object_), __FINISH_ERR); - } -}; - -#ifdef _WIN32 -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED -__declspec(selectany) std::atomic CommandQueue::default_initialized_; -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__declspec(selectany) volatile int CommandQueue::default_initialized_ = __DEFAULT_NOT_INITIALIZED; -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__declspec(selectany) CommandQueue CommandQueue::default_; -__declspec(selectany) volatile cl_int CommandQueue::default_error_ = CL_SUCCESS; -#else // !_WIN32 -#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED -__attribute__((weak)) std::atomic CommandQueue::default_initialized_; -#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__attribute__((weak)) volatile int CommandQueue::default_initialized_ = __DEFAULT_NOT_INITIALIZED; -#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED -__attribute__((weak)) CommandQueue CommandQueue::default_; -__attribute__((weak)) volatile cl_int CommandQueue::default_error_ = CL_SUCCESS; -#endif // !_WIN32 - -template< typename IteratorType > -Buffer::Buffer( - const Context &context, - IteratorType startIterator, - IteratorType endIterator, - bool readOnly, - bool useHostPtr, - cl_int* err) -{ - typedef typename std::iterator_traits::value_type DataType; - cl_int error; - - cl_mem_flags flags = 0; - if( readOnly ) { - flags |= CL_MEM_READ_ONLY; - } - else { - flags |= CL_MEM_READ_WRITE; - } - if( useHostPtr ) { - flags |= CL_MEM_USE_HOST_PTR; - } - - ::size_t size = sizeof(DataType)*(endIterator - startIterator); - - if( useHostPtr ) { - object_ = ::clCreateBuffer(context(), flags, size, static_cast(&*startIterator), &error); - } else { - object_ = ::clCreateBuffer(context(), flags, size, 0, &error); - } - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - - if( !useHostPtr ) { - CommandQueue queue(context, 0, &error); - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - - error = cl::copy(queue, startIterator, endIterator, *this); - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } -} - -template< typename IteratorType > -Buffer::Buffer( - const CommandQueue &queue, - IteratorType startIterator, - IteratorType endIterator, - bool readOnly, - bool useHostPtr, - cl_int* err) -{ - typedef typename std::iterator_traits::value_type DataType; - cl_int error; - - cl_mem_flags flags = 0; - if (readOnly) { - flags |= CL_MEM_READ_ONLY; - } - else { - flags |= CL_MEM_READ_WRITE; - } - if (useHostPtr) { - flags |= CL_MEM_USE_HOST_PTR; - } - - ::size_t size = sizeof(DataType)*(endIterator - startIterator); - - Context context = queue.getInfo(); - - if (useHostPtr) { - object_ = ::clCreateBuffer(context(), flags, size, static_cast(&*startIterator), &error); - } - else { - object_ = ::clCreateBuffer(context(), flags, size, 0, &error); - } - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - - if (!useHostPtr) { - error = cl::copy(queue, startIterator, endIterator, *this); - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } -} - -inline cl_int enqueueReadBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event); -} - -inline cl_int enqueueWriteBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - const void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event); -} - -inline void* enqueueMapBuffer( - const Buffer& buffer, - cl_bool blocking, - cl_map_flags flags, - ::size_t offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - - void * result = ::clEnqueueMapBuffer( - queue(), buffer(), blocking, flags, offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - return result; -} - -inline cl_int enqueueUnmapMemObject( - const Memory& memory, - void* mapped_ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); - if (error != CL_SUCCESS) { - return error; - } - - cl_event tmp; - cl_int err = detail::errHandler( - ::clEnqueueUnmapMemObject( - queue(), memory(), mapped_ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (event != NULL) ? &tmp : NULL), - __ENQUEUE_UNMAP_MEM_OBJECT_ERR); - - if (event != NULL && err == CL_SUCCESS) - *event = tmp; - - return err; -} - -inline cl_int enqueueCopyBuffer( - const Buffer& src, - const Buffer& dst, - ::size_t src_offset, - ::size_t dst_offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event); -} - -/** - * Blocking copy operation between iterators and a buffer. - * Host to Device. - * Uses default command queue. - */ -template< typename IteratorType > -inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - if (error != CL_SUCCESS) - return error; - - return cl::copy(queue, startIterator, endIterator, buffer); -} - -/** - * Blocking copy operation between iterators and a buffer. - * Device to Host. - * Uses default command queue. - */ -template< typename IteratorType > -inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - if (error != CL_SUCCESS) - return error; - - return cl::copy(queue, buffer, startIterator, endIterator); -} - -/** - * Blocking copy operation between iterators and a buffer. - * Host to Device. - * Uses specified queue. - */ -template< typename IteratorType > -inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ) -{ - typedef typename std::iterator_traits::value_type DataType; - cl_int error; - - ::size_t length = endIterator-startIterator; - ::size_t byteLength = length*sizeof(DataType); - - DataType *pointer = - static_cast(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error)); - // if exceptions enabled, enqueueMapBuffer will throw - if( error != CL_SUCCESS ) { - return error; - } -#if defined(_MSC_VER) - std::copy( - startIterator, - endIterator, - stdext::checked_array_iterator( - pointer, length)); -#else - std::copy(startIterator, endIterator, pointer); -#endif - Event endEvent; - error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent); - // if exceptions enabled, enqueueUnmapMemObject will throw - if( error != CL_SUCCESS ) { - return error; - } - endEvent.wait(); - return CL_SUCCESS; -} - -/** - * Blocking copy operation between iterators and a buffer. - * Device to Host. - * Uses specified queue. - */ -template< typename IteratorType > -inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ) -{ - typedef typename std::iterator_traits::value_type DataType; - cl_int error; - - ::size_t length = endIterator-startIterator; - ::size_t byteLength = length*sizeof(DataType); - - DataType *pointer = - static_cast(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error)); - // if exceptions enabled, enqueueMapBuffer will throw - if( error != CL_SUCCESS ) { - return error; - } - std::copy(pointer, pointer + length, startIterator); - Event endEvent; - error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent); - // if exceptions enabled, enqueueUnmapMemObject will throw - if( error != CL_SUCCESS ) { - return error; - } - endEvent.wait(); - return CL_SUCCESS; -} - -#if defined(CL_VERSION_1_1) -inline cl_int enqueueReadBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueReadBufferRect( - buffer, - blocking, - buffer_offset, - host_offset, - region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - events, - event); -} - -inline cl_int enqueueWriteBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueWriteBufferRect( - buffer, - blocking, - buffer_offset, - host_offset, - region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - events, - event); -} - -inline cl_int enqueueCopyBufferRect( - const Buffer& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - ::size_t src_row_pitch, - ::size_t src_slice_pitch, - ::size_t dst_row_pitch, - ::size_t dst_slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueCopyBufferRect( - src, - dst, - src_origin, - dst_origin, - region, - src_row_pitch, - src_slice_pitch, - dst_row_pitch, - dst_slice_pitch, - events, - event); -} -#endif - -inline cl_int enqueueReadImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueReadImage( - image, - blocking, - origin, - region, - row_pitch, - slice_pitch, - ptr, - events, - event); -} - -inline cl_int enqueueWriteImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueWriteImage( - image, - blocking, - origin, - region, - row_pitch, - slice_pitch, - ptr, - events, - event); -} - -inline cl_int enqueueCopyImage( - const Image& src, - const Image& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueCopyImage( - src, - dst, - src_origin, - dst_origin, - region, - events, - event); -} - -inline cl_int enqueueCopyImageToBuffer( - const Image& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& region, - ::size_t dst_offset, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueCopyImageToBuffer( - src, - dst, - src_origin, - region, - dst_offset, - events, - event); -} - -inline cl_int enqueueCopyBufferToImage( - const Buffer& src, - const Image& dst, - ::size_t src_offset, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.enqueueCopyBufferToImage( - src, - dst, - src_offset, - dst_origin, - region, - events, - event); -} - - -inline cl_int flush(void) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - return queue.flush(); -} - -inline cl_int finish(void) -{ - cl_int error; - CommandQueue queue = CommandQueue::getDefault(&error); - - if (error != CL_SUCCESS) { - return error; - } - - - return queue.finish(); -} - -// Kernel Functor support -// New interface as of September 2011 -// Requires the C++11 std::tr1::function (note do not support TR1) -// Visual Studio 2010 and GCC 4.2 - -struct EnqueueArgs -{ - CommandQueue queue_; - const NDRange offset_; - const NDRange global_; - const NDRange local_; - VECTOR_CLASS events_; - - EnqueueArgs(NDRange global) : - queue_(CommandQueue::getDefault()), - offset_(NullRange), - global_(global), - local_(NullRange) - { - - } - - EnqueueArgs(NDRange global, NDRange local) : - queue_(CommandQueue::getDefault()), - offset_(NullRange), - global_(global), - local_(local) - { - - } - - EnqueueArgs(NDRange offset, NDRange global, NDRange local) : - queue_(CommandQueue::getDefault()), - offset_(offset), - global_(global), - local_(local) - { - - } - - EnqueueArgs(Event e, NDRange global) : - queue_(CommandQueue::getDefault()), - offset_(NullRange), - global_(global), - local_(NullRange) - { - events_.push_back(e); - } - - EnqueueArgs(Event e, NDRange global, NDRange local) : - queue_(CommandQueue::getDefault()), - offset_(NullRange), - global_(global), - local_(local) - { - events_.push_back(e); - } - - EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) : - queue_(CommandQueue::getDefault()), - offset_(offset), - global_(global), - local_(local) - { - events_.push_back(e); - } - - EnqueueArgs(const VECTOR_CLASS &events, NDRange global) : - queue_(CommandQueue::getDefault()), - offset_(NullRange), - global_(global), - local_(NullRange), - events_(events) - { - - } - - EnqueueArgs(const VECTOR_CLASS &events, NDRange global, NDRange local) : - queue_(CommandQueue::getDefault()), - offset_(NullRange), - global_(global), - local_(local), - events_(events) - { - - } - - EnqueueArgs(const VECTOR_CLASS &events, NDRange offset, NDRange global, NDRange local) : - queue_(CommandQueue::getDefault()), - offset_(offset), - global_(global), - local_(local), - events_(events) - { - - } - - EnqueueArgs(CommandQueue &queue, NDRange global) : - queue_(queue), - offset_(NullRange), - global_(global), - local_(NullRange) - { - - } - - EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) : - queue_(queue), - offset_(NullRange), - global_(global), - local_(local) - { - - } - - EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) : - queue_(queue), - offset_(offset), - global_(global), - local_(local) - { - - } - - EnqueueArgs(CommandQueue &queue, Event e, NDRange global) : - queue_(queue), - offset_(NullRange), - global_(global), - local_(NullRange) - { - events_.push_back(e); - } - - EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) : - queue_(queue), - offset_(NullRange), - global_(global), - local_(local) - { - events_.push_back(e); - } - - EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) : - queue_(queue), - offset_(offset), - global_(global), - local_(local) - { - events_.push_back(e); - } - - EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS &events, NDRange global) : - queue_(queue), - offset_(NullRange), - global_(global), - local_(NullRange), - events_(events) - { - - } - - EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS &events, NDRange global, NDRange local) : - queue_(queue), - offset_(NullRange), - global_(global), - local_(local), - events_(events) - { - - } - - EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS &events, NDRange offset, NDRange global, NDRange local) : - queue_(queue), - offset_(offset), - global_(global), - local_(local), - events_(events) - { - - } -}; - -namespace detail { - -class NullType {}; - -template -struct SetArg -{ - static void set (Kernel kernel, T0 arg) - { - kernel.setArg(index, arg); - } -}; - -template -struct SetArg -{ - static void set (Kernel, NullType) - { - } -}; - -template < - typename T0, typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, typename T7, - typename T8, typename T9, typename T10, typename T11, - typename T12, typename T13, typename T14, typename T15, - typename T16, typename T17, typename T18, typename T19, - typename T20, typename T21, typename T22, typename T23, - typename T24, typename T25, typename T26, typename T27, - typename T28, typename T29, typename T30, typename T31 -> -class KernelFunctorGlobal -{ -private: - Kernel kernel_; - -public: - KernelFunctorGlobal( - Kernel kernel) : - kernel_(kernel) - {} - - KernelFunctorGlobal( - const Program& program, - const STRING_CLASS name, - cl_int * err = NULL) : - kernel_(program, name.c_str(), err) - {} - - Event operator() ( - const EnqueueArgs& args, - T0 t0, - T1 t1 = NullType(), - T2 t2 = NullType(), - T3 t3 = NullType(), - T4 t4 = NullType(), - T5 t5 = NullType(), - T6 t6 = NullType(), - T7 t7 = NullType(), - T8 t8 = NullType(), - T9 t9 = NullType(), - T10 t10 = NullType(), - T11 t11 = NullType(), - T12 t12 = NullType(), - T13 t13 = NullType(), - T14 t14 = NullType(), - T15 t15 = NullType(), - T16 t16 = NullType(), - T17 t17 = NullType(), - T18 t18 = NullType(), - T19 t19 = NullType(), - T20 t20 = NullType(), - T21 t21 = NullType(), - T22 t22 = NullType(), - T23 t23 = NullType(), - T24 t24 = NullType(), - T25 t25 = NullType(), - T26 t26 = NullType(), - T27 t27 = NullType(), - T28 t28 = NullType(), - T29 t29 = NullType(), - T30 t30 = NullType(), - T31 t31 = NullType() - ) - { - Event event; - SetArg<0, T0>::set(kernel_, t0); - SetArg<1, T1>::set(kernel_, t1); - SetArg<2, T2>::set(kernel_, t2); - SetArg<3, T3>::set(kernel_, t3); - SetArg<4, T4>::set(kernel_, t4); - SetArg<5, T5>::set(kernel_, t5); - SetArg<6, T6>::set(kernel_, t6); - SetArg<7, T7>::set(kernel_, t7); - SetArg<8, T8>::set(kernel_, t8); - SetArg<9, T9>::set(kernel_, t9); - SetArg<10, T10>::set(kernel_, t10); - SetArg<11, T11>::set(kernel_, t11); - SetArg<12, T12>::set(kernel_, t12); - SetArg<13, T13>::set(kernel_, t13); - SetArg<14, T14>::set(kernel_, t14); - SetArg<15, T15>::set(kernel_, t15); - SetArg<16, T16>::set(kernel_, t16); - SetArg<17, T17>::set(kernel_, t17); - SetArg<18, T18>::set(kernel_, t18); - SetArg<19, T19>::set(kernel_, t19); - SetArg<20, T20>::set(kernel_, t20); - SetArg<21, T21>::set(kernel_, t21); - SetArg<22, T22>::set(kernel_, t22); - SetArg<23, T23>::set(kernel_, t23); - SetArg<24, T24>::set(kernel_, t24); - SetArg<25, T25>::set(kernel_, t25); - SetArg<26, T26>::set(kernel_, t26); - SetArg<27, T27>::set(kernel_, t27); - SetArg<28, T28>::set(kernel_, t28); - SetArg<29, T29>::set(kernel_, t29); - SetArg<30, T30>::set(kernel_, t30); - SetArg<31, T31>::set(kernel_, t31); - - args.queue_.enqueueNDRangeKernel( - kernel_, - args.offset_, - args.global_, - args.local_, - &args.events_, - &event); - - return event; - } - -}; - -//------------------------------------------------------------------------------------------------------ - - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25, - typename T26, - typename T27, - typename T28, - typename T29, - typename T30, - typename T31> -struct functionImplementation_ -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - T31> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 32)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - T31); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25, - T26 arg26, - T27 arg27, - T28 arg28, - T29 arg29, - T30 arg30, - T31 arg31) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25, - arg26, - arg27, - arg28, - arg29, - arg30, - arg31); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25, - typename T26, - typename T27, - typename T28, - typename T29, - typename T30> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 31)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25, - T26 arg26, - T27 arg27, - T28 arg28, - T29 arg29, - T30 arg30) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25, - arg26, - arg27, - arg28, - arg29, - arg30); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25, - typename T26, - typename T27, - typename T28, - typename T29> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 30)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25, - T26 arg26, - T27 arg27, - T28 arg28, - T29 arg29) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25, - arg26, - arg27, - arg28, - arg29); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25, - typename T26, - typename T27, - typename T28> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 29)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25, - T26 arg26, - T27 arg27, - T28 arg28) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25, - arg26, - arg27, - arg28); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25, - typename T26, - typename T27> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 28)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25, - T26 arg26, - T27 arg27) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25, - arg26, - arg27); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25, - typename T26> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 27)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25, - T26 arg26) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25, - arg26); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24, - typename T25> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 26)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24, - T25 arg25) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24, - arg25); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23, - typename T24> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 25)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23, - T24 arg24) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23, - arg24); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22, - typename T23> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 24)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22, - T23 arg23) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22, - arg23); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21, - typename T22> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 23)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21, - arg22); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20, - typename T21> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 22)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20, - arg21); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19, - typename T20> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 21)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19, - arg20); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18, - typename T19> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 20)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17, - typename T18> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 19)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16, - typename T17> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 18)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15, - typename T16> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 17)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14, - typename T15> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 16)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13, - typename T14> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 15)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12, - typename T13> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 14)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11, - typename T12> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 13)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10, - typename T11> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 12)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 11)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 10)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 9)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 8)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6, - T7); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - T6, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - T6, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 7)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5, - T6); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - T5, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - T5, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 6)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4, - T5); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4, - arg5); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3, - typename T4> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - T4, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - T4, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 5)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3, - T4); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3, - arg4); - } - - -}; - -template< - typename T0, - typename T1, - typename T2, - typename T3> -struct functionImplementation_ -< T0, - T1, - T2, - T3, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - T3, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 4)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2, - T3); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2, - T3 arg3) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2, - arg3); - } - - -}; - -template< - typename T0, - typename T1, - typename T2> -struct functionImplementation_ -< T0, - T1, - T2, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - T2, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 3)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1, - T2); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1, - T2 arg2) - { - return functor_( - enqueueArgs, - arg0, - arg1, - arg2); - } - - -}; - -template< - typename T0, - typename T1> -struct functionImplementation_ -< T0, - T1, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - T1, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 2)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0, - T1); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0, - T1 arg1) - { - return functor_( - enqueueArgs, - arg0, - arg1); - } - - -}; - -template< - typename T0> -struct functionImplementation_ -< T0, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> -{ - typedef detail::KernelFunctorGlobal< - T0, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType, - NullType> FunctorType; - - FunctorType functor_; - - functionImplementation_(const FunctorType &functor) : - functor_(functor) - { - - #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 1)) - // Fail variadic expansion for dev11 - static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); - #endif - - } - - //! \brief Return type of the functor - typedef Event result_type; - - //! \brief Function signature of kernel functor with no event dependency. - typedef Event type_( - const EnqueueArgs&, - T0); - - Event operator()( - const EnqueueArgs& enqueueArgs, - T0 arg0) - { - return functor_( - enqueueArgs, - arg0); - } - - -}; - - - - - -} // namespace detail - -//---------------------------------------------------------------------------------------------- - -template < - typename T0, typename T1 = detail::NullType, typename T2 = detail::NullType, - typename T3 = detail::NullType, typename T4 = detail::NullType, - typename T5 = detail::NullType, typename T6 = detail::NullType, - typename T7 = detail::NullType, typename T8 = detail::NullType, - typename T9 = detail::NullType, typename T10 = detail::NullType, - typename T11 = detail::NullType, typename T12 = detail::NullType, - typename T13 = detail::NullType, typename T14 = detail::NullType, - typename T15 = detail::NullType, typename T16 = detail::NullType, - typename T17 = detail::NullType, typename T18 = detail::NullType, - typename T19 = detail::NullType, typename T20 = detail::NullType, - typename T21 = detail::NullType, typename T22 = detail::NullType, - typename T23 = detail::NullType, typename T24 = detail::NullType, - typename T25 = detail::NullType, typename T26 = detail::NullType, - typename T27 = detail::NullType, typename T28 = detail::NullType, - typename T29 = detail::NullType, typename T30 = detail::NullType, - typename T31 = detail::NullType -> -struct make_kernel : - public detail::functionImplementation_< - T0, T1, T2, T3, - T4, T5, T6, T7, - T8, T9, T10, T11, - T12, T13, T14, T15, - T16, T17, T18, T19, - T20, T21, T22, T23, - T24, T25, T26, T27, - T28, T29, T30, T31 - > -{ -public: - typedef detail::KernelFunctorGlobal< - T0, T1, T2, T3, - T4, T5, T6, T7, - T8, T9, T10, T11, - T12, T13, T14, T15, - T16, T17, T18, T19, - T20, T21, T22, T23, - T24, T25, T26, T27, - T28, T29, T30, T31 - > FunctorType; - - make_kernel( - const Program& program, - const STRING_CLASS name, - cl_int * err = NULL) : - detail::functionImplementation_< - T0, T1, T2, T3, - T4, T5, T6, T7, - T8, T9, T10, T11, - T12, T13, T14, T15, - T16, T17, T18, T19, - T20, T21, T22, T23, - T24, T25, T26, T27, - T28, T29, T30, T31 - >( - FunctorType(program, name, err)) - {} - - make_kernel( - const Kernel kernel) : - detail::functionImplementation_< - T0, T1, T2, T3, - T4, T5, T6, T7, - T8, T9, T10, T11, - T12, T13, T14, T15, - T16, T17, T18, T19, - T20, T21, T22, T23, - T24, T25, T26, T27, - T28, T29, T30, T31 - >( - FunctorType(kernel)) - {} -}; - - -//---------------------------------------------------------------------------------------------------------------------- - -#undef __ERR_STR -#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) -#undef __GET_DEVICE_INFO_ERR -#undef __GET_PLATFORM_INFO_ERR -#undef __GET_DEVICE_IDS_ERR -#undef __GET_CONTEXT_INFO_ERR -#undef __GET_EVENT_INFO_ERR -#undef __GET_EVENT_PROFILE_INFO_ERR -#undef __GET_MEM_OBJECT_INFO_ERR -#undef __GET_IMAGE_INFO_ERR -#undef __GET_SAMPLER_INFO_ERR -#undef __GET_KERNEL_INFO_ERR -#undef __GET_KERNEL_ARG_INFO_ERR -#undef __GET_KERNEL_WORK_GROUP_INFO_ERR -#undef __GET_PROGRAM_INFO_ERR -#undef __GET_PROGRAM_BUILD_INFO_ERR -#undef __GET_COMMAND_QUEUE_INFO_ERR - -#undef __CREATE_CONTEXT_ERR -#undef __CREATE_CONTEXT_FROM_TYPE_ERR -#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR - -#undef __CREATE_BUFFER_ERR -#undef __CREATE_SUBBUFFER_ERR -#undef __CREATE_IMAGE2D_ERR -#undef __CREATE_IMAGE3D_ERR -#undef __CREATE_SAMPLER_ERR -#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR - -#undef __CREATE_USER_EVENT_ERR -#undef __SET_USER_EVENT_STATUS_ERR -#undef __SET_EVENT_CALLBACK_ERR -#undef __SET_PRINTF_CALLBACK_ERR - -#undef __WAIT_FOR_EVENTS_ERR - -#undef __CREATE_KERNEL_ERR -#undef __SET_KERNEL_ARGS_ERR -#undef __CREATE_PROGRAM_WITH_SOURCE_ERR -#undef __CREATE_PROGRAM_WITH_BINARY_ERR -#undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR -#undef __BUILD_PROGRAM_ERR -#undef __CREATE_KERNELS_IN_PROGRAM_ERR - -#undef __CREATE_COMMAND_QUEUE_ERR -#undef __SET_COMMAND_QUEUE_PROPERTY_ERR -#undef __ENQUEUE_READ_BUFFER_ERR -#undef __ENQUEUE_WRITE_BUFFER_ERR -#undef __ENQUEUE_READ_BUFFER_RECT_ERR -#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR -#undef __ENQEUE_COPY_BUFFER_ERR -#undef __ENQEUE_COPY_BUFFER_RECT_ERR -#undef __ENQUEUE_READ_IMAGE_ERR -#undef __ENQUEUE_WRITE_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR -#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR -#undef __ENQUEUE_MAP_BUFFER_ERR -#undef __ENQUEUE_MAP_IMAGE_ERR -#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR -#undef __ENQUEUE_NDRANGE_KERNEL_ERR -#undef __ENQUEUE_TASK_ERR -#undef __ENQUEUE_NATIVE_KERNEL - -#undef __CL_EXPLICIT_CONSTRUCTORS - -#undef __UNLOAD_COMPILER_ERR -#endif //__CL_USER_OVERRIDE_ERROR_STRINGS - -#undef __CL_FUNCTION_TYPE - -// Extensions -/** - * Deprecated APIs for 1.2 - */ -#if defined(CL_VERSION_1_1) -#undef __INIT_CL_EXT_FCN_PTR -#endif // #if defined(CL_VERSION_1_1) -#undef __CREATE_SUB_DEVICES - -#if defined(USE_CL_DEVICE_FISSION) -#undef __PARAM_NAME_DEVICE_FISSION -#endif // USE_CL_DEVICE_FISSION - -#undef __DEFAULT_NOT_INITIALIZED -#undef __DEFAULT_BEING_INITIALIZED -#undef __DEFAULT_INITIALIZED - -#undef CL_HPP_RVALUE_REFERENCES_SUPPORTED -#undef CL_HPP_NOEXCEPT - -} // namespace cl - -#endif // CL_HPP_ diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp deleted file mode 100644 index 65f15d7ca..000000000 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* - This file is part of c-ethash. - - c-ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - c-ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file ethash_cl_miner.cpp -* @author Tim Hughes -* @date 2015 -*/ - - -#define _CRT_SECURE_NO_WARNINGS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ethash_cl_miner.h" -#include "ethash_cl_miner_kernel.h" - -#define ETHASH_BYTES 32 - -// workaround lame platforms -#if !CL_VERSION_1_2 -#define CL_MAP_WRITE_INVALIDATE_REGION CL_MAP_WRITE -#define CL_MEM_HOST_READ_ONLY 0 -#endif - -#undef min -#undef max - -using namespace std; - -static void add_definition(std::string& source, char const* id, unsigned value) -{ - char buf[256]; - sprintf(buf, "#define %s %uu\n", id, value); - source.insert(source.begin(), buf, buf + strlen(buf)); -} - -ethash_cl_miner::search_hook::~search_hook() {} - -ethash_cl_miner::ethash_cl_miner() -: m_opencl_1_1() -{ -} - -std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId) -{ - std::vector platforms; - cl::Platform::get(&platforms); - if (platforms.empty()) - { - cout << "No OpenCL platforms found." << endl; - return std::string(); - } - - // get GPU device of the selected platform - std::vector devices; - unsigned platform_num = std::min(_platformId, platforms.size() - 1); - platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); - if (devices.empty()) - { - cout << "No OpenCL devices found." << endl; - return std::string(); - } - - // use selected default device - unsigned device_num = std::min(_deviceId, devices.size() - 1); - cl::Device& device = devices[device_num]; - std::string device_version = device.getInfo(); - - return "{ \"platform\": \"" + platforms[platform_num].getInfo() + "\", \"device\": \"" + device.getInfo() + "\", \"version\": \"" + device_version + "\" }"; -} - -unsigned ethash_cl_miner::get_num_devices(unsigned _platformId) -{ - std::vector platforms; - cl::Platform::get(&platforms); - if (platforms.empty()) - { - cout << "No OpenCL platforms found." << endl; - return 0; - } - - std::vector devices; - unsigned platform_num = std::min(_platformId, platforms.size() - 1); - platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); - if (devices.empty()) - { - cout << "No OpenCL devices found." << endl; - return 0; - } - return devices.size(); -} - -void ethash_cl_miner::finish() -{ - if (m_queue()) - m_queue.finish(); -} - -bool ethash_cl_miner::init(uint64_t block_number, std::function _fillDAG, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId) -{ - // store params - m_fullSize = ethash_get_datasize(block_number); - - // get all platforms - std::vector platforms; - cl::Platform::get(&platforms); - if (platforms.empty()) - { - cout << "No OpenCL platforms found." << endl; - return false; - } - - // use selected platform - _platformId = std::min(_platformId, platforms.size() - 1); - - cout << "Using platform: " << platforms[_platformId].getInfo().c_str() << endl; - - // get GPU device of the default platform - std::vector devices; - platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices); - if (devices.empty()) - { - cout << "No OpenCL devices found." << endl; - return false; - } - - // use selected device - cl::Device& device = devices[std::min(_deviceId, devices.size() - 1)]; - std::string device_version = device.getInfo(); - cout << "Using device: " << device.getInfo().c_str() << "(" << device_version.c_str() << ")" << endl; - - if (strncmp("OpenCL 1.0", device_version.c_str(), 10) == 0) - { - cout << "OpenCL 1.0 is not supported." << endl; - return false; - } - if (strncmp("OpenCL 1.1", device_version.c_str(), 10) == 0) - m_opencl_1_1 = true; - - // create context - m_context = cl::Context(std::vector(&device, &device + 1)); - m_queue = cl::CommandQueue(m_context, device); - - // use requested workgroup size, but we require multiple of 8 - m_workgroup_size = ((workgroup_size + 7) / 8) * 8; - - // patch source code - std::string code(ETHASH_CL_MINER_KERNEL, ETHASH_CL_MINER_KERNEL + ETHASH_CL_MINER_KERNEL_SIZE); - add_definition(code, "GROUP_SIZE", m_workgroup_size); - add_definition(code, "DAG_SIZE", (unsigned)(m_fullSize / ETHASH_MIX_BYTES)); - add_definition(code, "ACCESSES", ETHASH_ACCESSES); - add_definition(code, "MAX_OUTPUTS", c_max_search_results); - //debugf("%s", code.c_str()); - - // create miner OpenCL program - cl::Program::Sources sources; - sources.push_back({code.c_str(), code.size()}); - - cl::Program program(m_context, sources); - try - { - program.build({device}); - } - catch (cl::Error err) - { - cout << program.getBuildInfo(device).c_str(); - return false; - } - m_hash_kernel = cl::Kernel(program, "ethash_hash"); - m_search_kernel = cl::Kernel(program, "ethash_search"); - - // create buffer for dag - m_dag = cl::Buffer(m_context, CL_MEM_READ_ONLY, m_fullSize); - - // create buffer for header - m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32); - - // compute dag on CPU - { - // if this throws then it's because we probably need to subdivide the dag uploads for compatibility - void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, m_fullSize); - // memcpying 1GB: horrible... really. horrible. but necessary since we can't mmap *and* gpumap. - _fillDAG(dag_ptr); - m_queue.enqueueUnmapMemObject(m_dag, dag_ptr); - } - - // create mining buffers - for (unsigned i = 0; i != c_num_buffers; ++i) - { - m_hash_buf[i] = cl::Buffer(m_context, CL_MEM_WRITE_ONLY | (!m_opencl_1_1 ? CL_MEM_HOST_READ_ONLY : 0), 32*c_hash_batch_size); - m_search_buf[i] = cl::Buffer(m_context, CL_MEM_WRITE_ONLY, (c_max_search_results + 1) * sizeof(uint32_t)); - } - return true; -} - -void ethash_cl_miner::hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count) -{ - struct pending_batch - { - unsigned base; - unsigned count; - unsigned buf; - }; - std::queue pending; - - // update header constant buffer - m_queue.enqueueWriteBuffer(m_header, true, 0, 32, header); - - /* - __kernel void ethash_combined_hash( - __global hash32_t* g_hashes, - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong start_nonce, - uint isolate - ) - */ - m_hash_kernel.setArg(1, m_header); - m_hash_kernel.setArg(2, m_dag); - m_hash_kernel.setArg(3, nonce); - m_hash_kernel.setArg(4, ~0u); // have to pass this to stop the compile unrolling the loop - - unsigned buf = 0; - for (unsigned i = 0; i < count || !pending.empty(); ) - { - // how many this batch - if (i < count) - { - unsigned const this_count = std::min(count - i, c_hash_batch_size); - unsigned const batch_count = std::max(this_count, m_workgroup_size); - - // supply output hash buffer to kernel - m_hash_kernel.setArg(0, m_hash_buf[buf]); - - // execute it! - m_queue.enqueueNDRangeKernel( - m_hash_kernel, - cl::NullRange, - cl::NDRange(batch_count), - cl::NDRange(m_workgroup_size) - ); - m_queue.flush(); - - pending.push({i, this_count, buf}); - i += this_count; - buf = (buf + 1) % c_num_buffers; - } - - // read results - if (i == count || pending.size() == c_num_buffers) - { - pending_batch const& batch = pending.front(); - - // could use pinned host pointer instead, but this path isn't that important. - uint8_t* hashes = (uint8_t*)m_queue.enqueueMapBuffer(m_hash_buf[batch.buf], true, CL_MAP_READ, 0, batch.count * ETHASH_BYTES); - memcpy(ret + batch.base*ETHASH_BYTES, hashes, batch.count*ETHASH_BYTES); - m_queue.enqueueUnmapMemObject(m_hash_buf[batch.buf], hashes); - - pending.pop(); - } - } -} - - -void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook& hook) -{ - struct pending_batch - { - uint64_t start_nonce; - unsigned buf; - }; - std::queue pending; - - static uint32_t const c_zero = 0; - - // update header constant buffer - m_queue.enqueueWriteBuffer(m_header, false, 0, 32, header); - for (unsigned i = 0; i != c_num_buffers; ++i) - { - m_queue.enqueueWriteBuffer(m_search_buf[i], false, 0, 4, &c_zero); - } - -#if CL_VERSION_1_2 && 0 - cl::Event pre_return_event; - if (!m_opencl_1_1) - { - m_queue.enqueueBarrierWithWaitList(NULL, &pre_return_event); - } - else -#endif - { - m_queue.finish(); - } - - /* - __kernel void ethash_combined_search( - __global hash32_t* g_hashes, // 0 - __constant hash32_t const* g_header, // 1 - __global hash128_t const* g_dag, // 2 - ulong start_nonce, // 3 - ulong target, // 4 - uint isolate // 5 - ) - */ - m_search_kernel.setArg(1, m_header); - m_search_kernel.setArg(2, m_dag); - - // pass these to stop the compiler unrolling the loops - m_search_kernel.setArg(4, target); - m_search_kernel.setArg(5, ~0u); - - - unsigned buf = 0; - for (uint64_t start_nonce = 0; ; start_nonce += c_search_batch_size) - { - // supply output buffer to kernel - m_search_kernel.setArg(0, m_search_buf[buf]); - m_search_kernel.setArg(3, start_nonce); - - // execute it! - m_queue.enqueueNDRangeKernel(m_search_kernel, cl::NullRange, c_search_batch_size, m_workgroup_size); - - pending.push({start_nonce, buf}); - buf = (buf + 1) % c_num_buffers; - - // read results - if (pending.size() == c_num_buffers) - { - pending_batch const& batch = pending.front(); - - // could use pinned host pointer instead - uint32_t* results = (uint32_t*)m_queue.enqueueMapBuffer(m_search_buf[batch.buf], true, CL_MAP_READ, 0, (1+c_max_search_results) * sizeof(uint32_t)); - unsigned num_found = std::min(results[0], c_max_search_results); - - uint64_t nonces[c_max_search_results]; - for (unsigned i = 0; i != num_found; ++i) - { - nonces[i] = batch.start_nonce + results[i+1]; - } - - m_queue.enqueueUnmapMemObject(m_search_buf[batch.buf], results); - - bool exit = num_found && hook.found(nonces, num_found); - exit |= hook.searched(batch.start_nonce, c_search_batch_size); // always report searched before exit - if (exit) - break; - - // reset search buffer if we're still going - if (num_found) - m_queue.enqueueWriteBuffer(m_search_buf[batch.buf], true, 0, 4, &c_zero); - - pending.pop(); - } - } - - // not safe to return until this is ready -#if CL_VERSION_1_2 && 0 - if (!m_opencl_1_1) - { - pre_return_event.wait(); - } -#endif -} - diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h deleted file mode 100644 index 23868b2c7..000000000 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#define __CL_ENABLE_EXCEPTIONS -#define CL_USE_DEPRECATED_OPENCL_2_0_APIS - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#include "cl.hpp" -#pragma clang diagnostic pop -#else -#include "cl.hpp" -#endif - -#include -#include -#include - -class ethash_cl_miner -{ -public: - struct search_hook - { - virtual ~search_hook(); // always a virtual destructor for a class with virtuals. - - // reports progress, return true to abort - virtual bool found(uint64_t const* nonces, uint32_t count) = 0; - virtual bool searched(uint64_t start_nonce, uint32_t count) = 0; - }; - -public: - ethash_cl_miner(); - - bool init(uint64_t block_number, std::function _fillDAG, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0); - static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); - static unsigned get_num_devices(unsigned _platformId = 0); - - - void finish(); - void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count); - void search(uint8_t const* header, uint64_t target, search_hook& hook); - -private: - enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 }; - - uint64_t m_fullSize; - cl::Context m_context; - cl::CommandQueue m_queue; - cl::Kernel m_hash_kernel; - cl::Kernel m_search_kernel; - cl::Buffer m_dag; - cl::Buffer m_header; - cl::Buffer m_hash_buf[c_num_buffers]; - cl::Buffer m_search_buf[c_num_buffers]; - unsigned m_workgroup_size; - bool m_opencl_1_1; -}; diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl deleted file mode 100644 index 3c8b9dc92..000000000 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl +++ /dev/null @@ -1,460 +0,0 @@ -// author Tim Hughes -// Tested on Radeon HD 7850 -// Hashrate: 15940347 hashes/s -// Bandwidth: 124533 MB/s -// search kernel should fit in <= 84 VGPRS (3 wavefronts) - -#define THREADS_PER_HASH (128 / 16) -#define HASHES_PER_LOOP (GROUP_SIZE / THREADS_PER_HASH) - -#define FNV_PRIME 0x01000193 - -__constant uint2 const Keccak_f1600_RC[24] = { - (uint2)(0x00000001, 0x00000000), - (uint2)(0x00008082, 0x00000000), - (uint2)(0x0000808a, 0x80000000), - (uint2)(0x80008000, 0x80000000), - (uint2)(0x0000808b, 0x00000000), - (uint2)(0x80000001, 0x00000000), - (uint2)(0x80008081, 0x80000000), - (uint2)(0x00008009, 0x80000000), - (uint2)(0x0000008a, 0x00000000), - (uint2)(0x00000088, 0x00000000), - (uint2)(0x80008009, 0x00000000), - (uint2)(0x8000000a, 0x00000000), - (uint2)(0x8000808b, 0x00000000), - (uint2)(0x0000008b, 0x80000000), - (uint2)(0x00008089, 0x80000000), - (uint2)(0x00008003, 0x80000000), - (uint2)(0x00008002, 0x80000000), - (uint2)(0x00000080, 0x80000000), - (uint2)(0x0000800a, 0x00000000), - (uint2)(0x8000000a, 0x80000000), - (uint2)(0x80008081, 0x80000000), - (uint2)(0x00008080, 0x80000000), - (uint2)(0x80000001, 0x00000000), - (uint2)(0x80008008, 0x80000000), -}; - -void keccak_f1600_round(uint2* a, uint r, uint out_size) -{ - #if !__ENDIAN_LITTLE__ - for (uint i = 0; i != 25; ++i) - a[i] = a[i].yx; - #endif - - uint2 b[25]; - uint2 t; - - // Theta - b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]; - b[1] = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]; - b[2] = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]; - b[3] = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]; - b[4] = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]; - t = b[4] ^ (uint2)(b[1].x << 1 | b[1].y >> 31, b[1].y << 1 | b[1].x >> 31); - a[0] ^= t; - a[5] ^= t; - a[10] ^= t; - a[15] ^= t; - a[20] ^= t; - t = b[0] ^ (uint2)(b[2].x << 1 | b[2].y >> 31, b[2].y << 1 | b[2].x >> 31); - a[1] ^= t; - a[6] ^= t; - a[11] ^= t; - a[16] ^= t; - a[21] ^= t; - t = b[1] ^ (uint2)(b[3].x << 1 | b[3].y >> 31, b[3].y << 1 | b[3].x >> 31); - a[2] ^= t; - a[7] ^= t; - a[12] ^= t; - a[17] ^= t; - a[22] ^= t; - t = b[2] ^ (uint2)(b[4].x << 1 | b[4].y >> 31, b[4].y << 1 | b[4].x >> 31); - a[3] ^= t; - a[8] ^= t; - a[13] ^= t; - a[18] ^= t; - a[23] ^= t; - t = b[3] ^ (uint2)(b[0].x << 1 | b[0].y >> 31, b[0].y << 1 | b[0].x >> 31); - a[4] ^= t; - a[9] ^= t; - a[14] ^= t; - a[19] ^= t; - a[24] ^= t; - - // Rho Pi - b[0] = a[0]; - b[10] = (uint2)(a[1].x << 1 | a[1].y >> 31, a[1].y << 1 | a[1].x >> 31); - b[7] = (uint2)(a[10].x << 3 | a[10].y >> 29, a[10].y << 3 | a[10].x >> 29); - b[11] = (uint2)(a[7].x << 6 | a[7].y >> 26, a[7].y << 6 | a[7].x >> 26); - b[17] = (uint2)(a[11].x << 10 | a[11].y >> 22, a[11].y << 10 | a[11].x >> 22); - b[18] = (uint2)(a[17].x << 15 | a[17].y >> 17, a[17].y << 15 | a[17].x >> 17); - b[3] = (uint2)(a[18].x << 21 | a[18].y >> 11, a[18].y << 21 | a[18].x >> 11); - b[5] = (uint2)(a[3].x << 28 | a[3].y >> 4, a[3].y << 28 | a[3].x >> 4); - b[16] = (uint2)(a[5].y << 4 | a[5].x >> 28, a[5].x << 4 | a[5].y >> 28); - b[8] = (uint2)(a[16].y << 13 | a[16].x >> 19, a[16].x << 13 | a[16].y >> 19); - b[21] = (uint2)(a[8].y << 23 | a[8].x >> 9, a[8].x << 23 | a[8].y >> 9); - b[24] = (uint2)(a[21].x << 2 | a[21].y >> 30, a[21].y << 2 | a[21].x >> 30); - b[4] = (uint2)(a[24].x << 14 | a[24].y >> 18, a[24].y << 14 | a[24].x >> 18); - b[15] = (uint2)(a[4].x << 27 | a[4].y >> 5, a[4].y << 27 | a[4].x >> 5); - b[23] = (uint2)(a[15].y << 9 | a[15].x >> 23, a[15].x << 9 | a[15].y >> 23); - b[19] = (uint2)(a[23].y << 24 | a[23].x >> 8, a[23].x << 24 | a[23].y >> 8); - b[13] = (uint2)(a[19].x << 8 | a[19].y >> 24, a[19].y << 8 | a[19].x >> 24); - b[12] = (uint2)(a[13].x << 25 | a[13].y >> 7, a[13].y << 25 | a[13].x >> 7); - b[2] = (uint2)(a[12].y << 11 | a[12].x >> 21, a[12].x << 11 | a[12].y >> 21); - b[20] = (uint2)(a[2].y << 30 | a[2].x >> 2, a[2].x << 30 | a[2].y >> 2); - b[14] = (uint2)(a[20].x << 18 | a[20].y >> 14, a[20].y << 18 | a[20].x >> 14); - b[22] = (uint2)(a[14].y << 7 | a[14].x >> 25, a[14].x << 7 | a[14].y >> 25); - b[9] = (uint2)(a[22].y << 29 | a[22].x >> 3, a[22].x << 29 | a[22].y >> 3); - b[6] = (uint2)(a[9].x << 20 | a[9].y >> 12, a[9].y << 20 | a[9].x >> 12); - b[1] = (uint2)(a[6].y << 12 | a[6].x >> 20, a[6].x << 12 | a[6].y >> 20); - - // Chi - a[0] = bitselect(b[0] ^ b[2], b[0], b[1]); - a[1] = bitselect(b[1] ^ b[3], b[1], b[2]); - a[2] = bitselect(b[2] ^ b[4], b[2], b[3]); - a[3] = bitselect(b[3] ^ b[0], b[3], b[4]); - if (out_size >= 4) - { - a[4] = bitselect(b[4] ^ b[1], b[4], b[0]); - a[5] = bitselect(b[5] ^ b[7], b[5], b[6]); - a[6] = bitselect(b[6] ^ b[8], b[6], b[7]); - a[7] = bitselect(b[7] ^ b[9], b[7], b[8]); - a[8] = bitselect(b[8] ^ b[5], b[8], b[9]); - if (out_size >= 8) - { - a[9] = bitselect(b[9] ^ b[6], b[9], b[5]); - a[10] = bitselect(b[10] ^ b[12], b[10], b[11]); - a[11] = bitselect(b[11] ^ b[13], b[11], b[12]); - a[12] = bitselect(b[12] ^ b[14], b[12], b[13]); - a[13] = bitselect(b[13] ^ b[10], b[13], b[14]); - a[14] = bitselect(b[14] ^ b[11], b[14], b[10]); - a[15] = bitselect(b[15] ^ b[17], b[15], b[16]); - a[16] = bitselect(b[16] ^ b[18], b[16], b[17]); - a[17] = bitselect(b[17] ^ b[19], b[17], b[18]); - a[18] = bitselect(b[18] ^ b[15], b[18], b[19]); - a[19] = bitselect(b[19] ^ b[16], b[19], b[15]); - a[20] = bitselect(b[20] ^ b[22], b[20], b[21]); - a[21] = bitselect(b[21] ^ b[23], b[21], b[22]); - a[22] = bitselect(b[22] ^ b[24], b[22], b[23]); - a[23] = bitselect(b[23] ^ b[20], b[23], b[24]); - a[24] = bitselect(b[24] ^ b[21], b[24], b[20]); - } - } - - // Iota - a[0] ^= Keccak_f1600_RC[r]; - - #if !__ENDIAN_LITTLE__ - for (uint i = 0; i != 25; ++i) - a[i] = a[i].yx; - #endif -} - -void keccak_f1600_no_absorb(ulong* a, uint in_size, uint out_size, uint isolate) -{ - for (uint i = in_size; i != 25; ++i) - { - a[i] = 0; - } -#if __ENDIAN_LITTLE__ - a[in_size] ^= 0x0000000000000001; - a[24-out_size*2] ^= 0x8000000000000000; -#else - a[in_size] ^= 0x0100000000000000; - a[24-out_size*2] ^= 0x0000000000000080; -#endif - - // Originally I unrolled the first and last rounds to interface - // better with surrounding code, however I haven't done this - // without causing the AMD compiler to blow up the VGPR usage. - uint r = 0; - do - { - // This dynamic branch stops the AMD compiler unrolling the loop - // and additionally saves about 33% of the VGPRs, enough to gain another - // wavefront. Ideally we'd get 4 in flight, but 3 is the best I can - // massage out of the compiler. It doesn't really seem to matter how - // much we try and help the compiler save VGPRs because it seems to throw - // that information away, hence the implementation of keccak here - // doesn't bother. - if (isolate) - { - keccak_f1600_round((uint2*)a, r++, 25); - } - } - while (r < 23); - - // final round optimised for digest size - keccak_f1600_round((uint2*)a, r++, out_size); -} - -#define copy(dst, src, count) for (uint i = 0; i != count; ++i) { (dst)[i] = (src)[i]; } - -#define countof(x) (sizeof(x) / sizeof(x[0])) - -uint fnv(uint x, uint y) -{ - return x * FNV_PRIME ^ y; -} - -uint4 fnv4(uint4 x, uint4 y) -{ - return x * FNV_PRIME ^ y; -} - -uint fnv_reduce(uint4 v) -{ - return fnv(fnv(fnv(v.x, v.y), v.z), v.w); -} - -typedef union -{ - ulong ulongs[32 / sizeof(ulong)]; - uint uints[32 / sizeof(uint)]; -} hash32_t; - -typedef union -{ - ulong ulongs[64 / sizeof(ulong)]; - uint4 uint4s[64 / sizeof(uint4)]; -} hash64_t; - -typedef union -{ - uint uints[128 / sizeof(uint)]; - uint4 uint4s[128 / sizeof(uint4)]; -} hash128_t; - -hash64_t init_hash(__constant hash32_t const* header, ulong nonce, uint isolate) -{ - hash64_t init; - uint const init_size = countof(init.ulongs); - uint const hash_size = countof(header->ulongs); - - // sha3_512(header .. nonce) - ulong state[25]; - copy(state, header->ulongs, hash_size); - state[hash_size] = nonce; - keccak_f1600_no_absorb(state, hash_size + 1, init_size, isolate); - - copy(init.ulongs, state, init_size); - return init; -} - -uint inner_loop(uint4 init, uint thread_id, __local uint* share, __global hash128_t const* g_dag, uint isolate) -{ - uint4 mix = init; - - // share init0 - if (thread_id == 0) - *share = mix.x; - barrier(CLK_LOCAL_MEM_FENCE); - uint init0 = *share; - - uint a = 0; - do - { - bool update_share = thread_id == (a/4) % THREADS_PER_HASH; - - #pragma unroll - for (uint i = 0; i != 4; ++i) - { - if (update_share) - { - uint m[4] = { mix.x, mix.y, mix.z, mix.w }; - *share = fnv(init0 ^ (a+i), m[i]) % DAG_SIZE; - } - barrier(CLK_LOCAL_MEM_FENCE); - - mix = fnv4(mix, g_dag[*share].uint4s[thread_id]); - } - } - while ((a += 4) != (ACCESSES & isolate)); - - return fnv_reduce(mix); -} - -hash32_t final_hash(hash64_t const* init, hash32_t const* mix, uint isolate) -{ - ulong state[25]; - - hash32_t hash; - uint const hash_size = countof(hash.ulongs); - uint const init_size = countof(init->ulongs); - uint const mix_size = countof(mix->ulongs); - - // keccak_256(keccak_512(header..nonce) .. mix); - copy(state, init->ulongs, init_size); - copy(state + init_size, mix->ulongs, mix_size); - keccak_f1600_no_absorb(state, init_size+mix_size, hash_size, isolate); - - // copy out - copy(hash.ulongs, state, hash_size); - return hash; -} - -hash32_t compute_hash_simple( - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong nonce, - uint isolate - ) -{ - hash64_t init = init_hash(g_header, nonce, isolate); - - hash128_t mix; - for (uint i = 0; i != countof(mix.uint4s); ++i) - { - mix.uint4s[i] = init.uint4s[i % countof(init.uint4s)]; - } - - uint mix_val = mix.uints[0]; - uint init0 = mix.uints[0]; - uint a = 0; - do - { - uint pi = fnv(init0 ^ a, mix_val) % DAG_SIZE; - uint n = (a+1) % countof(mix.uints); - - #pragma unroll - for (uint i = 0; i != countof(mix.uints); ++i) - { - mix.uints[i] = fnv(mix.uints[i], g_dag[pi].uints[i]); - mix_val = i == n ? mix.uints[i] : mix_val; - } - } - while (++a != (ACCESSES & isolate)); - - // reduce to output - hash32_t fnv_mix; - for (uint i = 0; i != countof(fnv_mix.uints); ++i) - { - fnv_mix.uints[i] = fnv_reduce(mix.uint4s[i]); - } - - return final_hash(&init, &fnv_mix, isolate); -} - -typedef union -{ - struct - { - hash64_t init; - uint pad; // avoid lds bank conflicts - }; - hash32_t mix; -} compute_hash_share; - -hash32_t compute_hash( - __local compute_hash_share* share, - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong nonce, - uint isolate - ) -{ - uint const gid = get_global_id(0); - - // Compute one init hash per work item. - hash64_t init = init_hash(g_header, nonce, isolate); - - // Threads work together in this phase in groups of 8. - uint const thread_id = gid % THREADS_PER_HASH; - uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH; - - hash32_t mix; - uint i = 0; - do - { - // share init with other threads - if (i == thread_id) - share[hash_id].init = init; - barrier(CLK_LOCAL_MEM_FENCE); - - uint4 thread_init = share[hash_id].init.uint4s[thread_id % (64 / sizeof(uint4))]; - barrier(CLK_LOCAL_MEM_FENCE); - - uint thread_mix = inner_loop(thread_init, thread_id, share[hash_id].mix.uints, g_dag, isolate); - - share[hash_id].mix.uints[thread_id] = thread_mix; - barrier(CLK_LOCAL_MEM_FENCE); - - if (i == thread_id) - mix = share[hash_id].mix; - barrier(CLK_LOCAL_MEM_FENCE); - } - while (++i != (THREADS_PER_HASH & isolate)); - - return final_hash(&init, &mix, isolate); -} - -__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1))) -__kernel void ethash_hash_simple( - __global hash32_t* g_hashes, - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong start_nonce, - uint isolate - ) -{ - uint const gid = get_global_id(0); - g_hashes[gid] = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate); -} - -__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1))) -__kernel void ethash_search_simple( - __global volatile uint* restrict g_output, - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong start_nonce, - ulong target, - uint isolate - ) -{ - uint const gid = get_global_id(0); - hash32_t hash = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate); - if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target) - { - uint slot = min(MAX_OUTPUTS, atomic_inc(&g_output[0]) + 1); - g_output[slot] = gid; - } -} - -__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1))) -__kernel void ethash_hash( - __global hash32_t* g_hashes, - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong start_nonce, - uint isolate - ) -{ - __local compute_hash_share share[HASHES_PER_LOOP]; - - uint const gid = get_global_id(0); - g_hashes[gid] = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate); -} - -__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1))) -__kernel void ethash_search( - __global volatile uint* restrict g_output, - __constant hash32_t const* g_header, - __global hash128_t const* g_dag, - ulong start_nonce, - ulong target, - uint isolate - ) -{ - __local compute_hash_share share[HASHES_PER_LOOP]; - - uint const gid = get_global_id(0); - hash32_t hash = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate); - - if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target) - { - uint slot = min(MAX_OUTPUTS, atomic_inc(&g_output[0]) + 1); - g_output[slot] = gid; - } -} diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h index 0ee402d9a..6ca6cc036 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h @@ -32,6 +32,9 @@ #include #define ethash_swap_u32(input_) OSSwapInt32(input_) #define ethash_swap_u64(input_) OSSwapInt64(input_) +#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) +#define ethash_swap_u32(input_) bswap32(input_) +#define ethash_swap_u64(input_) bswap64(input_) #else // posix #include #define ethash_swap_u32(input_) __bswap_32(input_) diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c index e881e0c7b..b28a59e43 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c @@ -364,6 +364,7 @@ static bool ethash_mmap(struct ethash_full* ret, FILE* f) { int fd; char* mmapped_data; + errno = 0; ret->file = f; if ((fd = ethash_fileno(ret->file)) == -1) { return false; @@ -400,38 +401,48 @@ ethash_full_t ethash_full_new_internal( ret->file_size = (size_t)full_size; switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) { case ETHASH_IO_FAIL: + // ethash_io_prepare will do all ETHASH_CRITICAL() logging in fail case goto fail_free_full; case ETHASH_IO_MEMO_MATCH: if (!ethash_mmap(ret, f)) { + ETHASH_CRITICAL("mmap failure()"); goto fail_close_file; } return ret; case ETHASH_IO_MEMO_SIZE_MISMATCH: // if a DAG of same filename but unexpected size is found, silently force new file creation if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) { + ETHASH_CRITICAL("Could not recreate DAG file after finding existing DAG with unexpected size."); goto fail_free_full; } // fallthrough to the mismatch case here, DO NOT go through match case ETHASH_IO_MEMO_MISMATCH: if (!ethash_mmap(ret, f)) { + ETHASH_CRITICAL("mmap failure()"); goto fail_close_file; } break; } if (!ethash_compute_full_data(ret->data, full_size, light, callback)) { + ETHASH_CRITICAL("Failure at computing DAG data."); goto fail_free_full_data; } // after the DAG has been filled then we finalize it by writting the magic number at the beginning if (fseek(f, 0, SEEK_SET) != 0) { + ETHASH_CRITICAL("Could not seek to DAG file start to write magic number."); goto fail_free_full_data; } uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM; if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { + ETHASH_CRITICAL("Could not write magic number to DAG's beginning."); + goto fail_free_full_data; + } + if (fflush(f) != 0) {// make sure the magic number IS there + ETHASH_CRITICAL("Could not flush memory mapped data to DAG file. Insufficient space?"); goto fail_free_full_data; } - fflush(f); // make sure the magic number IS there return ret; fail_free_full_data: diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c index 5b4e7da2b..f4db477c2 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c @@ -21,6 +21,7 @@ #include "io.h" #include #include +#include enum ethash_io_rc ethash_io_prepare( char const* dirname, @@ -32,15 +33,19 @@ enum ethash_io_rc ethash_io_prepare( { char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE]; enum ethash_io_rc ret = ETHASH_IO_FAIL; + // reset errno before io calls + errno = 0; // assert directory exists if (!ethash_mkdir(dirname)) { + ETHASH_CRITICAL("Could not create the ethash directory"); goto end; } ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name); char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name)); if (!tmpfile) { + ETHASH_CRITICAL("Could not create the full DAG pathname"); goto end; } @@ -52,6 +57,7 @@ enum ethash_io_rc ethash_io_prepare( size_t found_size; if (!ethash_file_size(f, &found_size)) { fclose(f); + ETHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile); goto free_memo; } if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) { @@ -64,6 +70,7 @@ enum ethash_io_rc ethash_io_prepare( if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { // I/O error fclose(f); + ETHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile); ret = ETHASH_IO_MEMO_SIZE_MISMATCH; goto free_memo; } @@ -80,15 +87,25 @@ enum ethash_io_rc ethash_io_prepare( // file does not exist, will need to be created f = ethash_fopen(tmpfile, "wb+"); if (!f) { + ETHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile); goto free_memo; } // make sure it's of the proper size if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) { fclose(f); + ETHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile); + goto free_memo; + } + if (fputc('\n', f) == EOF) { + fclose(f); + ETHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile); + goto free_memo; + } + if (fflush(f) != 0) { + fclose(f); + ETHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile); goto free_memo; } - fputc('\n', f); - fflush(f); ret = ETHASH_IO_MEMO_MISMATCH; goto set_file; diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h index 05aa5ed37..7a27089c7 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h @@ -54,6 +54,23 @@ enum ethash_io_rc { #define snprintf(...) sprintf_s(__VA_ARGS__) #endif +/** + * Logs a critical error in important parts of ethash. Should mostly help + * figure out what kind of problem (I/O, memory e.t.c.) causes a NULL + * ethash_full_t + */ +#ifdef ETHASH_PRINT_CRITICAL_OUTPUT +#define ETHASH_CRITICAL(...) \ + do \ + { \ + printf("ETHASH CRITICAL ERROR: "__VA_ARGS__); \ + printf("\n"); \ + fflush(stdout); \ + } while (0) +#else +#define ETHASH_CRITICAL(...) +#endif + /** * Prepares io for ethash * diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c index 7f03d5482..c9a17d845 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include FILE* ethash_fopen(char const* file_name, char const* mode) { @@ -89,6 +91,13 @@ bool ethash_get_default_dirname(char* strbuf, size_t buffsize) static const char dir_suffix[] = ".ethash/"; strbuf[0] = '\0'; char* home_dir = getenv("HOME"); + if (!home_dir || strlen(home_dir) == 0) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + home_dir = pwd->pw_dir; + } + size_t len = strlen(home_dir); if (!ethash_strncat(strbuf, buffsize, home_dir, len)) { return false; diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c index 2e6c8deb8..34f1aaa77 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c @@ -87,9 +87,9 @@ bool ethash_file_size(FILE* f, size_t* ret_size) bool ethash_get_default_dirname(char* strbuf, size_t buffsize) { - static const char dir_suffix[] = "Appdata\\Ethash\\"; + static const char dir_suffix[] = "Ethash\\"; strbuf[0] = '\0'; - if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)strbuf))) { + if (!SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, (CHAR*)strbuf))) { return false; } if (!ethash_strncat(strbuf, buffsize, "\\", 1)) { diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp index 1933e03e3..44e0c385b 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp @@ -292,12 +292,13 @@ BOOST_AUTO_TEST_CASE(test_ethash_io_memo_file_size_mismatch) { BOOST_AUTO_TEST_CASE(test_ethash_get_default_dirname) { char result[256]; - // this is really not an easy thing to test for in a unit test, so yeah it does look ugly + // this is really not an easy thing to test for in a unit test + // TODO: Improve this test ... #ifdef _WIN32 char homedir[256]; - BOOST_REQUIRE(SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)homedir))); + BOOST_REQUIRE(SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, (CHAR*)homedir))); BOOST_REQUIRE(ethash_get_default_dirname(result, 256)); - std::string res = std::string(homedir) + std::string("\\Appdata\\Ethash\\"); + std::string res = std::string(homedir) + std::string("\\AppData\\Local\\Ethash\\"); #else char* homedir = getenv("HOME"); BOOST_REQUIRE(ethash_get_default_dirname(result, 256)); @@ -305,7 +306,7 @@ BOOST_AUTO_TEST_CASE(test_ethash_get_default_dirname) { #endif BOOST_CHECK_MESSAGE(strcmp(res.c_str(), result) == 0, "Expected \"" + res + "\" but got \"" + std::string(result) + "\"" - ); + ); } BOOST_AUTO_TEST_CASE(light_and_full_client_checks) { From 7ec8c257ffd90ba4b63e5419ac9b9011af79be07 Mon Sep 17 00:00:00 2001 From: SilentCicero Date: Tue, 16 Jun 2015 12:28:10 -0400 Subject: [PATCH 013/110] New DataArgs and eth_sendRawTransaction --- rpc/api.go | 2 +- rpc/api/eth.go | 2 +- rpc/api/eth_args.go | 29 +++++++++++++++++++++++++++++ rpc/args.go | 29 +++++++++++++++++++++++++++++ xeth/xeth.go | 5 ++++- 5 files changed, 64 insertions(+), 3 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 943d50119..e825accfd 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -171,7 +171,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err *reply = v case "eth_sendRawTransaction": - args := new(NewSigArgs) + args := new(NewDataArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } diff --git a/rpc/api/eth.go b/rpc/api/eth.go index bb89615cf..e1e7381f5 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -250,7 +250,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) { - args := new(NewSigArgs) + args := new(NewDataArgs) if err := self.codec.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } diff --git a/rpc/api/eth_args.go b/rpc/api/eth_args.go index ad9a35fa2..70fb18289 100644 --- a/rpc/api/eth_args.go +++ b/rpc/api/eth_args.go @@ -226,6 +226,35 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { return nil } +type NewDataArgs struct { + Data string +} + +func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + // Check for sufficient params + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + + data, ok := obj[0].(string) + if !ok { + return shared.NewInvalidTypeError("data", "not a string") + } + args.Data = data + + if len(args.Data) == 0 { + return shared.NewValidationError("data", "is required") + } + + return nil +} + type NewSigArgs struct { From string Data string diff --git a/rpc/args.go b/rpc/args.go index 65f0f6043..aa7d20549 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -154,6 +154,35 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { return nil } +type NewDataArgs struct { + Data string +} + +func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + + if err := json.Unmarshal(b, &obj); err != nil { + return NewDecodeParamError(err.Error()) + } + + // Check for sufficient params + if len(obj) < 1 { + return NewInsufficientParamsError(len(obj), 1) + } + + data, ok := obj[0].(string) + if !ok { + return NewInvalidTypeError("data", "not a string") + } + args.Data = data + + if len(args.Data) == 0 { + return NewValidationError("data", "is required") + } + + return nil +} + type NewTxArgs struct { From string To string diff --git a/xeth/xeth.go b/xeth/xeth.go index d2f992084..c64ae71e3 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -787,6 +787,9 @@ func (self *XEth) FromNumber(str string) string { func (self *XEth) PushTx(encodedTx string) (string, error) { tx := types.NewTransactionFromBytes(common.FromHex(encodedTx)) + + glog.V(logger.Info).Infof("Tx(%x) gas: %x\n", tx.Hash(), tx.Gas()) + err := self.backend.TxPool().Add(tx) if err != nil { return "", err @@ -965,7 +968,7 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS return core.AddressFromMessage(tx).Hex(), nil } else { - glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) + glog.V(logger.Info).Infof("YEYEYE!! Tx(%x) to: %x\n, gas: %x", tx.Hash(), tx.To(), tx.Gas()) } return tx.Hash().Hex(), nil } From 6add45cd10a8f33e838a8922e694db7181c06fd9 Mon Sep 17 00:00:00 2001 From: SilentCicero Date: Tue, 16 Jun 2015 12:30:07 -0400 Subject: [PATCH 014/110] Remove Extra Loggers --- xeth/xeth.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/xeth/xeth.go b/xeth/xeth.go index c64ae71e3..d2f992084 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -787,9 +787,6 @@ func (self *XEth) FromNumber(str string) string { func (self *XEth) PushTx(encodedTx string) (string, error) { tx := types.NewTransactionFromBytes(common.FromHex(encodedTx)) - - glog.V(logger.Info).Infof("Tx(%x) gas: %x\n", tx.Hash(), tx.Gas()) - err := self.backend.TxPool().Add(tx) if err != nil { return "", err @@ -968,7 +965,7 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS return core.AddressFromMessage(tx).Hex(), nil } else { - glog.V(logger.Info).Infof("YEYEYE!! Tx(%x) to: %x\n, gas: %x", tx.Hash(), tx.To(), tx.Gas()) + glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } return tx.Hash().Hex(), nil } From 1f34daccc33d7d4edd3fdf27efbc0c29445f2f1f Mon Sep 17 00:00:00 2001 From: SilentCicero Date: Tue, 16 Jun 2015 12:47:34 -0400 Subject: [PATCH 015/110] Added glog messages like Transaction --- xeth/xeth.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xeth/xeth.go b/xeth/xeth.go index d2f992084..f0ba91ba7 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -794,8 +794,12 @@ func (self *XEth) PushTx(encodedTx string) (string, error) { if tx.To() == nil { addr := core.AddressFromMessage(tx) + glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) return addr.Hex(), nil + } else { + glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } + return tx.Hash().Hex(), nil } From be303ba1864d760c2d47eb9b27acbe889d1a0e29 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Wed, 17 Jun 2015 00:56:25 +0200 Subject: [PATCH 016/110] Update ethash Godep (again) --- Godeps/Godeps.json | 4 +-- .../src/github.com/ethereum/ethash/ethash.go | 3 +- .../github.com/ethereum/ethash/ethash_test.go | 28 +++++++++++++------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 24905d0bb..0607990a8 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -21,8 +21,8 @@ }, { "ImportPath": "github.com/ethereum/ethash", - "Comment": "v23.1-222-g5cfdcba", - "Rev": "5cfdcba92e634db228d1ddb140e3b7a3c4b38177" + "Comment": "v23.1-222-g173b8ff", + "Rev": "173b8ff953610c13710061e83b95b50c73d7ea50" }, { "ImportPath": "github.com/howeyc/fsnotify", diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go index ee68ab95f..73c5bf664 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go @@ -8,7 +8,6 @@ int ethashGoCallback_cgo(unsigned); import "C" import ( - "bytes" "errors" "fmt" "io/ioutil" @@ -122,7 +121,7 @@ func (l *Light) Verify(block pow.Block) bool { } // avoid mixdigest malleability as it's not included in a block's "hashNononce" - if !bytes.Equal(block.MixDigest().Bytes(), C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))) { + if block.MixDigest() != h256ToHash(ret.mix_hash) { return false } diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go index 42be77b94..e6833e343 100644 --- a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go +++ b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go @@ -39,6 +39,7 @@ var validBlocks = []*testBlock{ hashNoNonce: common.HexToHash("372eca2454ead349c3df0ab5d00b0b706b23e49d469387db91811cee0358fc6d"), difficulty: big.NewInt(132416), nonce: 0x495732e0ed7a801c, + mixDigest: common.HexToHash("2f74cdeb198af0b9abe65d22d372e22fb2d474371774a9583c1cc427a07939f5"), }, // from proof of concept nine testnet, epoch 1 { @@ -46,6 +47,7 @@ var validBlocks = []*testBlock{ hashNoNonce: common.HexToHash("7e44356ee3441623bc72a683fd3708fdf75e971bbe294f33e539eedad4b92b34"), difficulty: big.NewInt(1532671), nonce: 0x318df1c8adef7e5e, + mixDigest: common.HexToHash("144b180aad09ae3c81fb07be92c8e6351b5646dda80e6844ae1b697e55ddde84"), }, // from proof of concept nine testnet, epoch 2 { @@ -53,6 +55,7 @@ var validBlocks = []*testBlock{ hashNoNonce: common.HexToHash("5fc898f16035bf5ac9c6d9077ae1e3d5fc1ecc3c9fd5bee8bb00e810fdacbaa0"), difficulty: big.NewInt(2467358), nonce: 0x50377003e5d830ca, + mixDigest: common.HexToHash("ab546a5b73c452ae86dadd36f0ed83a6745226717d3798832d1b20b489e82063"), }, } @@ -73,8 +76,9 @@ func TestEthashConcurrentVerify(t *testing.T) { defer os.RemoveAll(eth.Full.Dir) block := &testBlock{difficulty: big.NewInt(10)} - nonce, _ := eth.Search(block, nil) + nonce, md := eth.Search(block, nil) block.nonce = nonce + block.mixDigest = common.BytesToHash(md) // Verify the block concurrently to check for data races. var wg sync.WaitGroup @@ -98,21 +102,26 @@ func TestEthashConcurrentSearch(t *testing.T) { eth.Turbo(true) defer os.RemoveAll(eth.Full.Dir) - // launch n searches concurrently. + type searchRes struct { + n uint64 + md []byte + } + var ( block = &testBlock{difficulty: big.NewInt(35000)} nsearch = 10 wg = new(sync.WaitGroup) - found = make(chan uint64) + found = make(chan searchRes) stop = make(chan struct{}) ) rand.Read(block.hashNoNonce[:]) wg.Add(nsearch) + // launch n searches concurrently. for i := 0; i < nsearch; i++ { go func() { - nonce, _ := eth.Search(block, stop) + nonce, md := eth.Search(block, stop) select { - case found <- nonce: + case found <- searchRes{n: nonce, md: md}: case <-stop: } wg.Done() @@ -120,12 +129,14 @@ func TestEthashConcurrentSearch(t *testing.T) { } // wait for one of them to find the nonce - nonce := <-found + res := <-found // stop the others close(stop) wg.Wait() - if block.nonce = nonce; !eth.Verify(block) { + block.nonce = res.n + block.mixDigest = common.BytesToHash(res.md) + if !eth.Verify(block) { t.Error("Block could not be verified") } } @@ -140,8 +151,9 @@ func TestEthashSearchAcrossEpoch(t *testing.T) { for i := epochLength - 40; i < epochLength+40; i++ { block := &testBlock{number: i, difficulty: big.NewInt(90)} rand.Read(block.hashNoNonce[:]) - nonce, _ := eth.Search(block, nil) + nonce, md := eth.Search(block, nil) block.nonce = nonce + block.mixDigest = common.BytesToHash(md) if !eth.Verify(block) { t.Fatalf("Block could not be verified") } From 5721fcf668f8ab798b6602dc6ff88726bf0c8f86 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 10:20:33 +0200 Subject: [PATCH 017/110] core/state, core/vm: cleanup refunds --- core/state/statedb.go | 22 ++++++++-------------- core/state_transition.go | 8 +++----- core/vm/vm.go | 4 ++-- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index b3050515b..895d9fe8b 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -21,7 +21,7 @@ type StateDB struct { stateObjects map[string]*StateObject - refund map[string]*big.Int + refund *big.Int thash, bhash common.Hash txIndex int @@ -31,7 +31,7 @@ type StateDB struct { // Create a new state from a given trie func New(root common.Hash, db common.Database) *StateDB { trie := trie.NewSecure(root[:], db) - return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: make(map[string]*big.Int), logs: make(map[common.Hash]Logs)} + return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: new(big.Int), logs: make(map[common.Hash]Logs)} } func (self *StateDB) PrintRoot() { @@ -63,12 +63,8 @@ func (self *StateDB) Logs() Logs { return logs } -func (self *StateDB) Refund(address common.Address, gas *big.Int) { - addr := address.Str() - if self.refund[addr] == nil { - self.refund[addr] = new(big.Int) - } - self.refund[addr].Add(self.refund[addr], gas) +func (self *StateDB) Refund(gas *big.Int) { + self.refund.Add(self.refund, gas) } /* @@ -268,9 +264,7 @@ func (self *StateDB) Copy() *StateDB { state.stateObjects[k] = stateObject.Copy() } - for addr, refund := range self.refund { - state.refund[addr] = new(big.Int).Set(refund) - } + state.refund.Set(self.refund) for hash, logs := range self.logs { state.logs[hash] = make(Logs, len(logs)) @@ -330,15 +324,15 @@ func (s *StateDB) Sync() { func (self *StateDB) Empty() { self.stateObjects = make(map[string]*StateObject) - self.refund = make(map[string]*big.Int) + self.refund = new(big.Int) } -func (self *StateDB) Refunds() map[string]*big.Int { +func (self *StateDB) Refunds() *big.Int { return self.refund } func (self *StateDB) Update() { - self.refund = make(map[string]*big.Int) + self.refund = new(big.Int) for _, stateObject := range self.stateObjects { if stateObject.dirty { diff --git a/core/state_transition.go b/core/state_transition.go index fedea8021..4a8d92375 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -241,11 +241,9 @@ func (self *StateTransition) refundGas() { sender.AddBalance(remaining) uhalf := new(big.Int).Div(self.gasUsed(), common.Big2) - for addr, ref := range self.state.Refunds() { - refund := common.BigMin(uhalf, ref) - self.gas.Add(self.gas, refund) - self.state.AddBalance(common.StringToAddress(addr), refund.Mul(refund, self.msg.GasPrice())) - } + refund := common.BigMin(uhalf, self.state.Refunds()) + self.gas.Add(self.gas, refund) + self.state.AddBalance(sender.Address(), refund.Mul(refund, self.msg.GasPrice())) coinbase.RefundGas(self.gas, self.msg.GasPrice()) } diff --git a/core/vm/vm.go b/core/vm/vm.go index c5ad761f6..0486fbbc7 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -690,7 +690,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo // 0 => non 0 g = params.SstoreSetGas } else if len(val) > 0 && len(y.Bytes()) == 0 { - statedb.Refund(self.env.Origin(), params.SstoreRefundGas) + statedb.Refund(params.SstoreRefundGas) g = params.SstoreClearGas } else { @@ -700,7 +700,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo gas.Set(g) case SUICIDE: if !statedb.IsDeleted(context.Address()) { - statedb.Refund(self.env.Origin(), params.SuicideRefundGas) + statedb.Refund(params.SuicideRefundGas) } case MLOAD: newMemSize = calcMemSize(stack.peek(), u256(32)) From 4a1e82cf3f7a5c9d7526fc01aa68466870e2a644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 17 Jun 2015 12:03:16 +0300 Subject: [PATCH 018/110] eth/downloader: fix #1280, overlapping (good/bad) delivery hang --- eth/downloader/downloader.go | 1 + eth/downloader/downloader_test.go | 34 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 306c4fd2d..c7a05eb35 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -548,6 +548,7 @@ out: peer.Demote() peer.SetIdle() glog.V(logger.Detail).Infof("%s: delivery partially failed: %v", peer, err) + go d.process() } } diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index f71c16237..53eb5f81d 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -708,6 +708,40 @@ func TestBannedChainMemoryExhaustionAttack(t *testing.T) { } } +// Tests a corner case (potential attack) where a peer delivers both good as well +// as unrequested blocks to a hash request. This may trigger a different code +// path than the fully correct or fully invalid delivery, potentially causing +// internal state problems +// +// No, don't delete this test, it actually did happen! +func TestOverlappingDeliveryAttack(t *testing.T) { + // Create an arbitrary batch of blocks ( < cache-size not to block) + targetBlocks := blockCacheLimit - 23 + hashes := createHashes(targetBlocks, knownHash) + blocks := createBlocksFromHashes(hashes) + + // Register an attacker that always returns non-requested blocks too + tester := newTester() + tester.newPeer("attack", hashes, blocks) + + rawGetBlocks := tester.downloader.peers.Peer("attack").getBlocks + tester.downloader.peers.Peer("attack").getBlocks = func(request []common.Hash) error { + // Add a non requested hash the screw the delivery (genesis should be fine) + return rawGetBlocks(append(request, hashes[0])) + } + // Test that synchronisation can complete, check for import success + if err := tester.sync("attack"); err != nil { + t.Fatalf("failed to synchronise blocks: %v", err) + } + start := time.Now() + for len(tester.ownHashes) != len(hashes) && time.Since(start) < time.Second { + time.Sleep(50 * time.Millisecond) + } + if len(tester.ownHashes) != len(hashes) { + t.Fatalf("chain length mismatch: have %v, want %v", len(tester.ownHashes), len(hashes)) + } +} + // Tests that misbehaving peers are disconnected, whilst behaving ones are not. func TestHashAttackerDropping(t *testing.T) { // Define the disconnection requirement for individual hash fetch errors From 787a61bb27b9f51f4af67c69eb8f1c5869ae3144 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 11:24:40 +0200 Subject: [PATCH 019/110] core/state, core/vm: reworked storage get / set to use common.Hash --- common/types.go | 4 ++++ core/state/state_object.go | 47 ++++++++++++++++---------------------- core/state/statedb.go | 10 ++++---- core/vm/vm.go | 15 ++++++++---- tests/vm/gh_test.go | 10 ++++---- 5 files changed, 45 insertions(+), 41 deletions(-) diff --git a/common/types.go b/common/types.go index d05c21eec..e41112a77 100644 --- a/common/types.go +++ b/common/types.go @@ -62,6 +62,10 @@ func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { return reflect.ValueOf(h) } +func EmptyHash(h Hash) bool { + return h == Hash{} +} + /////////// Address func BytesToAddress(b []byte) Address { var a Address diff --git a/core/state/state_object.go b/core/state/state_object.go index 6d2455d79..42dac632b 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -19,11 +19,11 @@ func (self Code) String() string { return string(self) //strings.Join(Disassemble(self), " ") } -type Storage map[string]*common.Value +type Storage map[string]common.Hash func (self Storage) String() (str string) { for key, value := range self { - str += fmt.Sprintf("%X : %X\n", key, value.Bytes()) + str += fmt.Sprintf("%X : %X\n", key, value) } return @@ -32,7 +32,6 @@ func (self Storage) String() (str string) { func (self Storage) Copy() Storage { cpy := make(Storage) for key, value := range self { - // XXX Do we need a 'value' copy or is this sufficient? cpy[key] = value } @@ -112,7 +111,7 @@ func NewStateObjectFromBytes(address common.Address, data []byte, db common.Data object.balance = extobject.Balance object.codeHash = extobject.CodeHash object.State = New(extobject.Root, db) - object.storage = make(map[string]*common.Value) + object.storage = make(map[string]common.Hash) object.gasPool = new(big.Int) object.prepaid = new(big.Int) object.code, _ = db.Get(extobject.CodeHash) @@ -129,35 +128,29 @@ func (self *StateObject) MarkForDeletion() { } } -func (c *StateObject) getAddr(addr common.Hash) *common.Value { - return common.NewValueFromBytes([]byte(c.State.trie.Get(addr[:]))) +func (c *StateObject) getAddr(addr common.Hash) (ret common.Hash) { + return common.BytesToHash(common.NewValueFromBytes([]byte(c.State.trie.Get(addr[:]))).Bytes()) } -func (c *StateObject) setAddr(addr []byte, value interface{}) { - c.State.trie.Update(addr, common.Encode(value)) -} - -func (self *StateObject) GetStorage(key *big.Int) *common.Value { - fmt.Printf("%v: get %v %v", self.address.Hex(), key) - return self.GetState(common.BytesToHash(key.Bytes())) -} - -func (self *StateObject) SetStorage(key *big.Int, value *common.Value) { - fmt.Printf("%v: set %v -> %v", self.address.Hex(), key, value) - self.SetState(common.BytesToHash(key.Bytes()), value) +func (c *StateObject) setAddr(addr []byte, value common.Hash) { + v, err := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) + if err != nil { + // if RLPing failed we better panic and not fail silently. This would be considered a consensus issue + panic(err) + } + c.State.trie.Update(addr, v) } func (self *StateObject) Storage() Storage { return self.storage } -func (self *StateObject) GetState(key common.Hash) *common.Value { +func (self *StateObject) GetState(key common.Hash) common.Hash { strkey := key.Str() - value := self.storage[strkey] - if value == nil { + value, exists := self.storage[strkey] + if !exists { value = self.getAddr(key) - - if !value.IsNil() { + if (value != common.Hash{}) { self.storage[strkey] = value } } @@ -165,14 +158,14 @@ func (self *StateObject) GetState(key common.Hash) *common.Value { return value } -func (self *StateObject) SetState(k common.Hash, value *common.Value) { - self.storage[k.Str()] = value.Copy() +func (self *StateObject) SetState(k, value common.Hash) { + self.storage[k.Str()] = value self.dirty = true } func (self *StateObject) Sync() { for key, value := range self.storage { - if value.Len() == 0 { + if (value == common.Hash{}) { self.State.trie.Delete([]byte(key)) continue } @@ -370,7 +363,7 @@ func (c *StateObject) RlpDecode(data []byte) { c.nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() c.State = New(common.BytesToHash(decoder.Get(2).Bytes()), c.db) //New(trie.New(common.Config.Db, decoder.Get(2).Interface())) - c.storage = make(map[string]*common.Value) + c.storage = make(map[string]common.Hash) c.gasPool = new(big.Int) c.codeHash = decoder.Get(3).Bytes() diff --git a/core/state/statedb.go b/core/state/statedb.go index 895d9fe8b..1c75ee4db 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -103,13 +103,13 @@ func (self *StateDB) GetCode(addr common.Address) []byte { return nil } -func (self *StateDB) GetState(a common.Address, b common.Hash) []byte { +func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash { stateObject := self.GetStateObject(a) if stateObject != nil { - return stateObject.GetState(b).Bytes() + return stateObject.GetState(b) } - return nil + return common.Hash{} } func (self *StateDB) IsDeleted(addr common.Address) bool { @@ -145,10 +145,10 @@ func (self *StateDB) SetCode(addr common.Address, code []byte) { } } -func (self *StateDB) SetState(addr common.Address, key common.Hash, value interface{}) { +func (self *StateDB) SetState(addr common.Address, key common.Hash, value common.Hash) { stateObject := self.GetOrNewStateObject(addr) if stateObject != nil { - stateObject.SetState(key, common.NewValue(value)) + stateObject.SetState(key, value) } } diff --git a/core/vm/vm.go b/core/vm/vm.go index 0486fbbc7..336f6cf95 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -506,14 +506,14 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) { case SLOAD: loc := common.BigToHash(stack.pop()) - val := common.Bytes2Big(statedb.GetState(context.Address(), loc)) + val := statedb.GetState(context.Address(), loc).Big() stack.push(val) case SSTORE: loc := common.BigToHash(stack.pop()) val := stack.pop() - statedb.SetState(context.Address(), loc, val) + statedb.SetState(context.Address(), loc, common.BigToHash(val)) case JUMP: if err := jump(pc, stack.pop()); err != nil { @@ -686,10 +686,10 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo var g *big.Int y, x := stack.data[stack.len()-2], stack.data[stack.len()-1] val := statedb.GetState(context.Address(), common.BigToHash(x)) - if len(val) == 0 && len(y.Bytes()) > 0 { + if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) { // 0 => non 0 g = params.SstoreSetGas - } else if len(val) > 0 && len(y.Bytes()) == 0 { + } else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) { statedb.Refund(params.SstoreRefundGas) g = params.SstoreClearGas @@ -697,6 +697,13 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo // non 0 => non 0 (or 0 => 0) g = params.SstoreClearGas } + + /* + if len(val) == 0 && len(y.Bytes()) > 0 { + } else if len(val) > 0 && len(y.Bytes()) == 0 { + } else { + } + */ gas.Set(g) case SUICIDE: if !statedb.IsDeleted(context.Address()) { diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go index a95d02576..be9e89d9c 100644 --- a/tests/vm/gh_test.go +++ b/tests/vm/gh_test.go @@ -97,7 +97,7 @@ func RunVmTest(p string, t *testing.T) { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) for a, v := range account.Storage { - obj.SetState(common.HexToHash(a), common.NewValue(helper.FromHex(v))) + obj.SetState(common.HexToHash(a), common.HexToHash(v)) } } @@ -168,11 +168,11 @@ func RunVmTest(p string, t *testing.T) { } for addr, value := range account.Storage { - v := obj.GetState(common.HexToHash(addr)).Bytes() - vexp := helper.FromHex(value) + v := obj.GetState(common.HexToHash(addr)) + vexp := common.HexToHash(value) - if bytes.Compare(v, vexp) != 0 { - t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) + if v != vexp { + t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) } } } From 30b27336ea73f7d65c62363047fa37fdd0a54de1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 11:30:42 +0200 Subject: [PATCH 020/110] core/state: remove the need for common.Value --- core/state/state_object.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/state/state_object.go b/core/state/state_object.go index 42dac632b..1deb9bf02 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -128,8 +128,10 @@ func (self *StateObject) MarkForDeletion() { } } -func (c *StateObject) getAddr(addr common.Hash) (ret common.Hash) { - return common.BytesToHash(common.NewValueFromBytes([]byte(c.State.trie.Get(addr[:]))).Bytes()) +func (c *StateObject) getAddr(addr common.Hash) common.Hash { + var ret []byte + rlp.DecodeBytes(c.State.trie.Get(addr[:]), &ret) + return common.BytesToHash(ret) } func (c *StateObject) setAddr(addr []byte, value common.Hash) { From a977f3c0dc050463e2b3c8622d289a23f0d1ce02 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 11:44:40 +0200 Subject: [PATCH 021/110] xeth, tests: fixed api --- tests/block_test_util.go | 2 +- xeth/types.go | 8 ++++---- xeth/xeth.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/block_test_util.go b/tests/block_test_util.go index ae2ae4033..200fcbd59 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -124,7 +124,7 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro obj.SetBalance(balance) obj.SetNonce(nonce) for k, v := range acct.Storage { - statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.FromHex(v)) + statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.HexToHash(v)) } } // sync objects to trie diff --git a/xeth/types.go b/xeth/types.go index 3bb1447ca..ed64dc45e 100644 --- a/xeth/types.go +++ b/xeth/types.go @@ -22,7 +22,7 @@ func NewObject(state *state.StateObject) *Object { return &Object{state} } -func (self *Object) StorageString(str string) *common.Value { +func (self *Object) StorageString(str string) []byte { if common.IsHex(str) { return self.storage(common.Hex2Bytes(str[2:])) } else { @@ -30,12 +30,12 @@ func (self *Object) StorageString(str string) *common.Value { } } -func (self *Object) StorageValue(addr *common.Value) *common.Value { +func (self *Object) StorageValue(addr *common.Value) []byte { return self.storage(addr.Bytes()) } -func (self *Object) storage(addr []byte) *common.Value { - return self.StateObject.GetStorage(common.BigD(addr)) +func (self *Object) storage(addr []byte) []byte { + return self.StateObject.GetState(common.BytesToHash(addr)).Bytes() } func (self *Object) Storage() (storage map[string]string) { diff --git a/xeth/xeth.go b/xeth/xeth.go index 71753d6bd..d68f48d50 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -488,7 +488,7 @@ func (self *XEth) NumberToHuman(balance string) string { } func (self *XEth) StorageAt(addr, storageAddr string) string { - return common.ToHex(self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr))) + return self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex() } func (self *XEth) BalanceAt(addr string) string { From aaddc99c35f1fcc9b5d7198dd6571dfa43718ae8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 12:53:22 +0200 Subject: [PATCH 022/110] core/state: fixed state tests --- core/state/state_test.go | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/core/state/state_test.go b/core/state/state_test.go index 09a65de54..00e133dab 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -70,37 +70,34 @@ func TestNull(t *testing.T) { address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") state.CreateAccount(address) //value := common.FromHex("0x823140710bf13990e4500136726d8b55") - value := make([]byte, 16) + var value common.Hash state.SetState(address, common.Hash{}, value) state.Update() state.Sync() value = state.GetState(address, common.Hash{}) + if !common.EmptyHash(value) { + t.Errorf("expected empty hash. got %x", value) + } } func (s *StateSuite) TestSnapshot(c *checker.C) { stateobjaddr := toAddr([]byte("aa")) - storageaddr := common.Big("0") - data1 := common.NewValue(42) - data2 := common.NewValue(43) + var storageaddr common.Hash + data1 := common.BytesToHash([]byte{42}) + data2 := common.BytesToHash([]byte{43}) - // get state object - stateObject := s.state.GetOrNewStateObject(stateobjaddr) // set inital state object value - stateObject.SetStorage(storageaddr, data1) + s.state.SetState(stateobjaddr, storageaddr, data1) // get snapshot of current state snapshot := s.state.Copy() - // get state object. is this strictly necessary? - stateObject = s.state.GetStateObject(stateobjaddr) // set new state object value - stateObject.SetStorage(storageaddr, data2) + s.state.SetState(stateobjaddr, storageaddr, data2) // restore snapshot s.state.Set(snapshot) - // get state object - stateObject = s.state.GetStateObject(stateobjaddr) // get state storage value - res := stateObject.GetStorage(storageaddr) + res := s.state.GetState(stateobjaddr, storageaddr) c.Assert(data1, checker.DeepEquals, res) } From aa699a1283c93740bba15f94c774d92ea6fe1980 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 13:27:51 +0200 Subject: [PATCH 023/110] core/state: removed state from state object --- core/state/dump.go | 6 +++--- core/state/state_object.go | 33 +++++++++++++++------------------ core/state/statedb.go | 12 ++---------- 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/core/state/dump.go b/core/state/dump.go index 70ea21691..f6f2f9029 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -34,7 +34,7 @@ func (self *StateDB) RawDump() World { account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: common.Bytes2Hex(stateObject.Root()), CodeHash: common.Bytes2Hex(stateObject.codeHash)} account.Storage = make(map[string]string) - storageIt := stateObject.State.trie.Iterator() + storageIt := stateObject.trie.Iterator() for storageIt.Next() { account.Storage[common.Bytes2Hex(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value) } @@ -54,8 +54,8 @@ func (self *StateDB) Dump() []byte { // Debug stuff func (self *StateObject) CreateOutputForDiff() { - fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.nonce) - it := self.State.trie.Iterator() + fmt.Printf("%x %x %x %x\n", self.Address(), self.Root(), self.balance.Bytes(), self.nonce) + it := self.trie.Iterator() for it.Next() { fmt.Printf("%x %x\n", it.Key, it.Value) } diff --git a/core/state/state_object.go b/core/state/state_object.go index 1deb9bf02..2e4fe3269 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -40,9 +40,8 @@ func (self Storage) Copy() Storage { type StateObject struct { // State database for storing state changes - db common.Database - // The state object - State *StateDB + db common.Database + trie *trie.SecureTrie // Address belonging to this account address common.Address @@ -75,7 +74,6 @@ type StateObject struct { func (self *StateObject) Reset() { self.storage = make(Storage) - self.State.Reset() } func NewStateObject(address common.Address, db common.Database) *StateObject { @@ -83,7 +81,7 @@ func NewStateObject(address common.Address, db common.Database) *StateObject { //address := common.ToAddress(addr) object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true} - object.State = New(common.Hash{}, db) //New(trie.New(common.Config.Db, "")) + object.trie = trie.NewSecure((common.Hash{}).Bytes(), db) object.storage = make(Storage) object.gasPool = new(big.Int) object.prepaid = new(big.Int) @@ -110,7 +108,7 @@ func NewStateObjectFromBytes(address common.Address, data []byte, db common.Data object.nonce = extobject.Nonce object.balance = extobject.Balance object.codeHash = extobject.CodeHash - object.State = New(extobject.Root, db) + object.trie = trie.NewSecure(extobject.Root[:], db) object.storage = make(map[string]common.Hash) object.gasPool = new(big.Int) object.prepaid = new(big.Int) @@ -130,7 +128,7 @@ func (self *StateObject) MarkForDeletion() { func (c *StateObject) getAddr(addr common.Hash) common.Hash { var ret []byte - rlp.DecodeBytes(c.State.trie.Get(addr[:]), &ret) + rlp.DecodeBytes(c.trie.Get(addr[:]), &ret) return common.BytesToHash(ret) } @@ -140,7 +138,7 @@ func (c *StateObject) setAddr(addr []byte, value common.Hash) { // if RLPing failed we better panic and not fail silently. This would be considered a consensus issue panic(err) } - c.State.trie.Update(addr, v) + c.trie.Update(addr, v) } func (self *StateObject) Storage() Storage { @@ -165,10 +163,11 @@ func (self *StateObject) SetState(k, value common.Hash) { self.dirty = true } -func (self *StateObject) Sync() { +// Update updates the current cached storage to the trie +func (self *StateObject) Update() { for key, value := range self.storage { if (value == common.Hash{}) { - self.State.trie.Delete([]byte(key)) + self.trie.Delete([]byte(key)) continue } @@ -261,9 +260,7 @@ func (self *StateObject) Copy() *StateObject { stateObject.balance.Set(self.balance) stateObject.codeHash = common.CopyBytes(self.codeHash) stateObject.nonce = self.nonce - if self.State != nil { - stateObject.State = self.State.Copy() - } + stateObject.trie = self.trie stateObject.code = common.CopyBytes(self.code) stateObject.initCode = common.CopyBytes(self.initCode) stateObject.storage = self.storage.Copy() @@ -301,11 +298,11 @@ func (c *StateObject) Init() Code { } func (self *StateObject) Trie() *trie.SecureTrie { - return self.State.trie + return self.trie } func (self *StateObject) Root() []byte { - return self.Trie().Root() + return self.trie.Root() } func (self *StateObject) Code() []byte { @@ -337,10 +334,10 @@ func (self *StateObject) EachStorage(cb func(key, value []byte)) { cb([]byte(h), v.Bytes()) } - it := self.State.trie.Iterator() + it := self.trie.Iterator() for it.Next() { // ignore cached values - key := self.State.trie.GetKey(it.Key) + key := self.trie.GetKey(it.Key) if _, ok := self.storage[string(key)]; !ok { cb(key, it.Value) } @@ -364,7 +361,7 @@ func (c *StateObject) RlpDecode(data []byte) { decoder := common.NewValueFromBytes(data) c.nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() - c.State = New(common.BytesToHash(decoder.Get(2).Bytes()), c.db) //New(trie.New(common.Config.Db, decoder.Get(2).Interface())) + c.trie = trie.NewSecure(decoder.Get(2).Bytes(), c.db) c.storage = make(map[string]common.Hash) c.gasPool = new(big.Int) diff --git a/core/state/statedb.go b/core/state/statedb.go index 1c75ee4db..134c4b3c7 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -296,10 +296,6 @@ func (s *StateDB) Reset() { // Reset all nested states for _, stateObject := range s.stateObjects { - if stateObject.State == nil { - continue - } - stateObject.Reset() } @@ -310,11 +306,7 @@ func (s *StateDB) Reset() { func (s *StateDB) Sync() { // Sync all nested states for _, stateObject := range s.stateObjects { - if stateObject.State == nil { - continue - } - - stateObject.State.Sync() + stateObject.trie.Commit() } s.trie.Commit() @@ -339,7 +331,7 @@ func (self *StateDB) Update() { if stateObject.remove { self.DeleteStateObject(stateObject) } else { - stateObject.Sync() + stateObject.Update() self.UpdateStateObject(stateObject) } From bdd63837ea20f3103cd44a2fb76591be074dcade Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 13:39:19 +0200 Subject: [PATCH 024/110] core/state: removed trie copy --- core/state/statedb.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 134c4b3c7..f6f63f329 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -259,7 +259,7 @@ func (s *StateDB) Cmp(other *StateDB) bool { func (self *StateDB) Copy() *StateDB { state := New(common.Hash{}, self.db) - state.trie = self.trie.Copy() + state.trie = self.trie for k, stateObject := range self.stateObjects { state.stateObjects[k] = stateObject.Copy() } From 753d62a4ddd974a1410b1ed3ee92a30115a1e0df Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 14:14:17 +0200 Subject: [PATCH 025/110] core: TMP testing code --- core/block_processor.go | 23 ++++++++--------------- core/vm/context.go | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index c01b110be..748750e32 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -246,25 +246,18 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st return } - // store the receipts - err = putReceipts(sm.extraDb, block.Hash(), receipts) - if err != nil { - return nil, err - } - // Sync the current block's state to the database state.Sync() - // This puts transactions in a extra db for rpc - for i, tx := range block.Transactions() { - putTx(sm.extraDb, tx, block, uint64(i)) - } + go func() { + // This puts transactions in a extra db for rpc + for i, tx := range block.Transactions() { + putTx(sm.extraDb, tx, block, uint64(i)) + } - receiptsRlp := receipts.RlpEncode() - /*if len(receipts) > 0 { - glog.V(logger.Info).Infof("Saving %v receipts, rlp len is %v\n", len(receipts), len(receiptsRlp)) - }*/ - sm.extraDb.Put(append(receiptsPre, block.Hash().Bytes()...), receiptsRlp) + // store the receipts + putReceipts(sm.extraDb, block.Hash(), receipts) + }() return state.Logs(), nil } diff --git a/core/vm/context.go b/core/vm/context.go index e33324b53..56e8f925a 100644 --- a/core/vm/context.go +++ b/core/vm/context.go @@ -26,16 +26,25 @@ type Context struct { Args []byte } +var dests destinations + +func init() { + dests = make(destinations) +} + // Create a new context for the given data items. func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int) *Context { c := &Context{caller: caller, self: object, Args: nil} - if parent, ok := caller.(*Context); ok { - // Reuse JUMPDEST analysis from parent context if available. - c.jumpdests = parent.jumpdests - } else { - c.jumpdests = make(destinations) - } + /* + if parent, ok := caller.(*Context); ok { + // Reuse JUMPDEST analysis from parent context if available. + c.jumpdests = parent.jumpdests + } else { + c.jumpdests = make(destinations) + } + */ + c.jumpdests = dests // Gas should be a pointer so it can safely be reduced through the run // This pointer will be off the state transition From f5abc9f188fb684e3601314b8ae454ac5abbf0e9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Jun 2015 17:09:39 +0200 Subject: [PATCH 026/110] core, core/vm: state improvements and tx pool speed up Removed full tx validation during state transitions --- core/block_processor.go | 14 ++++++-------- core/transaction_pool.go | 22 +++++++++++++--------- core/vm/context.go | 21 ++++++--------------- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index 748750e32..c6df2d0f4 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -249,15 +249,13 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st // Sync the current block's state to the database state.Sync() - go func() { - // This puts transactions in a extra db for rpc - for i, tx := range block.Transactions() { - putTx(sm.extraDb, tx, block, uint64(i)) - } + // This puts transactions in a extra db for rpc + for i, tx := range block.Transactions() { + putTx(sm.extraDb, tx, block, uint64(i)) + } - // store the receipts - putReceipts(sm.extraDb, block.Hash(), receipts) - }() + // store the receipts + putReceipts(sm.extraDb, block.Hash(), receipts) return state.Logs(), nil } diff --git a/core/transaction_pool.go b/core/transaction_pool.go index e31f5c6b3..5ebe3576b 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -105,7 +105,9 @@ func (pool *TxPool) resetState() { if addr, err := tx.From(); err == nil { // Set the nonce. Transaction nonce can never be lower // than the state nonce; validatePool took care of that. - pool.pendingState.SetNonce(addr, tx.Nonce()) + if pool.pendingState.GetNonce(addr) < tx.Nonce() { + pool.pendingState.SetNonce(addr, tx.Nonce()) + } } } @@ -153,6 +155,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error { return ErrNonExistentAccount } + // Last but not least check for nonce errors + if pool.currentState().GetNonce(from) > tx.Nonce() { + return ErrNonce + } + // Check the transaction doesn't exceed the current // block limit gas. if pool.gasLimit().Cmp(tx.GasLimit) < 0 { @@ -179,12 +186,6 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error { return ErrIntrinsicGas } - // Last but not least check for nonce errors (intensive - // operation, saved for last) - if pool.currentState().GetNonce(from) > tx.Nonce() { - return ErrNonce - } - return nil } @@ -394,10 +395,13 @@ func (pool *TxPool) removeTx(hash common.Hash) { // validatePool removes invalid and processed transactions from the main pool. func (pool *TxPool) validatePool() { + state := pool.currentState() for hash, tx := range pool.pending { - if err := pool.validateTx(tx); err != nil { + from, _ := tx.From() // err already checked + // perform light nonce validation + if state.GetNonce(from) > tx.Nonce() { if glog.V(logger.Core) { - glog.Infof("removed tx (%x) from pool: %v\n", hash[:4], err) + glog.Infof("removed tx (%x) from pool: low tx nonce\n", hash[:4]) } delete(pool.pending, hash) } diff --git a/core/vm/context.go b/core/vm/context.go index 56e8f925a..e33324b53 100644 --- a/core/vm/context.go +++ b/core/vm/context.go @@ -26,25 +26,16 @@ type Context struct { Args []byte } -var dests destinations - -func init() { - dests = make(destinations) -} - // Create a new context for the given data items. func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int) *Context { c := &Context{caller: caller, self: object, Args: nil} - /* - if parent, ok := caller.(*Context); ok { - // Reuse JUMPDEST analysis from parent context if available. - c.jumpdests = parent.jumpdests - } else { - c.jumpdests = make(destinations) - } - */ - c.jumpdests = dests + if parent, ok := caller.(*Context); ok { + // Reuse JUMPDEST analysis from parent context if available. + c.jumpdests = parent.jumpdests + } else { + c.jumpdests = make(destinations) + } // Gas should be a pointer so it can safely be reduced through the run // This pointer will be off the state transition From 5afebc2a4b490bef9618c3f55a8c52e25ab716ef Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 17 Jun 2015 18:07:45 +0200 Subject: [PATCH 027/110] unit test coverage for NewDataArgs --- rpc/args_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/rpc/args_test.go b/rpc/args_test.go index 81a2972cd..fd20dbab8 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -2577,3 +2577,57 @@ func TestSigArgsEmpty(t *testing.T) { t.Error(str) } } + +func TestDataArgs(t *testing.T) { + input := `["0x0123"]` + expected := new(NewDataArgs) + expected.Data = "0x0123" + + args := new(NewDataArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err) + } + + if expected.Data != args.Data { + t.Errorf("Data should be %v but is %v", expected.Data, args.Data) + } +} + +func TestDataArgsEmptyData(t *testing.T) { + input := `[""]` + + args := new(NewDataArgs) + str := ExpectValidationError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDataArgsDataType(t *testing.T) { + input := `[13]` + + args := new(NewDataArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDataArgsEmpty(t *testing.T) { + input := `[]` + args := new(NewDataArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDataArgsInvalid(t *testing.T) { + input := `{}` + + args := new(NewDataArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} From 2f4cbe22f5207b830f2685caae175cce70bcd231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 00:04:57 +0300 Subject: [PATCH 028/110] eth, eth/downloader: fix processing interrupt caused by temp cancel --- eth/downloader/downloader.go | 40 +++++++++++++++---------------- eth/downloader/downloader_test.go | 4 ++-- eth/sync.go | 2 +- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index c7a05eb35..a79eabb3c 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -87,6 +87,8 @@ type Downloader struct { checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain banned *set.Set // Set of hashes we've received and banned + interrupt int32 // Atomic boolean to signal termination + // Statistics importStart time.Time // Instance when the last blocks were taken from the cache importQueue []*Block // Previously taken blocks to check import progress @@ -245,12 +247,6 @@ func (d *Downloader) synchronise(id string, hash common.Hash) error { if atomic.CompareAndSwapInt32(&d.notified, 0, 1) { glog.V(logger.Info).Infoln("Block synchronisation started") } - - // Create cancel channel for aborting mid-flight - d.cancelLock.Lock() - d.cancelCh = make(chan struct{}) - d.cancelLock.Unlock() - // Abort if the queue still contains some leftover data if _, cached := d.queue.Size(); cached > 0 && d.queue.GetHeadBlock() != nil { return errPendingQueue @@ -260,12 +256,16 @@ func (d *Downloader) synchronise(id string, hash common.Hash) error { d.peers.Reset() d.checks = make(map[common.Hash]*crossCheck) + // Create cancel channel for aborting mid-flight + d.cancelLock.Lock() + d.cancelCh = make(chan struct{}) + d.cancelLock.Unlock() + // Retrieve the origin peer and initiate the downloading process p := d.peers.Peer(id) if p == nil { return errUnknownPeer } - return d.syncWithPeer(p, hash) } @@ -282,7 +282,7 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash) (err error) { defer func() { // reset on error if err != nil { - d.Cancel() + d.cancel() d.mux.Post(FailedEvent{err}) } else { d.mux.Post(DoneEvent{}) @@ -301,9 +301,9 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash) (err error) { return nil } -// Cancel cancels all of the operations and resets the queue. It returns true +// cancel cancels all of the operations and resets the queue. It returns true // if the cancel operation was completed. -func (d *Downloader) Cancel() { +func (d *Downloader) cancel() { // Close the current cancel channel d.cancelLock.Lock() if d.cancelCh != nil { @@ -320,6 +320,12 @@ func (d *Downloader) Cancel() { d.queue.Reset() } +// Terminate interrupts the downloader, canceling all pending operations. +func (d *Downloader) Terminate() { + atomic.StoreInt32(&d.interrupt, 1) + d.cancel() +} + // fetchHahes starts retrieving hashes backwards from a specific peer and hash, // up until it finds a common ancestor. If the source peer times out, alternative // ones are tried for continuation. @@ -737,12 +743,6 @@ func (d *Downloader) process() (err error) { atomic.StoreInt32(&d.processing, 0) }() - - // Fetch the current cancel channel to allow termination - d.cancelLock.RLock() - cancel := d.cancelCh - d.cancelLock.RUnlock() - // Repeat the processing as long as there are blocks to import for { // Fetch the next batch of blocks @@ -759,12 +759,10 @@ func (d *Downloader) process() (err error) { // Actually import the blocks glog.V(logger.Debug).Infof("Inserting chain with %d blocks (#%v - #%v)\n", len(blocks), blocks[0].RawBlock.Number(), blocks[len(blocks)-1].RawBlock.Number()) - for len(blocks) != 0 { // TODO: quit + for len(blocks) != 0 { // Check for any termination requests - select { - case <-cancel: + if atomic.LoadInt32(&d.interrupt) == 1 { return errCancelChainImport - default: } // Retrieve the first batch of blocks to insert max := int(math.Min(float64(len(blocks)), float64(maxBlockProcess))) @@ -777,7 +775,7 @@ func (d *Downloader) process() (err error) { if err != nil { glog.V(logger.Debug).Infof("Block #%d import failed: %v", raw[index].NumberU64(), err) d.dropPeer(blocks[index].OriginPeer) - d.Cancel() + d.cancel() return errCancelChainImport } blocks = blocks[max:] diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 53eb5f81d..f97e6077b 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -247,7 +247,7 @@ func TestCancel(t *testing.T) { tester.newPeer("peer", hashes, blocks) // Make sure canceling works with a pristine downloader - tester.downloader.Cancel() + tester.downloader.cancel() hashCount, blockCount := tester.downloader.queue.Size() if hashCount > 0 || blockCount > 0 { t.Errorf("block or hash count mismatch: %d hashes, %d blocks, want 0", hashCount, blockCount) @@ -256,7 +256,7 @@ func TestCancel(t *testing.T) { if err := tester.sync("peer"); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } - tester.downloader.Cancel() + tester.downloader.cancel() hashCount, blockCount = tester.downloader.queue.Size() if hashCount > 0 || blockCount > 0 { t.Errorf("block or hash count mismatch: %d hashes, %d blocks, want 0", hashCount, blockCount) diff --git a/eth/sync.go b/eth/sync.go index a3b177a4d..751bc1a2a 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -251,7 +251,7 @@ func (pm *ProtocolManager) fetcher() { // downloading hashes and blocks as well as retrieving cached ones. func (pm *ProtocolManager) syncer() { // Abort any pending syncs if we terminate - defer pm.downloader.Cancel() + defer pm.downloader.Terminate() forceSync := time.Tick(forceSyncCycle) for { From 55dd8fd6216e8880f441975f32eb070be5d401a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 00:26:54 +0300 Subject: [PATCH 029/110] eth/downloader: always reenter processing if not exiting --- eth/downloader/downloader.go | 45 +++++++++++++++---------------- eth/downloader/downloader_test.go | 31 +++++++++++---------- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index a79eabb3c..9866a5b46 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -33,23 +33,22 @@ var ( ) var ( - errBusy = errors.New("busy") - errUnknownPeer = errors.New("peer is unknown or unhealthy") - errBadPeer = errors.New("action from bad peer ignored") - errStallingPeer = errors.New("peer is stalling") - errBannedHead = errors.New("peer head hash already banned") - errNoPeers = errors.New("no peers to keep download active") - errPendingQueue = errors.New("pending items in queue") - errTimeout = errors.New("timeout") - errEmptyHashSet = errors.New("empty hash set by peer") - errPeersUnavailable = errors.New("no peers available or all peers tried for block download process") - errAlreadyInPool = errors.New("hash already in pool") - errInvalidChain = errors.New("retrieved hash chain is invalid") - errCrossCheckFailed = errors.New("block cross-check failed") - errCancelHashFetch = errors.New("hash fetching canceled (requested)") - errCancelBlockFetch = errors.New("block downloading canceled (requested)") - errCancelChainImport = errors.New("chain importing canceled (requested)") - errNoSyncActive = errors.New("no sync active") + errBusy = errors.New("busy") + errUnknownPeer = errors.New("peer is unknown or unhealthy") + errBadPeer = errors.New("action from bad peer ignored") + errStallingPeer = errors.New("peer is stalling") + errBannedHead = errors.New("peer head hash already banned") + errNoPeers = errors.New("no peers to keep download active") + errPendingQueue = errors.New("pending items in queue") + errTimeout = errors.New("timeout") + errEmptyHashSet = errors.New("empty hash set by peer") + errPeersUnavailable = errors.New("no peers available or all peers tried for block download process") + errAlreadyInPool = errors.New("hash already in pool") + errInvalidChain = errors.New("retrieved hash chain is invalid") + errCrossCheckFailed = errors.New("block cross-check failed") + errCancelHashFetch = errors.New("hash fetching canceled (requested)") + errCancelBlockFetch = errors.New("block downloading canceled (requested)") + errNoSyncActive = errors.New("no sync active") ) // hashCheckFn is a callback type for verifying a hash's presence in the local chain. @@ -719,7 +718,7 @@ func (d *Downloader) banBlocks(peerId string, head common.Hash) error { // between these state changes, a block may have arrived, but a processing // attempt denied, so we need to re-enter to ensure the block isn't left // to idle in the cache. -func (d *Downloader) process() (err error) { +func (d *Downloader) process() { // Make sure only one goroutine is ever allowed to process blocks at once if !atomic.CompareAndSwapInt32(&d.processing, 0, 1) { return @@ -729,8 +728,8 @@ func (d *Downloader) process() (err error) { // the fresh blocks might have been rejected entry to to this present thread // not yet releasing the `processing` state. defer func() { - if err == nil && d.queue.GetHeadBlock() != nil { - err = d.process() + if atomic.LoadInt32(&d.interrupt) == 0 && d.queue.GetHeadBlock() != nil { + d.process() } }() // Release the lock upon exit (note, before checking for reentry!), and set @@ -748,7 +747,7 @@ func (d *Downloader) process() (err error) { // Fetch the next batch of blocks blocks := d.queue.TakeBlocks() if len(blocks) == 0 { - return nil + return } // Reset the import statistics d.importLock.Lock() @@ -762,7 +761,7 @@ func (d *Downloader) process() (err error) { for len(blocks) != 0 { // Check for any termination requests if atomic.LoadInt32(&d.interrupt) == 1 { - return errCancelChainImport + return } // Retrieve the first batch of blocks to insert max := int(math.Min(float64(len(blocks)), float64(maxBlockProcess))) @@ -776,7 +775,7 @@ func (d *Downloader) process() (err error) { glog.V(logger.Debug).Infof("Block #%d import failed: %v", raw[index].NumberU64(), err) d.dropPeer(blocks[index].OriginPeer) d.cancel() - return errCancelChainImport + return } blocks = blocks[max:] } diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index f97e6077b..40f77e7db 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -749,22 +749,21 @@ func TestHashAttackerDropping(t *testing.T) { result error drop bool }{ - {nil, false}, // Sync succeeded, all is well - {errBusy, false}, // Sync is already in progress, no problem - {errUnknownPeer, false}, // Peer is unknown, was already dropped, don't double drop - {errBadPeer, true}, // Peer was deemed bad for some reason, drop it - {errStallingPeer, true}, // Peer was detected to be stalling, drop it - {errBannedHead, true}, // Peer's head hash is a known bad hash, drop it - {errNoPeers, false}, // No peers to download from, soft race, no issue - {errPendingQueue, false}, // There are blocks still cached, wait to exhaust, no issue - {errTimeout, true}, // No hashes received in due time, drop the peer - {errEmptyHashSet, true}, // No hashes were returned as a response, drop as it's a dead end - {errPeersUnavailable, true}, // Nobody had the advertised blocks, drop the advertiser - {errInvalidChain, true}, // Hash chain was detected as invalid, definitely drop - {errCrossCheckFailed, true}, // Hash-origin failed to pass a block cross check, drop - {errCancelHashFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop - {errCancelBlockFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop - {errCancelChainImport, false}, // Synchronisation was canceled, origin may be innocent, don't drop + {nil, false}, // Sync succeeded, all is well + {errBusy, false}, // Sync is already in progress, no problem + {errUnknownPeer, false}, // Peer is unknown, was already dropped, don't double drop + {errBadPeer, true}, // Peer was deemed bad for some reason, drop it + {errStallingPeer, true}, // Peer was detected to be stalling, drop it + {errBannedHead, true}, // Peer's head hash is a known bad hash, drop it + {errNoPeers, false}, // No peers to download from, soft race, no issue + {errPendingQueue, false}, // There are blocks still cached, wait to exhaust, no issue + {errTimeout, true}, // No hashes received in due time, drop the peer + {errEmptyHashSet, true}, // No hashes were returned as a response, drop as it's a dead end + {errPeersUnavailable, true}, // Nobody had the advertised blocks, drop the advertiser + {errInvalidChain, true}, // Hash chain was detected as invalid, definitely drop + {errCrossCheckFailed, true}, // Hash-origin failed to pass a block cross check, drop + {errCancelHashFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop + {errCancelBlockFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop } // Run the tests and check disconnection status tester := newTester() From 4365668462a1f3b1f637388ff33b714529536f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 00:42:02 +0300 Subject: [PATCH 030/110] eth/downloader: extend slow test to fix even slower CI server... --- eth/downloader/downloader_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 40f77e7db..484cc3218 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -359,7 +359,7 @@ func TestSlowSynchronisation(t *testing.T) { // Create a batch of blocks, with a slow and a full speed peer targetCycles := 2 targetBlocks := targetCycles*blockCacheLimit - 15 - targetIODelay := 500 * time.Millisecond + targetIODelay := time.Second hashes := createHashes(targetBlocks, knownHash) blocks := createBlocksFromHashes(hashes) From 15e169e5b6566b77aba23cc04c2f19a94ff23738 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Jun 2015 11:37:30 +0200 Subject: [PATCH 031/110] core: ValidatedHeader (method => function) Changed header validation method to function in preparation of @karalabe's PR. --- core/block_processor.go | 126 +++++++++++++++++------------------ core/block_processor_test.go | 8 ++- 2 files changed, 68 insertions(+), 66 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index c6df2d0f4..c78d419ce 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -185,7 +185,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st state := state.New(parent.Root(), sm.db) // Block validation - if err = sm.ValidateHeader(block.Header(), parent.Header(), false); err != nil { + if err = ValidateHeader(sm.Pow, block.Header(), parent.Header(), false); err != nil { return } @@ -260,67 +260,6 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st return state.Logs(), nil } -// See YP section 4.3.4. "Block Header Validity" -// Validates a block. Returns an error if the block is invalid. -func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error { - if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 { - return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) - } - - expd := CalcDifficulty(block, parent) - if expd.Cmp(block.Difficulty) != 0 { - return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) - } - - a := new(big.Int).Sub(block.GasLimit, parent.GasLimit) - a.Abs(a) - b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor) - if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { - return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) - } - - if int64(block.Time) > time.Now().Unix() { - return BlockFutureErr - } - - if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 { - return BlockNumberErr - } - - if block.Time <= parent.Time { - return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) - } - - if checkPow { - // Verify the nonce of the block. Return an error if it's not valid - if !sm.Pow.Verify(types.NewBlockWithHeader(block)) { - return ValidationError("Block's nonce is invalid (= %x)", block.Nonce) - } - } - - return nil -} - -func AccumulateRewards(statedb *state.StateDB, block *types.Block) { - reward := new(big.Int).Set(BlockReward) - - for _, uncle := range block.Uncles() { - num := new(big.Int).Add(big.NewInt(8), uncle.Number) - num.Sub(num, block.Number()) - - r := new(big.Int) - r.Mul(BlockReward, num) - r.Div(r, big.NewInt(8)) - - statedb.AddBalance(uncle.Coinbase, r) - - reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) - } - - // Get the account associated with the coinbase - statedb.AddBalance(block.Header().Coinbase, reward) -} - func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *types.Block) error { ancestors := set.New() uncles := set.New() @@ -358,7 +297,7 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4]) } - if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash], true); err != nil { + if err := ValidateHeader(sm.Pow, uncle, ancestorHeaders[uncle.ParentHash], true); err != nil { return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err)) } } @@ -395,6 +334,67 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro return state.Logs(), nil } +// See YP section 4.3.4. "Block Header Validity" +// Validates a block. Returns an error if the block is invalid. +func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) error { + if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 { + return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) + } + + expd := CalcDifficulty(block, parent) + if expd.Cmp(block.Difficulty) != 0 { + return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) + } + + a := new(big.Int).Sub(block.GasLimit, parent.GasLimit) + a.Abs(a) + b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor) + if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { + return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) + } + + if int64(block.Time) > time.Now().Unix() { + return BlockFutureErr + } + + if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 { + return BlockNumberErr + } + + if block.Time <= parent.Time { + return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) + } + + if checkPow { + // Verify the nonce of the block. Return an error if it's not valid + if !pow.Verify(types.NewBlockWithHeader(block)) { + return ValidationError("Block's nonce is invalid (= %x)", block.Nonce) + } + } + + return nil +} + +func AccumulateRewards(statedb *state.StateDB, block *types.Block) { + reward := new(big.Int).Set(BlockReward) + + for _, uncle := range block.Uncles() { + num := new(big.Int).Add(big.NewInt(8), uncle.Number) + num.Sub(num, block.Number()) + + r := new(big.Int) + r.Mul(BlockReward, num) + r.Div(r, big.NewInt(8)) + + statedb.AddBalance(uncle.Coinbase, r) + + reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) + } + + // Get the account associated with the coinbase + statedb.AddBalance(block.Header().Coinbase, reward) +} + func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) { var rdata []byte rdata, err = db.Get(append(receiptsPre, bhash[:]...)) diff --git a/core/block_processor_test.go b/core/block_processor_test.go index 97b80038d..e38c815ef 100644 --- a/core/block_processor_test.go +++ b/core/block_processor_test.go @@ -26,18 +26,20 @@ func proc() (*BlockProcessor, *ChainManager) { } func TestNumber(t *testing.T) { - bp, chain := proc() + _, chain := proc() block1 := chain.NewBlock(common.Address{}) block1.Header().Number = big.NewInt(3) block1.Header().Time-- - err := bp.ValidateHeader(block1.Header(), chain.Genesis().Header(), false) + pow := ezp.New() + + err := ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false) if err != BlockNumberErr { t.Errorf("expected block number error %v", err) } block1 = chain.NewBlock(common.Address{}) - err = bp.ValidateHeader(block1.Header(), chain.Genesis().Header(), false) + err = ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false) if err == BlockNumberErr { t.Errorf("didn't expect block number error") } From 430bcdb21959e018fbc93bac0ccd8bbfa2fd5afb Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Jun 2015 12:25:02 +0200 Subject: [PATCH 032/110] core/vm: clarified SSTORE --- core/vm/vm.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/vm/vm.go b/core/vm/vm.go index 336f6cf95..9e092300d 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -686,6 +686,11 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo var g *big.Int y, x := stack.data[stack.len()-2], stack.data[stack.len()-1] val := statedb.GetState(context.Address(), common.BigToHash(x)) + + // This checks for 3 scenario's and calculates gas accordingly + // 1. From a zero-value address to a non-zero value (NEW VALUE) + // 2. From a non-zero value address to a zero-value address (DELETE) + // 3. From a nen-zero to a non-zero (CHANGE) if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) { // 0 => non 0 g = params.SstoreSetGas @@ -697,13 +702,6 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo // non 0 => non 0 (or 0 => 0) g = params.SstoreClearGas } - - /* - if len(val) == 0 && len(y.Bytes()) > 0 { - } else if len(val) > 0 && len(y.Bytes()) == 0 { - } else { - } - */ gas.Set(g) case SUICIDE: if !statedb.IsDeleted(context.Address()) { From 7c2af1c11722dc3175a98342c060afcfaf6a275f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 11:58:32 +0300 Subject: [PATCH 033/110] eth, eth/fetcher: separate notification sync mechanism --- eth/downloader/downloader.go | 1 + eth/fetcher/fetcher.go | 258 +++++++++++++++++++++++++++++++++++ eth/handler.go | 71 ++++------ eth/sync.go | 145 ++------------------ 4 files changed, 293 insertions(+), 182 deletions(-) create mode 100644 eth/fetcher/fetcher.go diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 9866a5b46..18e5f50e8 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -1,3 +1,4 @@ +// Package downloader contains the manual full chain synchronisation. package downloader import ( diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go new file mode 100644 index 000000000..19c53048c --- /dev/null +++ b/eth/fetcher/fetcher.go @@ -0,0 +1,258 @@ +// Package fetcher contains the block announcement based synchonisation. +package fetcher + +import ( + "errors" + "math/rand" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" +) + +const ( + arriveTimeout = 500 * time.Millisecond // Time allowance before an announced block is explicitly requested + fetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block +) + +var ( + errTerminated = errors.New("terminated") +) + +// hashCheckFn is a callback type for verifying a hash's presence in the local chain. +type hashCheckFn func(common.Hash) bool + +// blockRequesterFn is a callback type for sending a block retrieval request. +type blockRequesterFn func([]common.Hash) error + +// blockImporterFn is a callback type for trying to inject a block into the local chain. +type blockImporterFn func(peer string, block *types.Block) error + +// announce is the hash notification of the availability of a new block in the +// network. +type announce struct { + hash common.Hash // Hash of the block being announced + time time.Time // Timestamp of the announcement + + origin string // Identifier of the peer originating the notification + fetch blockRequesterFn // Fetcher function to retrieve +} + +// Fetcher is responsible for accumulating block announcements from various peers +// and scheduling them for retrieval. +type Fetcher struct { + // Various event channels + notify chan *announce + filter chan chan []*types.Block + quit chan struct{} + + // Callbacks + hasBlock hashCheckFn // Checks if a block is present in the chain + importBlock blockImporterFn // Injects a block from an origin peer into the chain +} + +// New creates a block fetcher to retrieve blocks based on hash announcements. +func New(hasBlock hashCheckFn, importBlock blockImporterFn) *Fetcher { + return &Fetcher{ + notify: make(chan *announce), + filter: make(chan chan []*types.Block), + quit: make(chan struct{}), + hasBlock: hasBlock, + importBlock: importBlock, + } +} + +// Start boots up the announcement based synchoniser, accepting and processing +// hash notifications and block fetches until termination requested. +func (f *Fetcher) Start() { + go f.loop() +} + +// Stop terminates the announcement based synchroniser, canceling all pending +// operations. +func (f *Fetcher) Stop() { + close(f.quit) +} + +// Notify announces the fetcher of the potential availability of a new block in +// the network. +func (f *Fetcher) Notify(peer string, hash common.Hash, time time.Time, fetcher blockRequesterFn) error { + block := &announce{ + hash: hash, + time: time, + origin: peer, + fetch: fetcher, + } + select { + case f.notify <- block: + return nil + case <-f.quit: + return errTerminated + } +} + +// Filter extracts all the blocks that were explicitly requested by the fetcher, +// returning those that should be handled differently. +func (f *Fetcher) Filter(blocks types.Blocks) types.Blocks { + // Send the filter channel to the fetcher + filter := make(chan []*types.Block) + + select { + case f.filter <- filter: + case <-f.quit: + return nil + } + // Request the filtering of the block list + select { + case filter <- blocks: + case <-f.quit: + return nil + } + // Retrieve the blocks remaining after filtering + select { + case blocks := <-filter: + return blocks + case <-f.quit: + return nil + } +} + +// Loop is the main fetcher loop, checking and processing various notification +// events. +func (f *Fetcher) loop() { + announced := make(map[common.Hash][]*announce) + fetching := make(map[common.Hash]*announce) + fetch := time.NewTimer(0) + done := make(chan common.Hash) + + // Iterate the block fetching until a quit is requested + for { + // Clean up any expired block fetches + for hash, announce := range fetching { + if time.Since(announce.time) > fetchTimeout { + delete(announced, hash) + delete(fetching, hash) + } + } + // Wait for an outside event to occur + select { + case <-f.quit: + // Fetcher terminating, abort all operations + return + + case notification := <-f.notify: + // A block was announced, schedule if it's not yet downloading + glog.V(logger.Debug).Infof("Peer %s: scheduling %x", notification.origin, notification.hash[:4]) + if _, ok := fetching[notification.hash]; ok { + break + } + if len(announced) == 0 { + fetch.Reset(arriveTimeout) + } + announced[notification.hash] = append(announced[notification.hash], notification) + + case hash := <-done: + // A pending import finished, remove all traces of the notification + delete(announced, hash) + delete(fetching, hash) + + case <-fetch.C: + // At least one block's timer ran out, check for needing retrieval + request := make(map[string][]common.Hash) + + for hash, announces := range announced { + if time.Since(announces[0].time) > arriveTimeout { + announce := announces[rand.Intn(len(announces))] + if !f.hasBlock(hash) { + request[announce.origin] = append(request[announce.origin], hash) + fetching[hash] = announce + } + delete(announced, hash) + } + } + // Send out all block requests + for peer, hashes := range request { + glog.V(logger.Debug).Infof("Peer %s: explicitly fetching %d blocks", peer, len(hashes)) + go fetching[hashes[0]].fetch(hashes) + } + // Schedule the next fetch if blocks are still pending + if len(announced) > 0 { + nearest := time.Now() + for _, announces := range announced { + if nearest.Before(announces[0].time) { + nearest = announces[0].time + } + } + fetch.Reset(arriveTimeout + time.Since(nearest)) + } + + case filter := <-f.filter: + // Blocks arrived, extract any explicit fetches, return all else + var blocks types.Blocks + select { + case blocks = <-filter: + case <-f.quit: + return + } + + explicit, download := []*types.Block{}, []*types.Block{} + for _, block := range blocks { + hash := block.Hash() + + // Filter explicitly requested blocks from hash announcements + if _, ok := fetching[hash]; ok { + // Discard if already imported by other means + if !f.hasBlock(hash) { + explicit = append(explicit, block) + } else { + delete(fetching, hash) + } + } else { + download = append(download, block) + } + } + + select { + case filter <- download: + case <-f.quit: + return + } + // Create a closure with the retrieved blocks and origin peers + peers := make([]string, 0, len(explicit)) + blocks = make([]*types.Block, 0, len(explicit)) + for _, block := range explicit { + hash := block.Hash() + if announce := fetching[hash]; announce != nil { + // Drop the block if it surely cannot fit + if f.hasBlock(hash) || !f.hasBlock(block.ParentHash()) { + // delete(fetching, hash) // if we drop, it will re-fetch it, wait for timeout? + continue + } + // Otherwise accumulate for import + peers = append(peers, announce.origin) + blocks = append(blocks, block) + } + } + // If any explicit fetches were replied to, import them + if count := len(blocks); count > 0 { + glog.V(logger.Debug).Infof("Importing %d explicitly fetched blocks", len(blocks)) + go func() { + // Make sure all hashes are cleaned up + for _, block := range blocks { + hash := block.Hash() + defer func() { done <- hash }() + } + // Try and actually import the blocks + for i := 0; i < len(blocks); i++ { + if err := f.importBlock(peers[i], blocks[i]); err != nil { + glog.V(logger.Detail).Infof("Failed to import explicitly fetched block: %v", err) + return + } + } + }() + } + } + } +} diff --git a/eth/handler.go b/eth/handler.go index ec4f2d53a..99ac4ce68 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -7,6 +7,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/eth/fetcher" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -45,6 +47,7 @@ type ProtocolManager struct { txpool txPool chainman *core.ChainManager downloader *downloader.Downloader + fetcher *fetcher.Fetcher peers *peerSet SubProtocol p2p.Protocol @@ -54,11 +57,9 @@ type ProtocolManager struct { minedBlockSub event.Subscription // channels for fetcher, syncer, txsyncLoop - newPeerCh chan *peer - newHashCh chan []*blockAnnounce - newBlockCh chan chan []*types.Block - txsyncCh chan *txsync - quitSync chan struct{} + newPeerCh chan *peer + txsyncCh chan *txsync + quitSync chan struct{} // wait group is used for graceful shutdowns during downloading // and processing @@ -69,30 +70,33 @@ type ProtocolManager struct { // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the ethereum network. func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpool txPool, chainman *core.ChainManager) *ProtocolManager { + // Create the protocol manager and initialize peer handlers manager := &ProtocolManager{ - eventMux: mux, - txpool: txpool, - chainman: chainman, - peers: newPeerSet(), - newPeerCh: make(chan *peer, 1), - newHashCh: make(chan []*blockAnnounce, 1), - newBlockCh: make(chan chan []*types.Block), - txsyncCh: make(chan *txsync), - quitSync: make(chan struct{}), + eventMux: mux, + txpool: txpool, + chainman: chainman, + peers: newPeerSet(), + newPeerCh: make(chan *peer, 1), + txsyncCh: make(chan *txsync), + quitSync: make(chan struct{}), } - manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.InsertChain, manager.removePeer) manager.SubProtocol = p2p.Protocol{ Name: "eth", Version: uint(protocolVersion), Length: ProtocolLength, Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { peer := manager.newPeer(protocolVersion, networkId, p, rw) - manager.newPeerCh <- peer - return manager.handle(peer) }, } + // Construct the different synchronisation mechanisms + manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.InsertChain, manager.removePeer) + + importer := func(peer string, block *types.Block) error { + return manager.importBlock(manager.peers.Peer(peer), block, nil) + } + manager.fetcher = fetcher.New(manager.chainman.HasBlock, importer) return manager } @@ -126,7 +130,6 @@ func (pm *ProtocolManager) Start() { // start sync handlers go pm.syncer() - go pm.fetcher() go pm.txsyncLoop() } @@ -291,20 +294,9 @@ func (self *ProtocolManager) handleMsg(p *peer) error { glog.V(logger.Detail).Infoln("Decode error", err) blocks = nil } - // Filter out any explicitly requested blocks (cascading select to get blocking back to peer) - filter := make(chan []*types.Block) - select { - case <-self.quitSync: - case self.newBlockCh <- filter: - select { - case <-self.quitSync: - case filter <- blocks: - select { - case <-self.quitSync: - case blocks := <-filter: - self.downloader.DeliverBlocks(p.id, blocks) - } - } + // Filter out any explicitly requested blocks, deliver the rest to the downloader + if blocks := self.fetcher.Filter(blocks); len(blocks) > 0 { + self.downloader.DeliverBlocks(p.id, blocks) } case NewBlockHashesMsg: @@ -327,19 +319,8 @@ func (self *ProtocolManager) handleMsg(p *peer) error { unknown = append(unknown, hash) } } - announces := make([]*blockAnnounce, len(unknown)) - for i, hash := range unknown { - announces[i] = &blockAnnounce{ - hash: hash, - peer: p, - time: time.Now(), - } - } - if len(announces) > 0 { - select { - case self.newHashCh <- announces: - case <-self.quitSync: - } + for _, hash := range unknown { + self.fetcher.Notify(p.id, hash, time.Now(), p.requestBlocks) } case NewBlockMsg: diff --git a/eth/sync.go b/eth/sync.go index 751bc1a2a..82abb725f 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -12,11 +12,8 @@ import ( ) const ( - forceSyncCycle = 10 * time.Second // Time interval to force syncs, even if few peers are available - notifyCheckCycle = 100 * time.Millisecond // Time interval to allow hash notifies to fulfill before hard fetching - notifyArriveTimeout = 500 * time.Millisecond // Time allowance before an announced block is explicitly requested - notifyFetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block - minDesiredPeerCount = 5 // Amount of peers desired to start syncing + forceSyncCycle = 10 * time.Second // Time interval to force syncs, even if few peers are available + minDesiredPeerCount = 5 // Amount of peers desired to start syncing // This is the target size for the packs of transactions sent by txsyncLoop. // A pack can get larger than this if a single transactions exceeds this size. @@ -119,140 +116,15 @@ func (pm *ProtocolManager) txsyncLoop() { } } -// fetcher is responsible for collecting hash notifications, and periodically -// checking all unknown ones and individually fetching them. -func (pm *ProtocolManager) fetcher() { - announces := make(map[common.Hash][]*blockAnnounce) - request := make(map[*peer][]common.Hash) - pending := make(map[common.Hash]*blockAnnounce) - cycle := time.Tick(notifyCheckCycle) - done := make(chan common.Hash) - - // Iterate the block fetching until a quit is requested - for { - select { - case notifications := <-pm.newHashCh: - // A batch of hashes the notified, schedule them for retrieval - glog.V(logger.Debug).Infof("Scheduling %d hash announcements from %s", len(notifications), notifications[0].peer.id) - for _, announce := range notifications { - // Skip if it's already pending fetch - if _, ok := pending[announce.hash]; ok { - continue - } - // Otherwise queue up the peer as a potential source - announces[announce.hash] = append(announces[announce.hash], announce) - } - - case hash := <-done: - // A pending import finished, remove all traces - delete(pending, hash) - - case <-cycle: - // Clean up any expired block fetches - for hash, announce := range pending { - if time.Since(announce.time) > notifyFetchTimeout { - delete(pending, hash) - } - } - // Check if any notified blocks failed to arrive - for hash, all := range announces { - if time.Since(all[0].time) > notifyArriveTimeout { - announce := all[rand.Intn(len(all))] - if !pm.chainman.HasBlock(hash) { - request[announce.peer] = append(request[announce.peer], hash) - pending[hash] = announce - } - delete(announces, hash) - } - } - if len(request) == 0 { - break - } - // Send out all block requests - for peer, hashes := range request { - glog.V(logger.Debug).Infof("Explicitly fetching %d blocks from %s", len(hashes), peer.id) - go peer.requestBlocks(hashes) - } - request = make(map[*peer][]common.Hash) - - case filter := <-pm.newBlockCh: - // Blocks arrived, extract any explicit fetches, return all else - var blocks types.Blocks - select { - case blocks = <-filter: - case <-pm.quitSync: - return - } - - explicit, download := []*types.Block{}, []*types.Block{} - for _, block := range blocks { - hash := block.Hash() - - // Filter explicitly requested blocks from hash announcements - if _, ok := pending[hash]; ok { - // Discard if already imported by other means - if !pm.chainman.HasBlock(hash) { - explicit = append(explicit, block) - } else { - delete(pending, hash) - } - } else { - download = append(download, block) - } - } - - select { - case filter <- download: - case <-pm.quitSync: - return - } - // Create a closure with the retrieved blocks and origin peers - peers := make([]*peer, 0, len(explicit)) - blocks = make([]*types.Block, 0, len(explicit)) - for _, block := range explicit { - hash := block.Hash() - if announce := pending[hash]; announce != nil { - // Drop the block if it surely cannot fit - if pm.chainman.HasBlock(hash) || !pm.chainman.HasBlock(block.ParentHash()) { - // delete(pending, hash) // if we drop, it will re-fetch it, wait for timeout? - continue - } - // Otherwise accumulate for import - peers = append(peers, announce.peer) - blocks = append(blocks, block) - } - } - // If any explicit fetches were replied to, import them - if count := len(blocks); count > 0 { - glog.V(logger.Debug).Infof("Importing %d explicitly fetched blocks", len(blocks)) - go func() { - // Make sure all hashes are cleaned up - for _, block := range blocks { - hash := block.Hash() - defer func() { done <- hash }() - } - // Try and actually import the blocks - for i := 0; i < len(blocks); i++ { - if err := pm.importBlock(peers[i], blocks[i], nil); err != nil { - glog.V(logger.Detail).Infof("Failed to import explicitly fetched block: %v", err) - return - } - } - }() - } - - case <-pm.quitSync: - return - } - } -} - // syncer is responsible for periodically synchronising with the network, both -// downloading hashes and blocks as well as retrieving cached ones. +// downloading hashes and blocks as well as handling the announcement handler. func (pm *ProtocolManager) syncer() { - // Abort any pending syncs if we terminate + // Start and ensure cleanup of sync mechanisms + pm.fetcher.Start() + defer pm.fetcher.Stop() defer pm.downloader.Terminate() + // Wait for different events to fire synchronisation operations forceSync := time.Tick(forceSyncCycle) for { select { @@ -273,8 +145,7 @@ func (pm *ProtocolManager) syncer() { } } -// synchronise tries to sync up our local block chain with a remote peer, both -// adding various sanity checks as well as wrapping it with various log entries. +// synchronise tries to sync up our local block chain with a remote peer. func (pm *ProtocolManager) synchronise(peer *peer) { // Short circuit if no peers are available if peer == nil { From 2a1b722d048d00401084c37a5ca12612f1dd5fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 14:02:43 +0300 Subject: [PATCH 034/110] eth/fetcher: fix timer reset bug, add initial tests --- eth/downloader/downloader_test.go | 8 +- eth/fetcher/fetcher.go | 8 +- eth/fetcher/fetcher_test.go | 202 ++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 6 deletions(-) create mode 100644 eth/fetcher/fetcher_test.go diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 484cc3218..4fc4e1434 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -52,6 +52,8 @@ func copyBlock(block *types.Block) *types.Block { return createBlock(int(block.Number().Int64()), block.ParentHeaderHash, block.HeaderHash) } +// createBlocksFromHashes assembles a collection of blocks, each having a correct +// place in the given hash chain. func createBlocksFromHashes(hashes []common.Hash) map[common.Hash]*types.Block { blocks := make(map[common.Hash]*types.Block) for i := 0; i < len(hashes); i++ { @@ -64,6 +66,7 @@ func createBlocksFromHashes(hashes []common.Hash) map[common.Hash]*types.Block { return blocks } +// downloadTester is a test simulator for mocking out local block chain. type downloadTester struct { downloader *Downloader @@ -75,6 +78,7 @@ type downloadTester struct { maxHashFetch int // Overrides the maximum number of retrieved hashes } +// newTester creates a new downloader test mocker. func newTester() *downloadTester { tester := &downloadTester{ ownHashes: []common.Hash{knownHash}, @@ -82,9 +86,7 @@ func newTester() *downloadTester { peerHashes: make(map[string][]common.Hash), peerBlocks: make(map[string]map[common.Hash]*types.Block), } - var mux event.TypeMux - downloader := New(&mux, tester.hasBlock, tester.getBlock, tester.insertChain, tester.dropPeer) - tester.downloader = downloader + tester.downloader = New(new(event.TypeMux), tester.hasBlock, tester.getBlock, tester.insertChain, tester.dropPeer) return tester } diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 19c53048c..a8d1f2fb5 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -149,7 +149,8 @@ func (f *Fetcher) loop() { break } if len(announced) == 0 { - fetch.Reset(arriveTimeout) + glog.V(logger.Detail).Infof("Scheduling fetch in %v, at %v", arriveTimeout-time.Since(notification.time), notification.time.Add(arriveTimeout)) + fetch.Reset(arriveTimeout - time.Since(notification.time)) } announced[notification.hash] = append(announced[notification.hash], notification) @@ -181,11 +182,12 @@ func (f *Fetcher) loop() { if len(announced) > 0 { nearest := time.Now() for _, announces := range announced { - if nearest.Before(announces[0].time) { + if nearest.After(announces[0].time) { nearest = announces[0].time } } - fetch.Reset(arriveTimeout + time.Since(nearest)) + glog.V(logger.Detail).Infof("Rescheduling fetch in %v, at %v", arriveTimeout-time.Since(nearest), nearest.Add(arriveTimeout)) + fetch.Reset(arriveTimeout - time.Since(nearest)) } case filter := <-f.filter: diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go new file mode 100644 index 000000000..e29f9c7cd --- /dev/null +++ b/eth/fetcher/fetcher_test.go @@ -0,0 +1,202 @@ +package fetcher + +import ( + "encoding/binary" + "errors" + "math/big" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +var ( + knownHash = common.Hash{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + unknownHash = common.Hash{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} + bannedHash = common.Hash{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3} + + genesis = createBlock(1, common.Hash{}, knownHash) +) + +// idCounter is used by the createHashes method the generate deterministic but unique hashes +var idCounter = int64(2) // #1 is the genesis block + +// createHashes generates a batch of hashes rooted at a specific point in the chain. +func createHashes(amount int, root common.Hash) (hashes []common.Hash) { + hashes = make([]common.Hash, amount+1) + hashes[len(hashes)-1] = root + + for i := 0; i < len(hashes)-1; i++ { + binary.BigEndian.PutUint64(hashes[i][:8], uint64(idCounter)) + idCounter++ + } + return +} + +// createBlock assembles a new block at the given chain height. +func createBlock(i int, parent, hash common.Hash) *types.Block { + header := &types.Header{Number: big.NewInt(int64(i))} + block := types.NewBlockWithHeader(header) + block.HeaderHash = hash + block.ParentHeaderHash = parent + return block +} + +// copyBlock makes a deep copy of a block suitable for local modifications. +func copyBlock(block *types.Block) *types.Block { + return createBlock(int(block.Number().Int64()), block.ParentHeaderHash, block.HeaderHash) +} + +// createBlocksFromHashes assembles a collection of blocks, each having a correct +// place in the given hash chain. +func createBlocksFromHashes(hashes []common.Hash) map[common.Hash]*types.Block { + blocks := make(map[common.Hash]*types.Block) + for i := 0; i < len(hashes); i++ { + parent := knownHash + if i < len(hashes)-1 { + parent = hashes[i+1] + } + blocks[hashes[i]] = createBlock(len(hashes)-i, parent, hashes[i]) + } + return blocks +} + +// fetcherTester is a test simulator for mocking out local block chain. +type fetcherTester struct { + fetcher *Fetcher + + ownHashes []common.Hash // Hash chain belonging to the tester + ownBlocks map[common.Hash]*types.Block // Blocks belonging to the tester +} + +// newTester creates a new fetcher test mocker. +func newTester() *fetcherTester { + tester := &fetcherTester{ + ownHashes: []common.Hash{knownHash}, + ownBlocks: map[common.Hash]*types.Block{knownHash: genesis}, + } + tester.fetcher = New(tester.hasBlock, tester.importBlock) + tester.fetcher.Start() + + return tester +} + +// hasBlock checks if a block is pres ent in the testers canonical chain. +func (f *fetcherTester) hasBlock(hash common.Hash) bool { + _, ok := f.ownBlocks[hash] + return ok +} + +// importBlock injects a new blocks into the simulated chain. +func (f *fetcherTester) importBlock(peer string, block *types.Block) error { + if _, ok := f.ownBlocks[block.ParentHash()]; !ok { + return errors.New("unknown parent") + } + f.ownHashes = append(f.ownHashes, block.Hash()) + f.ownBlocks[block.Hash()] = block + return nil +} + +// peerFetcher retrieves a fetcher associated with a simulated peer. +func (f *fetcherTester) makeFetcher(blocks map[common.Hash]*types.Block) blockRequesterFn { + // Copy all the blocks to ensure they are not tampered with + closure := make(map[common.Hash]*types.Block) + for hash, block := range blocks { + closure[hash] = copyBlock(block) + } + // Create a function that returns blocks from the closure + return func(hashes []common.Hash) error { + // Gather the blocks to return + blocks := make([]*types.Block, 0, len(hashes)) + for _, hash := range hashes { + if block, ok := closure[hash]; ok { + blocks = append(blocks, block) + } + } + // Return on a new thread + go f.fetcher.Filter(blocks) + + return nil + } +} + +// Tests that a fetcher accepts block announcements and initiates retrievals for +// them, successfully importing into the local chain. +func TestSequentialAnnouncements(t *testing.T) { + // Create a chain of blocks to import + targetBlocks := 24 + hashes := createHashes(targetBlocks, knownHash) + blocks := createBlocksFromHashes(hashes) + + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + // Iteratively announce blocks until all are imported + for i := len(hashes) - 1; i >= 0; i-- { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) + time.Sleep(50 * time.Millisecond) + } + if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + } +} + +// Tests that if blocks are announced by multiple peers (or even the same buggy +// peer), they will only get downloaded at most once. +func TestConcurrentAnnouncements(t *testing.T) { + // Create a chain of blocks to import + targetBlocks := 24 + hashes := createHashes(targetBlocks, knownHash) + blocks := createBlocksFromHashes(hashes) + + // Assemble a tester with a built in counter for the requests + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + counter := uint32(0) + wrapper := func(hashes []common.Hash) error { + atomic.AddUint32(&counter, uint32(len(hashes))) + return fetcher(hashes) + } + // Iteratively announce blocks until all are imported + for i := len(hashes) - 1; i >= 0; i-- { + tester.fetcher.Notify("first", hashes[i], time.Now().Add(-arriveTimeout), wrapper) + tester.fetcher.Notify("second", hashes[i], time.Now().Add(-arriveTimeout+time.Millisecond), wrapper) + tester.fetcher.Notify("second", hashes[i], time.Now().Add(-arriveTimeout-time.Millisecond), wrapper) + + time.Sleep(50 * time.Millisecond) + } + if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + } + // Make sure no blocks were retrieved twice + if int(counter) != targetBlocks { + t.Fatalf("retrieval count mismatch: have %v, want %v", counter, targetBlocks) + } +} + +// Tests that announcements arriving while a previous is being fetched still +// results in a valid import. +func TestOverlappingAnnouncements(t *testing.T) { + // Create a chain of blocks to import + targetBlocks := 24 + hashes := createHashes(targetBlocks, knownHash) + blocks := createBlocksFromHashes(hashes) + + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + // Iteratively announce blocks, but overlap them continuously + delay, overlap := 50*time.Millisecond, time.Duration(5) + for i := len(hashes) - 1; i >= 0; i-- { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout+overlap*delay), fetcher) + time.Sleep(delay) + } + time.Sleep(overlap * delay) + + if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + } +} From 8b64e041d6c41d76994510fdd8bb42ad7c5be5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 15:35:15 +0300 Subject: [PATCH 035/110] eth/fetcher: add test to check for duplicate downloads --- eth/fetcher/fetcher_test.go | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index e29f9c7cd..44e99f30f 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -200,3 +200,41 @@ func TestOverlappingAnnouncements(t *testing.T) { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } + +// Tests that announces already being retrieved will not be duplicated. +func TestPendingDeduplication(t *testing.T) { + // Create a hash and corresponding block + hashes := createHashes(1, knownHash) + blocks := createBlocksFromHashes(hashes) + + // Assemble a tester with a built in counter and delayed fetcher + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + delay := 50 * time.Millisecond + counter := uint32(0) + wrapper := func(hashes []common.Hash) error { + atomic.AddUint32(&counter, uint32(len(hashes))) + + // Simulate a long running fetch + go func() { + time.Sleep(delay) + fetcher(hashes) + }() + return nil + } + // Announce the same block many times until it's fetched (wait for any pending ops) + for !tester.hasBlock(hashes[0]) { + tester.fetcher.Notify("repeater", hashes[0], time.Now().Add(-arriveTimeout), wrapper) + time.Sleep(time.Millisecond) + } + time.Sleep(delay) + + // Check that all blocks were imported and none fetched twice + if imported := len(tester.ownBlocks); imported != 2 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, 2) + } + if int(counter) != 1 { + t.Fatalf("retrieval count mismatch: have %v, want %v", counter, 1) + } +} From 057bc237adf9ed0adf615a72cc1e92d9aed15d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 17:39:04 +0300 Subject: [PATCH 036/110] eth, eth/fetcher: use an import queue to store out of order blocks --- eth/fetcher/fetcher.go | 78 +++++++++++++++++++++++-------------- eth/fetcher/fetcher_test.go | 35 ++++++++++++++++- eth/handler.go | 11 +++++- 3 files changed, 91 insertions(+), 33 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index a8d1f2fb5..e8a9cc093 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -10,11 +10,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" + "gopkg.in/karalabe/cookiejar.v2/collections/prque" ) const ( arriveTimeout = 500 * time.Millisecond // Time allowance before an announced block is explicitly requested fetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block + maxQueueDist = 256 // Maximum allowed distance from the chain head to queue ) var ( @@ -30,6 +32,9 @@ type blockRequesterFn func([]common.Hash) error // blockImporterFn is a callback type for trying to inject a block into the local chain. type blockImporterFn func(peer string, block *types.Block) error +// chainHeightFn is a callback type to retrieve the current chain height. +type chainHeightFn func() uint64 + // announce is the hash notification of the availability of a new block in the // network. type announce struct { @@ -40,6 +45,12 @@ type announce struct { fetch blockRequesterFn // Fetcher function to retrieve } +// inject represents a schedules import operation. +type inject struct { + origin string + block *types.Block +} + // Fetcher is responsible for accumulating block announcements from various peers // and scheduling them for retrieval. type Fetcher struct { @@ -51,16 +62,18 @@ type Fetcher struct { // Callbacks hasBlock hashCheckFn // Checks if a block is present in the chain importBlock blockImporterFn // Injects a block from an origin peer into the chain + chainHeight chainHeightFn // Retrieves the current chain's height } // New creates a block fetcher to retrieve blocks based on hash announcements. -func New(hasBlock hashCheckFn, importBlock blockImporterFn) *Fetcher { +func New(hasBlock hashCheckFn, importBlock blockImporterFn, chainHeight chainHeightFn) *Fetcher { return &Fetcher{ notify: make(chan *announce), filter: make(chan chan []*types.Block), quit: make(chan struct{}), hasBlock: hasBlock, importBlock: importBlock, + chainHeight: chainHeight, } } @@ -124,6 +137,7 @@ func (f *Fetcher) Filter(blocks types.Blocks) types.Blocks { func (f *Fetcher) loop() { announced := make(map[common.Hash][]*announce) fetching := make(map[common.Hash]*announce) + queued := prque.New() fetch := time.NewTimer(0) done := make(chan common.Hash) @@ -136,6 +150,30 @@ func (f *Fetcher) loop() { delete(fetching, hash) } } + // Import any queued blocks that could potentially fit + height := f.chainHeight() + for !queued.Empty() { + // Fetch the next block, and skip if already known + op := queued.PopItem().(*inject) + if f.hasBlock(op.block.Hash()) { + continue + } + // If unknown, but too high up the chain, continue later + if number := op.block.NumberU64(); number > height+1 { + queued.Push(op, -float32(op.block.NumberU64())) + break + } + // Block may just fit, try to import it + glog.V(logger.Debug).Infof("Peer %s: importing block %x", op.origin, op.block.Hash().Bytes()[:4]) + go func() { + defer func() { done <- op.block.Hash() }() + + if err := f.importBlock(op.origin, op.block); err != nil { + glog.V(logger.Detail).Infof("Peer %s: block %x import failed: %v", op.origin, op.block.Hash().Bytes()[:4], err) + return + } + }() + } // Wait for an outside event to occur select { case <-f.quit: @@ -221,40 +259,20 @@ func (f *Fetcher) loop() { case <-f.quit: return } - // Create a closure with the retrieved blocks and origin peers - peers := make([]string, 0, len(explicit)) - blocks = make([]*types.Block, 0, len(explicit)) + // Schedule the retrieved blocks for ordered import + height := f.chainHeight() for _, block := range explicit { + // Skip any blocks too far into the future + if height+maxQueueDist < block.NumberU64() { + continue + } + // Otherwise if the announce is still pending, schedule hash := block.Hash() if announce := fetching[hash]; announce != nil { - // Drop the block if it surely cannot fit - if f.hasBlock(hash) || !f.hasBlock(block.ParentHash()) { - // delete(fetching, hash) // if we drop, it will re-fetch it, wait for timeout? - continue - } - // Otherwise accumulate for import - peers = append(peers, announce.origin) - blocks = append(blocks, block) + queued.Push(&inject{origin: announce.origin, block: block}, -float32(block.NumberU64())) + glog.V(logger.Detail).Infof("Peer %s: scheduled block %x, total %v", announce.origin, hash[:4], queued.Size()) } } - // If any explicit fetches were replied to, import them - if count := len(blocks); count > 0 { - glog.V(logger.Debug).Infof("Importing %d explicitly fetched blocks", len(blocks)) - go func() { - // Make sure all hashes are cleaned up - for _, block := range blocks { - hash := block.Hash() - defer func() { done <- hash }() - } - // Try and actually import the blocks - for i := 0; i < len(blocks); i++ { - if err := f.importBlock(peers[i], blocks[i]); err != nil { - glog.V(logger.Detail).Infof("Failed to import explicitly fetched block: %v", err) - return - } - } - }() - } } } } diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 44e99f30f..cde4bb70a 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -77,7 +77,7 @@ func newTester() *fetcherTester { ownHashes: []common.Hash{knownHash}, ownBlocks: map[common.Hash]*types.Block{knownHash: genesis}, } - tester.fetcher = New(tester.hasBlock, tester.importBlock) + tester.fetcher = New(tester.hasBlock, tester.importBlock, tester.chainHeight) tester.fetcher.Start() return tester @@ -99,6 +99,11 @@ func (f *fetcherTester) importBlock(peer string, block *types.Block) error { return nil } +// chainHeight retrieves the current height (block number) of the chain. +func (f *fetcherTester) chainHeight() uint64 { + return f.ownBlocks[f.ownHashes[len(f.ownHashes)-1]].NumberU64() +} + // peerFetcher retrieves a fetcher associated with a simulated peer. func (f *fetcherTester) makeFetcher(blocks map[common.Hash]*types.Block) blockRequesterFn { // Copy all the blocks to ensure they are not tampered with @@ -238,3 +243,31 @@ func TestPendingDeduplication(t *testing.T) { t.Fatalf("retrieval count mismatch: have %v, want %v", counter, 1) } } + +// Tests that announcements retrieved in a random order are cached and eventually +// imported when all the gaps are filled in. +func TestRandomArrivalImport(t *testing.T) { + // Create a chain of blocks to import, and choose one to delay + targetBlocks := 24 + hashes := createHashes(targetBlocks, knownHash) + blocks := createBlocksFromHashes(hashes) + skip := targetBlocks / 2 + + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + // Iteratively announce blocks, skipping one entry + for i := len(hashes) - 1; i >= 0; i-- { + if i != skip { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) + time.Sleep(50 * time.Millisecond) + } + } + // Finally announce the skipped entry and check full import + tester.fetcher.Notify("valid", hashes[skip], time.Now().Add(-arriveTimeout), fetcher) + time.Sleep(50 * time.Millisecond) + + if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + } +} diff --git a/eth/handler.go b/eth/handler.go index 99ac4ce68..e5908dc88 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -1,6 +1,7 @@ package eth import ( + "errors" "fmt" "math" "math/big" @@ -94,9 +95,15 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.InsertChain, manager.removePeer) importer := func(peer string, block *types.Block) error { - return manager.importBlock(manager.peers.Peer(peer), block, nil) + if p := manager.peers.Peer(peer); p != nil { + return manager.importBlock(manager.peers.Peer(peer), block, nil) + } + return errors.New("unknown peer") } - manager.fetcher = fetcher.New(manager.chainman.HasBlock, importer) + heighter := func() uint64 { + return manager.chainman.CurrentBlock().NumberU64() + } + manager.fetcher = fetcher.New(manager.chainman.HasBlock, importer, heighter) return manager } From 11c8f83a583745b01a4c06cdd29529af1df364f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 18:14:52 +0300 Subject: [PATCH 037/110] eth, eth/fetcher: cache future propagated blocks too --- eth/fetcher/fetcher.go | 21 +++++++++++++++++++++ eth/fetcher/fetcher_test.go | 28 ++++++++++++++++++++++++++++ eth/handler.go | 2 ++ 3 files changed, 51 insertions(+) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index e8a9cc093..34d368780 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -56,6 +56,7 @@ type inject struct { type Fetcher struct { // Various event channels notify chan *announce + insert chan *inject filter chan chan []*types.Block quit chan struct{} @@ -69,6 +70,7 @@ type Fetcher struct { func New(hasBlock hashCheckFn, importBlock blockImporterFn, chainHeight chainHeightFn) *Fetcher { return &Fetcher{ notify: make(chan *announce), + insert: make(chan *inject), filter: make(chan chan []*types.Block), quit: make(chan struct{}), hasBlock: hasBlock, @@ -106,6 +108,20 @@ func (f *Fetcher) Notify(peer string, hash common.Hash, time time.Time, fetcher } } +// Enqueue tries to fill gaps the the fetcher's future import queue. +func (f *Fetcher) Enqueue(peer string, block *types.Block) error { + op := &inject{ + origin: peer, + block: block, + } + select { + case f.insert <- op: + return nil + case <-f.quit: + return errTerminated + } +} + // Filter extracts all the blocks that were explicitly requested by the fetcher, // returning those that should be handled differently. func (f *Fetcher) Filter(blocks types.Blocks) types.Blocks { @@ -192,6 +208,11 @@ func (f *Fetcher) loop() { } announced[notification.hash] = append(announced[notification.hash], notification) + case op := <-f.insert: + // A direct block insertion was requested, try and fill any pending gaps + queued.Push(op, -float32(op.block.NumberU64())) + glog.V(logger.Detail).Infof("Peer %s: filled block %x, total %v", op.origin, op.block.Hash().Bytes()[:4], queued.Size()) + case hash := <-done: // A pending import finished, remove all traces of the notification delete(announced, hash) diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index cde4bb70a..7c975841c 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -271,3 +271,31 @@ func TestRandomArrivalImport(t *testing.T) { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } + +// Tests that direct block enqueues (due to block propagation vs. hash announce) +// are correctly schedule, filling and import queue gaps. +func TestQueueGapFill(t *testing.T) { + // Create a chain of blocks to import, and choose one to not announce at all + targetBlocks := 24 + hashes := createHashes(targetBlocks, knownHash) + blocks := createBlocksFromHashes(hashes) + skip := targetBlocks / 2 + + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + // Iteratively announce blocks, skipping one entry + for i := len(hashes) - 1; i >= 0; i-- { + if i != skip { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) + time.Sleep(50 * time.Millisecond) + } + } + // Fill the missing block directly as if propagated + tester.fetcher.Enqueue("valid", blocks[hashes[skip]]) + time.Sleep(50 * time.Millisecond) + + if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + } +} diff --git a/eth/handler.go b/eth/handler.go index e5908dc88..604983a7b 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -340,6 +340,8 @@ func (self *ProtocolManager) handleMsg(p *peer) error { } request.Block.ReceivedAt = msg.ReceivedAt + // Try to import the propagated block, also making it fill any fetcher gaps + self.fetcher.Enqueue(p.id, request.Block) if err := self.importBlock(p, request.Block, request.TD); err != nil { return err } From 026ee40650bde909c962f15e32bdea6c1d6e978a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 18:43:58 +0300 Subject: [PATCH 038/110] eth/fetcher: deduplicate future blocks --- eth/fetcher/fetcher.go | 60 +++++++++++++++++++++---------------- eth/fetcher/fetcher_test.go | 36 ++++++++++++++++++++++ 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 34d368780..207bd9323 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -153,11 +153,28 @@ func (f *Fetcher) Filter(blocks types.Blocks) types.Blocks { func (f *Fetcher) loop() { announced := make(map[common.Hash][]*announce) fetching := make(map[common.Hash]*announce) - queued := prque.New() + + // Create the priority queue and a matching presence set + queue := prque.New() + queued := make(map[common.Hash]struct{}) + enqueue := func(peer string, block *types.Block) { + // Make sure the block isn't in some weird place + if f.chainHeight()+maxQueueDist < block.NumberU64() { + return + } + // If not, schedule the block for future import + hash := block.Hash() + if _, ok := queued[hash]; !ok { + queued[hash] = struct{}{} + queue.Push(&inject{origin: peer, block: block}, -float32(block.NumberU64())) + + glog.V(logger.Detail).Infof("Peer %s: queued block %x, total %v", peer, hash.Bytes()[:4], queue.Size()) + } + } + // Iterate the block fetching until a quit is requested fetch := time.NewTimer(0) done := make(chan common.Hash) - // Iterate the block fetching until a quit is requested for { // Clean up any expired block fetches for hash, announce := range fetching { @@ -168,24 +185,26 @@ func (f *Fetcher) loop() { } // Import any queued blocks that could potentially fit height := f.chainHeight() - for !queued.Empty() { - // Fetch the next block, and skip if already known - op := queued.PopItem().(*inject) - if f.hasBlock(op.block.Hash()) { - continue - } - // If unknown, but too high up the chain, continue later + for !queue.Empty() { + // If too high up the chain, continue later + op := queue.PopItem().(*inject) if number := op.block.NumberU64(); number > height+1 { - queued.Push(op, -float32(op.block.NumberU64())) + queue.Push(op, -float32(op.block.NumberU64())) break } + // Otherwise if not known yet, try and import + hash := op.block.Hash() + delete(queued, hash) + if f.hasBlock(hash) { + continue + } // Block may just fit, try to import it - glog.V(logger.Debug).Infof("Peer %s: importing block %x", op.origin, op.block.Hash().Bytes()[:4]) + glog.V(logger.Debug).Infof("Peer %s: importing block %x", op.origin, hash.Bytes()[:4]) go func() { - defer func() { done <- op.block.Hash() }() + defer func() { done <- hash }() if err := f.importBlock(op.origin, op.block); err != nil { - glog.V(logger.Detail).Infof("Peer %s: block %x import failed: %v", op.origin, op.block.Hash().Bytes()[:4], err) + glog.V(logger.Detail).Infof("Peer %s: block %x import failed: %v", op.origin, hash.Bytes()[:4], err) return } }() @@ -210,8 +229,7 @@ func (f *Fetcher) loop() { case op := <-f.insert: // A direct block insertion was requested, try and fill any pending gaps - queued.Push(op, -float32(op.block.NumberU64())) - glog.V(logger.Detail).Infof("Peer %s: filled block %x, total %v", op.origin, op.block.Hash().Bytes()[:4], queued.Size()) + enqueue(op.origin, op.block) case hash := <-done: // A pending import finished, remove all traces of the notification @@ -281,17 +299,9 @@ func (f *Fetcher) loop() { return } // Schedule the retrieved blocks for ordered import - height := f.chainHeight() for _, block := range explicit { - // Skip any blocks too far into the future - if height+maxQueueDist < block.NumberU64() { - continue - } - // Otherwise if the announce is still pending, schedule - hash := block.Hash() - if announce := fetching[hash]; announce != nil { - queued.Push(&inject{origin: announce.origin, block: block}, -float32(block.NumberU64())) - glog.V(logger.Detail).Infof("Peer %s: scheduled block %x, total %v", announce.origin, hash[:4], queued.Size()) + if announce := fetching[block.Hash()]; announce != nil { + enqueue(announce.origin, block) } } } diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 7c975841c..e11a211a1 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -299,3 +299,39 @@ func TestQueueGapFill(t *testing.T) { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } + +// Tests that blocks arriving from various sources (multiple propagations, hash +// announces, etc) do not get scheduled for import multiple times. +func TestImportDeduplication(t *testing.T) { + // Create two blocks to import (one for duplication, the other for stalling) + hashes := createHashes(2, knownHash) + blocks := createBlocksFromHashes(hashes) + + // Create the tester and wrap the importer with a counter + tester := newTester() + fetcher := tester.makeFetcher(blocks) + + counter := uint32(0) + tester.fetcher.importBlock = func(peer string, block *types.Block) error { + atomic.AddUint32(&counter, 1) + return tester.importBlock(peer, block) + } + // Announce the duplicating block, wait for retrieval, and also propagate directly + tester.fetcher.Notify("valid", hashes[0], time.Now().Add(-arriveTimeout), fetcher) + time.Sleep(50 * time.Millisecond) + + tester.fetcher.Enqueue("valid", blocks[hashes[0]]) + tester.fetcher.Enqueue("valid", blocks[hashes[0]]) + tester.fetcher.Enqueue("valid", blocks[hashes[0]]) + + // Fill the missing block directly as if propagated, and check import uniqueness + tester.fetcher.Enqueue("valid", blocks[hashes[1]]) + time.Sleep(50 * time.Millisecond) + + if imported := len(tester.ownBlocks); imported != 3 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, 3) + } + if counter != 2 { + t.Fatalf("import invocation count mismatch: have %v, want %v", counter, 2) + } +} From 497a7f1717a798e59c9550fbb58504b08fe13b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 16 Jun 2015 23:18:01 +0300 Subject: [PATCH 039/110] eth, eth/fetcher: define and enforce propagation boundaries --- eth/fetcher/fetcher.go | 55 +++++++++++++++++++++---------------- eth/fetcher/fetcher_test.go | 28 +++++++++++++++++++ eth/handler.go | 1 - 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 207bd9323..76d3798cb 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -3,6 +3,7 @@ package fetcher import ( "errors" + "math" "math/rand" "time" @@ -60,6 +61,10 @@ type Fetcher struct { filter chan chan []*types.Block quit chan struct{} + // Block cache + queue *prque.Prque // Queue containing the import operations (block number sorted) + queued map[common.Hash]struct{} // Presence set of already queued blocks (to dedup imports) + // Callbacks hasBlock hashCheckFn // Checks if a block is present in the chain importBlock blockImporterFn // Injects a block from an origin peer into the chain @@ -73,6 +78,8 @@ func New(hasBlock hashCheckFn, importBlock blockImporterFn, chainHeight chainHei insert: make(chan *inject), filter: make(chan chan []*types.Block), quit: make(chan struct{}), + queue: prque.New(), + queued: make(map[common.Hash]struct{}), hasBlock: hasBlock, importBlock: importBlock, chainHeight: chainHeight, @@ -154,23 +161,6 @@ func (f *Fetcher) loop() { announced := make(map[common.Hash][]*announce) fetching := make(map[common.Hash]*announce) - // Create the priority queue and a matching presence set - queue := prque.New() - queued := make(map[common.Hash]struct{}) - enqueue := func(peer string, block *types.Block) { - // Make sure the block isn't in some weird place - if f.chainHeight()+maxQueueDist < block.NumberU64() { - return - } - // If not, schedule the block for future import - hash := block.Hash() - if _, ok := queued[hash]; !ok { - queued[hash] = struct{}{} - queue.Push(&inject{origin: peer, block: block}, -float32(block.NumberU64())) - - glog.V(logger.Detail).Infof("Peer %s: queued block %x, total %v", peer, hash.Bytes()[:4], queue.Size()) - } - } // Iterate the block fetching until a quit is requested fetch := time.NewTimer(0) done := make(chan common.Hash) @@ -185,16 +175,16 @@ func (f *Fetcher) loop() { } // Import any queued blocks that could potentially fit height := f.chainHeight() - for !queue.Empty() { + for !f.queue.Empty() { // If too high up the chain, continue later - op := queue.PopItem().(*inject) + op := f.queue.PopItem().(*inject) if number := op.block.NumberU64(); number > height+1 { - queue.Push(op, -float32(op.block.NumberU64())) + f.queue.Push(op, -float32(op.block.NumberU64())) break } // Otherwise if not known yet, try and import hash := op.block.Hash() - delete(queued, hash) + delete(f.queued, hash) if f.hasBlock(hash) { continue } @@ -229,7 +219,7 @@ func (f *Fetcher) loop() { case op := <-f.insert: // A direct block insertion was requested, try and fill any pending gaps - enqueue(op.origin, op.block) + f.enqueue(op.origin, op.block) case hash := <-done: // A pending import finished, remove all traces of the notification @@ -301,9 +291,28 @@ func (f *Fetcher) loop() { // Schedule the retrieved blocks for ordered import for _, block := range explicit { if announce := fetching[block.Hash()]; announce != nil { - enqueue(announce.origin, block) + f.enqueue(announce.origin, block) } } } } } + +// enqueue schedules a new future import operation, if the block to be imported +// has not yet been seen. +func (f *Fetcher) enqueue(peer string, block *types.Block) { + // Make sure the block isn't in some weird place + if math.Abs(float64(f.chainHeight())-float64(block.NumberU64())) > maxQueueDist { + return + } + // Schedule the block for future importing + hash := block.Hash() + if _, ok := f.queued[hash]; !ok { + f.queued[hash] = struct{}{} + f.queue.Push(&inject{origin: peer, block: block}, -float32(block.NumberU64())) + + if glog.V(logger.Detail) { + glog.Infof("Peer %s: queued block %x, total %v", peer, hash.Bytes()[:4], f.queue.Size()) + } + } +} diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index e11a211a1..af2652a86 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -335,3 +335,31 @@ func TestImportDeduplication(t *testing.T) { t.Fatalf("import invocation count mismatch: have %v, want %v", counter, 2) } } + +// Tests that blocks with numbers much lower or higher than out current head get +// discarded no prevent wasting resources on useless blocks from faulty peers. +func TestDistantDiscarding(t *testing.T) { + // Create a long chain to import + hashes := createHashes(3*maxQueueDist, knownHash) + blocks := createBlocksFromHashes(hashes) + + head := hashes[len(hashes)/2] + + // Create a tester and simulate a head block being the middle of the above chain + tester := newTester() + tester.ownHashes = []common.Hash{head} + tester.ownBlocks = map[common.Hash]*types.Block{head: blocks[head]} + + // Ensure that a block with a lower number than the threshold is discarded + tester.fetcher.Enqueue("lower", blocks[hashes[0]]) + time.Sleep(10 * time.Millisecond) + if !tester.fetcher.queue.Empty() { + t.Fatalf("fetcher queued stale block") + } + // Ensure that a block with a higher number than the threshold is discarded + tester.fetcher.Enqueue("higher", blocks[hashes[len(hashes)-1]]) + time.Sleep(10 * time.Millisecond) + if !tester.fetcher.queue.Empty() { + t.Fatalf("fetcher queued future block") + } +} diff --git a/eth/handler.go b/eth/handler.go index 604983a7b..c3b58650d 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ethereum/go-ethereum/eth/fetcher" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" From 2a7411bc9605dae9798ed29ed237e28c8fc98895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 17 Jun 2015 00:19:09 +0300 Subject: [PATCH 040/110] eth/fetcher: fix premature queue cleanup, general polishes --- eth/fetcher/fetcher.go | 82 ++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 76d3798cb..78d25f72e 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -61,6 +61,10 @@ type Fetcher struct { filter chan chan []*types.Block quit chan struct{} + // Announce states + announced map[common.Hash][]*announce // Announced blocks, scheduled for fetching + fetching map[common.Hash]*announce // Announced blocks, currently fetching + // Block cache queue *prque.Prque // Queue containing the import operations (block number sorted) queued map[common.Hash]struct{} // Presence set of already queued blocks (to dedup imports) @@ -78,6 +82,8 @@ func New(hasBlock hashCheckFn, importBlock blockImporterFn, chainHeight chainHei insert: make(chan *inject), filter: make(chan chan []*types.Block), quit: make(chan struct{}), + announced: make(map[common.Hash][]*announce), + fetching: make(map[common.Hash]*announce), queue: prque.New(), queued: make(map[common.Hash]struct{}), hasBlock: hasBlock, @@ -158,19 +164,16 @@ func (f *Fetcher) Filter(blocks types.Blocks) types.Blocks { // Loop is the main fetcher loop, checking and processing various notification // events. func (f *Fetcher) loop() { - announced := make(map[common.Hash][]*announce) - fetching := make(map[common.Hash]*announce) - // Iterate the block fetching until a quit is requested fetch := time.NewTimer(0) done := make(chan common.Hash) for { // Clean up any expired block fetches - for hash, announce := range fetching { + for hash, announce := range f.fetching { if time.Since(announce.time) > fetchTimeout { - delete(announced, hash) - delete(fetching, hash) + delete(f.announced, hash) + delete(f.fetching, hash) } } // Import any queued blocks that could potentially fit @@ -184,17 +187,16 @@ func (f *Fetcher) loop() { } // Otherwise if not known yet, try and import hash := op.block.Hash() - delete(f.queued, hash) if f.hasBlock(hash) { continue } // Block may just fit, try to import it - glog.V(logger.Debug).Infof("Peer %s: importing block %x", op.origin, hash.Bytes()[:4]) + glog.V(logger.Debug).Infof("Peer %s: importing block #%d [%x]", op.origin, op.block.NumberU64(), hash.Bytes()[:4]) go func() { defer func() { done <- hash }() if err := f.importBlock(op.origin, op.block); err != nil { - glog.V(logger.Detail).Infof("Peer %s: block %x import failed: %v", op.origin, hash.Bytes()[:4], err) + glog.V(logger.Detail).Infof("Peer %s: block #%d [%x] import failed: %v", op.origin, op.block.NumberU64(), hash.Bytes()[:4], err) return } }() @@ -208,14 +210,13 @@ func (f *Fetcher) loop() { case notification := <-f.notify: // A block was announced, schedule if it's not yet downloading glog.V(logger.Debug).Infof("Peer %s: scheduling %x", notification.origin, notification.hash[:4]) - if _, ok := fetching[notification.hash]; ok { + if _, ok := f.fetching[notification.hash]; ok { break } - if len(announced) == 0 { - glog.V(logger.Detail).Infof("Scheduling fetch in %v, at %v", arriveTimeout-time.Since(notification.time), notification.time.Add(arriveTimeout)) - fetch.Reset(arriveTimeout - time.Since(notification.time)) + f.announced[notification.hash] = append(f.announced[notification.hash], notification) + if len(f.announced) == 1 { + f.reschedule(fetch) } - announced[notification.hash] = append(announced[notification.hash], notification) case op := <-f.insert: // A direct block insertion was requested, try and fill any pending gaps @@ -223,39 +224,31 @@ func (f *Fetcher) loop() { case hash := <-done: // A pending import finished, remove all traces of the notification - delete(announced, hash) - delete(fetching, hash) + delete(f.announced, hash) + delete(f.fetching, hash) + delete(f.queued, hash) case <-fetch.C: // At least one block's timer ran out, check for needing retrieval request := make(map[string][]common.Hash) - for hash, announces := range announced { + for hash, announces := range f.announced { if time.Since(announces[0].time) > arriveTimeout { announce := announces[rand.Intn(len(announces))] if !f.hasBlock(hash) { request[announce.origin] = append(request[announce.origin], hash) - fetching[hash] = announce + f.fetching[hash] = announce } - delete(announced, hash) + delete(f.announced, hash) } } // Send out all block requests for peer, hashes := range request { glog.V(logger.Debug).Infof("Peer %s: explicitly fetching %d blocks", peer, len(hashes)) - go fetching[hashes[0]].fetch(hashes) + go f.fetching[hashes[0]].fetch(hashes) } // Schedule the next fetch if blocks are still pending - if len(announced) > 0 { - nearest := time.Now() - for _, announces := range announced { - if nearest.After(announces[0].time) { - nearest = announces[0].time - } - } - glog.V(logger.Detail).Infof("Rescheduling fetch in %v, at %v", arriveTimeout-time.Since(nearest), nearest.Add(arriveTimeout)) - fetch.Reset(arriveTimeout - time.Since(nearest)) - } + f.reschedule(fetch) case filter := <-f.filter: // Blocks arrived, extract any explicit fetches, return all else @@ -271,12 +264,12 @@ func (f *Fetcher) loop() { hash := block.Hash() // Filter explicitly requested blocks from hash announcements - if _, ok := fetching[hash]; ok { + if _, ok := f.fetching[hash]; ok { // Discard if already imported by other means if !f.hasBlock(hash) { explicit = append(explicit, block) } else { - delete(fetching, hash) + delete(f.fetching, hash) } } else { download = append(download, block) @@ -290,7 +283,7 @@ func (f *Fetcher) loop() { } // Schedule the retrieved blocks for ordered import for _, block := range explicit { - if announce := fetching[block.Hash()]; announce != nil { + if announce := f.fetching[block.Hash()]; announce != nil { f.enqueue(announce.origin, block) } } @@ -298,21 +291,40 @@ func (f *Fetcher) loop() { } } +// reschedule resets the specified fetch timer to the next announce timeout. +func (f *Fetcher) reschedule(fetch *time.Timer) { + // Short circuit if no blocks are announced + if len(f.announced) == 0 { + return + } + // Otherwise find the earliest expiring announcement + earliest := time.Now() + for _, announces := range f.announced { + if earliest.After(announces[0].time) { + earliest = announces[0].time + } + } + glog.V(logger.Detail).Infof("Scheduling next fetch in %v", arriveTimeout-time.Since(earliest)) + fetch.Reset(arriveTimeout - time.Since(earliest)) +} + // enqueue schedules a new future import operation, if the block to be imported // has not yet been seen. func (f *Fetcher) enqueue(peer string, block *types.Block) { + hash := block.Hash() + // Make sure the block isn't in some weird place if math.Abs(float64(f.chainHeight())-float64(block.NumberU64())) > maxQueueDist { + glog.Infof("Peer %s: discarded block #%d [%x] too far from head", peer, block.NumberU64(), hash.Bytes()[:4]) return } // Schedule the block for future importing - hash := block.Hash() if _, ok := f.queued[hash]; !ok { f.queued[hash] = struct{}{} f.queue.Push(&inject{origin: peer, block: block}, -float32(block.NumberU64())) if glog.V(logger.Detail) { - glog.Infof("Peer %s: queued block %x, total %v", peer, hash.Bytes()[:4], f.queue.Size()) + glog.Infof("Peer %s: queued block #%d [%x], total %v", peer, block.NumberU64(), hash.Bytes()[:4], f.queue.Size()) } } } From 37c5ff392f71fddaa6acd92925f69e81876fe22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 17 Jun 2015 16:53:28 +0300 Subject: [PATCH 041/110] eth/fetcher: build longest chain until proven otherwise --- eth/fetcher/fetcher.go | 67 ++++++++++++++++++++----------------- eth/fetcher/fetcher_test.go | 57 +++++++++++++++++++++++++++++++ eth/handler.go | 2 +- 3 files changed, 95 insertions(+), 31 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 78d25f72e..a70fcbeed 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -3,7 +3,6 @@ package fetcher import ( "errors" - "math" "math/rand" "time" @@ -57,8 +56,9 @@ type inject struct { type Fetcher struct { // Various event channels notify chan *announce - insert chan *inject + inject chan *inject filter chan chan []*types.Block + done chan common.Hash quit chan struct{} // Announce states @@ -79,8 +79,9 @@ type Fetcher struct { func New(hasBlock hashCheckFn, importBlock blockImporterFn, chainHeight chainHeightFn) *Fetcher { return &Fetcher{ notify: make(chan *announce), - insert: make(chan *inject), + inject: make(chan *inject), filter: make(chan chan []*types.Block), + done: make(chan common.Hash), quit: make(chan struct{}), announced: make(map[common.Hash][]*announce), fetching: make(map[common.Hash]*announce), @@ -128,7 +129,7 @@ func (f *Fetcher) Enqueue(peer string, block *types.Block) error { block: block, } select { - case f.insert <- op: + case f.inject <- op: return nil case <-f.quit: return errTerminated @@ -166,8 +167,6 @@ func (f *Fetcher) Filter(blocks types.Blocks) types.Blocks { func (f *Fetcher) loop() { // Iterate the block fetching until a quit is requested fetch := time.NewTimer(0) - done := make(chan common.Hash) - for { // Clean up any expired block fetches for hash, announce := range f.fetching { @@ -179,27 +178,19 @@ func (f *Fetcher) loop() { // Import any queued blocks that could potentially fit height := f.chainHeight() for !f.queue.Empty() { - // If too high up the chain, continue later op := f.queue.PopItem().(*inject) - if number := op.block.NumberU64(); number > height+1 { + number := op.block.NumberU64() + + // If too high up the chain or phase, continue later + if number > height+1 { f.queue.Push(op, -float32(op.block.NumberU64())) break } - // Otherwise if not known yet, try and import - hash := op.block.Hash() - if f.hasBlock(hash) { + // Otherwise if fresh and still unknown, try and import + if number <= height || f.hasBlock(op.block.Hash()) { continue } - // Block may just fit, try to import it - glog.V(logger.Debug).Infof("Peer %s: importing block #%d [%x]", op.origin, op.block.NumberU64(), hash.Bytes()[:4]) - go func() { - defer func() { done <- hash }() - - if err := f.importBlock(op.origin, op.block); err != nil { - glog.V(logger.Detail).Infof("Peer %s: block #%d [%x] import failed: %v", op.origin, op.block.NumberU64(), hash.Bytes()[:4], err) - return - } - }() + f.insert(op.origin, op.block) } // Wait for an outside event to occur select { @@ -209,7 +200,6 @@ func (f *Fetcher) loop() { case notification := <-f.notify: // A block was announced, schedule if it's not yet downloading - glog.V(logger.Debug).Infof("Peer %s: scheduling %x", notification.origin, notification.hash[:4]) if _, ok := f.fetching[notification.hash]; ok { break } @@ -218,11 +208,11 @@ func (f *Fetcher) loop() { f.reschedule(fetch) } - case op := <-f.insert: + case op := <-f.inject: // A direct block insertion was requested, try and fill any pending gaps f.enqueue(op.origin, op.block) - case hash := <-done: + case hash := <-f.done: // A pending import finished, remove all traces of the notification delete(f.announced, hash) delete(f.fetching, hash) @@ -243,8 +233,7 @@ func (f *Fetcher) loop() { } } // Send out all block requests - for peer, hashes := range request { - glog.V(logger.Debug).Infof("Peer %s: explicitly fetching %d blocks", peer, len(hashes)) + for _, hashes := range request { go f.fetching[hashes[0]].fetch(hashes) } // Schedule the next fetch if blocks are still pending @@ -304,7 +293,6 @@ func (f *Fetcher) reschedule(fetch *time.Timer) { earliest = announces[0].time } } - glog.V(logger.Detail).Infof("Scheduling next fetch in %v", arriveTimeout-time.Since(earliest)) fetch.Reset(arriveTimeout - time.Since(earliest)) } @@ -313,9 +301,9 @@ func (f *Fetcher) reschedule(fetch *time.Timer) { func (f *Fetcher) enqueue(peer string, block *types.Block) { hash := block.Hash() - // Make sure the block isn't in some weird place - if math.Abs(float64(f.chainHeight())-float64(block.NumberU64())) > maxQueueDist { - glog.Infof("Peer %s: discarded block #%d [%x] too far from head", peer, block.NumberU64(), hash.Bytes()[:4]) + // Discard any past or too distant blocks + if dist := int64(block.NumberU64()) - int64(f.chainHeight()); dist <= 0 || dist > maxQueueDist { + glog.Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) return } // Schedule the block for future importing @@ -328,3 +316,22 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { } } } + +// insert spawns a new goroutine to run a block insertion into the chain. If the +// block's number is at the same height as the current import phase, if updates +// the phase states accordingly. +func (f *Fetcher) insert(peer string, block *types.Block) { + hash := block.Hash() + + // Run the import on a new thread + glog.V(logger.Debug).Infof("Peer %s: importing block #%d [%x]", peer, block.NumberU64(), hash[:4]) + go func() { + defer func() { f.done <- hash }() + + // Run the actual import and log any issues + if err := f.importBlock(peer, block); err != nil { + glog.V(logger.Detail).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err) + return + } + }() +} diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index af2652a86..00fad3498 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -91,9 +91,15 @@ func (f *fetcherTester) hasBlock(hash common.Hash) bool { // importBlock injects a new blocks into the simulated chain. func (f *fetcherTester) importBlock(peer string, block *types.Block) error { + // Make sure the parent in known if _, ok := f.ownBlocks[block.ParentHash()]; !ok { return errors.New("unknown parent") } + // Discard any new blocks if the same height already exists + if block.NumberU64() <= f.ownBlocks[f.ownHashes[len(f.ownHashes)-1]].NumberU64() { + return nil + } + // Otherwise build our current chain f.ownHashes = append(f.ownHashes, block.Hash()) f.ownBlocks[block.Hash()] = block return nil @@ -363,3 +369,54 @@ func TestDistantDiscarding(t *testing.T) { t.Fatalf("fetcher queued future block") } } + +// Tests that if multiple uncles (i.e. blocks at the same height) are queued for +// importing, then they will get inserted in phases, previous heights needing to +// complete before the next numbered blocks can begin. +func TestCompetingImports(t *testing.T) { + // Generate a few soft-forks for concurrent imports + hashesA := createHashes(16, knownHash) + hashesB := createHashes(16, knownHash) + hashesC := createHashes(16, knownHash) + + blocksA := createBlocksFromHashes(hashesA) + blocksB := createBlocksFromHashes(hashesB) + blocksC := createBlocksFromHashes(hashesC) + + // Create a tester, and override the import to check number reversals + tester := newTester() + + first := int32(1) + height := uint64(1) + tester.fetcher.importBlock = func(peer string, block *types.Block) error { + // Check for any phase reordering + if prev := atomic.LoadUint64(&height); block.NumberU64() < prev { + t.Errorf("phase reversal: have %v, want %v", block.NumberU64(), prev) + } + atomic.StoreUint64(&height, block.NumberU64()) + + // Sleep a bit on the first import not to race with the enqueues + if atomic.CompareAndSwapInt32(&first, 1, 0) { + time.Sleep(50 * time.Millisecond) + } + return tester.importBlock(peer, block) + } + // Queue up everything but with a missing link + for i := 0; i < len(hashesA)-2; i++ { + tester.fetcher.Enqueue("chain A", blocksA[hashesA[i]]) + tester.fetcher.Enqueue("chain B", blocksB[hashesB[i]]) + tester.fetcher.Enqueue("chain C", blocksC[hashesC[i]]) + } + // Add the three missing links, and wait for a full import + tester.fetcher.Enqueue("chain A", blocksA[hashesA[len(hashesA)-2]]) + tester.fetcher.Enqueue("chain B", blocksB[hashesB[len(hashesB)-2]]) + tester.fetcher.Enqueue("chain C", blocksC[hashesC[len(hashesC)-2]]) + + start := time.Now() + for len(tester.ownHashes) != len(hashesA) && time.Since(start) < time.Second { + time.Sleep(50 * time.Millisecond) + } + if len(tester.ownHashes) != len(hashesA) { + t.Fatalf("chain length mismatch: have %v, want %v", len(tester.ownHashes), len(hashesA)) + } +} diff --git a/eth/handler.go b/eth/handler.go index c3b58650d..b62815532 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -8,11 +8,11 @@ import ( "sync" "time" - "github.com/ethereum/go-ethereum/eth/fetcher" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/fetcher" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" From a9ada0b5baa9c47f8673cb63707797cbd08f0d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 17 Jun 2015 17:08:32 +0300 Subject: [PATCH 042/110] eth/fetcher: make tests thread safe --- eth/fetcher/fetcher_test.go | 56 ++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 00fad3498..4c6a1bf6a 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "errors" "math/big" + "sync" "sync/atomic" "testing" "time" @@ -67,15 +68,17 @@ func createBlocksFromHashes(hashes []common.Hash) map[common.Hash]*types.Block { type fetcherTester struct { fetcher *Fetcher - ownHashes []common.Hash // Hash chain belonging to the tester - ownBlocks map[common.Hash]*types.Block // Blocks belonging to the tester + hashes []common.Hash // Hash chain belonging to the tester + blocks map[common.Hash]*types.Block // Blocks belonging to the tester + + lock sync.RWMutex } // newTester creates a new fetcher test mocker. func newTester() *fetcherTester { tester := &fetcherTester{ - ownHashes: []common.Hash{knownHash}, - ownBlocks: map[common.Hash]*types.Block{knownHash: genesis}, + hashes: []common.Hash{knownHash}, + blocks: map[common.Hash]*types.Block{knownHash: genesis}, } tester.fetcher = New(tester.hasBlock, tester.importBlock, tester.chainHeight) tester.fetcher.Start() @@ -85,29 +88,38 @@ func newTester() *fetcherTester { // hasBlock checks if a block is pres ent in the testers canonical chain. func (f *fetcherTester) hasBlock(hash common.Hash) bool { - _, ok := f.ownBlocks[hash] + f.lock.RLock() + defer f.lock.RUnlock() + + _, ok := f.blocks[hash] return ok } // importBlock injects a new blocks into the simulated chain. func (f *fetcherTester) importBlock(peer string, block *types.Block) error { + f.lock.Lock() + defer f.lock.Unlock() + // Make sure the parent in known - if _, ok := f.ownBlocks[block.ParentHash()]; !ok { + if _, ok := f.blocks[block.ParentHash()]; !ok { return errors.New("unknown parent") } // Discard any new blocks if the same height already exists - if block.NumberU64() <= f.ownBlocks[f.ownHashes[len(f.ownHashes)-1]].NumberU64() { + if block.NumberU64() <= f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() { return nil } // Otherwise build our current chain - f.ownHashes = append(f.ownHashes, block.Hash()) - f.ownBlocks[block.Hash()] = block + f.hashes = append(f.hashes, block.Hash()) + f.blocks[block.Hash()] = block return nil } // chainHeight retrieves the current height (block number) of the chain. func (f *fetcherTester) chainHeight() uint64 { - return f.ownBlocks[f.ownHashes[len(f.ownHashes)-1]].NumberU64() + f.lock.RLock() + defer f.lock.RUnlock() + + return f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() } // peerFetcher retrieves a fetcher associated with a simulated peer. @@ -149,7 +161,7 @@ func TestSequentialAnnouncements(t *testing.T) { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) time.Sleep(50 * time.Millisecond) } - if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + if imported := len(tester.blocks); imported != targetBlocks+1 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } @@ -179,7 +191,7 @@ func TestConcurrentAnnouncements(t *testing.T) { time.Sleep(50 * time.Millisecond) } - if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + if imported := len(tester.blocks); imported != targetBlocks+1 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } // Make sure no blocks were retrieved twice @@ -207,7 +219,7 @@ func TestOverlappingAnnouncements(t *testing.T) { } time.Sleep(overlap * delay) - if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + if imported := len(tester.blocks); imported != targetBlocks+1 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } @@ -242,7 +254,7 @@ func TestPendingDeduplication(t *testing.T) { time.Sleep(delay) // Check that all blocks were imported and none fetched twice - if imported := len(tester.ownBlocks); imported != 2 { + if imported := len(tester.blocks); imported != 2 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, 2) } if int(counter) != 1 { @@ -273,7 +285,7 @@ func TestRandomArrivalImport(t *testing.T) { tester.fetcher.Notify("valid", hashes[skip], time.Now().Add(-arriveTimeout), fetcher) time.Sleep(50 * time.Millisecond) - if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + if imported := len(tester.blocks); imported != targetBlocks+1 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } @@ -301,7 +313,7 @@ func TestQueueGapFill(t *testing.T) { tester.fetcher.Enqueue("valid", blocks[hashes[skip]]) time.Sleep(50 * time.Millisecond) - if imported := len(tester.ownBlocks); imported != targetBlocks+1 { + if imported := len(tester.blocks); imported != targetBlocks+1 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) } } @@ -334,7 +346,7 @@ func TestImportDeduplication(t *testing.T) { tester.fetcher.Enqueue("valid", blocks[hashes[1]]) time.Sleep(50 * time.Millisecond) - if imported := len(tester.ownBlocks); imported != 3 { + if imported := len(tester.blocks); imported != 3 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, 3) } if counter != 2 { @@ -353,8 +365,8 @@ func TestDistantDiscarding(t *testing.T) { // Create a tester and simulate a head block being the middle of the above chain tester := newTester() - tester.ownHashes = []common.Hash{head} - tester.ownBlocks = map[common.Hash]*types.Block{head: blocks[head]} + tester.hashes = []common.Hash{head} + tester.blocks = map[common.Hash]*types.Block{head: blocks[head]} // Ensure that a block with a lower number than the threshold is discarded tester.fetcher.Enqueue("lower", blocks[hashes[0]]) @@ -413,10 +425,10 @@ func TestCompetingImports(t *testing.T) { tester.fetcher.Enqueue("chain C", blocksC[hashesC[len(hashesC)-2]]) start := time.Now() - for len(tester.ownHashes) != len(hashesA) && time.Since(start) < time.Second { + for len(tester.hashes) != len(hashesA) && time.Since(start) < time.Second { time.Sleep(50 * time.Millisecond) } - if len(tester.ownHashes) != len(hashesA) { - t.Fatalf("chain length mismatch: have %v, want %v", len(tester.ownHashes), len(hashesA)) + if len(tester.hashes) != len(hashesA) { + t.Fatalf("chain length mismatch: have %v, want %v", len(tester.hashes), len(hashesA)) } } From 5ec6ecc511dc861c0395335f06883bc9ac650e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 17 Jun 2015 18:25:23 +0300 Subject: [PATCH 043/110] eth, eth/fetcher: move propagated block import into fetcher --- eth/downloader/downloader.go | 2 +- eth/fetcher/fetcher.go | 59 ++++++++++++------- eth/fetcher/fetcher_test.go | 62 +++++++++++--------- eth/handler.go | 110 +++++++++++------------------------ 4 files changed, 108 insertions(+), 125 deletions(-) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 18e5f50e8..39976aae1 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -99,7 +99,7 @@ type Downloader struct { hasBlock hashCheckFn // Checks if a block is present in the chain getBlock blockRetrievalFn // Retrieves a block from the chain insertChain chainInsertFn // Injects a batch of blocks into the chain - dropPeer peerDropFn // Retrieved the TD of our own chain + dropPeer peerDropFn // Drops a peer for misbehaving // Status synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index a70fcbeed..c96471554 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -29,12 +29,18 @@ type hashCheckFn func(common.Hash) bool // blockRequesterFn is a callback type for sending a block retrieval request. type blockRequesterFn func([]common.Hash) error -// blockImporterFn is a callback type for trying to inject a block into the local chain. -type blockImporterFn func(peer string, block *types.Block) error +// blockBroadcasterFn is a callback type for broadcasting a block to connected peers. +type blockBroadcasterFn func(block *types.Block) // chainHeightFn is a callback type to retrieve the current chain height. type chainHeightFn func() uint64 +// chainInsertFn is a callback type to insert a batch of blocks into the local chain. +type chainInsertFn func(types.Blocks) (int, error) + +// peerDropFn is a callback type for dropping a peer detected as malicious. +type peerDropFn func(id string) + // announce is the hash notification of the availability of a new block in the // network. type announce struct { @@ -70,26 +76,30 @@ type Fetcher struct { queued map[common.Hash]struct{} // Presence set of already queued blocks (to dedup imports) // Callbacks - hasBlock hashCheckFn // Checks if a block is present in the chain - importBlock blockImporterFn // Injects a block from an origin peer into the chain - chainHeight chainHeightFn // Retrieves the current chain's height + hasBlock hashCheckFn // Checks if a block is present in the chain + broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers + chainHeight chainHeightFn // Retrieves the current chain's height + insertChain chainInsertFn // Injects a batch of blocks into the chain + dropPeer peerDropFn // Drops a peer for misbehaving } // New creates a block fetcher to retrieve blocks based on hash announcements. -func New(hasBlock hashCheckFn, importBlock blockImporterFn, chainHeight chainHeightFn) *Fetcher { +func New(hasBlock hashCheckFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher { return &Fetcher{ - notify: make(chan *announce), - inject: make(chan *inject), - filter: make(chan chan []*types.Block), - done: make(chan common.Hash), - quit: make(chan struct{}), - announced: make(map[common.Hash][]*announce), - fetching: make(map[common.Hash]*announce), - queue: prque.New(), - queued: make(map[common.Hash]struct{}), - hasBlock: hasBlock, - importBlock: importBlock, - chainHeight: chainHeight, + notify: make(chan *announce), + inject: make(chan *inject), + filter: make(chan chan []*types.Block), + done: make(chan common.Hash), + quit: make(chan struct{}), + announced: make(map[common.Hash][]*announce), + fetching: make(map[common.Hash]*announce), + queue: prque.New(), + queued: make(map[common.Hash]struct{}), + hasBlock: hasBlock, + broadcastBlock: broadcastBlock, + chainHeight: chainHeight, + insertChain: insertChain, + dropPeer: dropPeer, } } @@ -328,10 +338,17 @@ func (f *Fetcher) insert(peer string, block *types.Block) { go func() { defer func() { f.done <- hash }() - // Run the actual import and log any issues - if err := f.importBlock(peer, block); err != nil { - glog.V(logger.Detail).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err) + // If the parent's unknown, abort insertion + if !f.hasBlock(block.ParentHash()) { return } + // Run the actual import and log any issues + if _, err := f.insertChain(types.Blocks{block}); err != nil { + glog.V(logger.Detail).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err) + f.dropPeer(peer) + return + } + // If import succeeded, broadcast the block + go f.broadcastBlock(block) }() } diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 4c6a1bf6a..3e8df1804 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -80,7 +80,7 @@ func newTester() *fetcherTester { hashes: []common.Hash{knownHash}, blocks: map[common.Hash]*types.Block{knownHash: genesis}, } - tester.fetcher = New(tester.hasBlock, tester.importBlock, tester.chainHeight) + tester.fetcher = New(tester.hasBlock, tester.broadcastBlock, tester.chainHeight, tester.insertChain, tester.dropPeer) tester.fetcher.Start() return tester @@ -95,23 +95,8 @@ func (f *fetcherTester) hasBlock(hash common.Hash) bool { return ok } -// importBlock injects a new blocks into the simulated chain. -func (f *fetcherTester) importBlock(peer string, block *types.Block) error { - f.lock.Lock() - defer f.lock.Unlock() - - // Make sure the parent in known - if _, ok := f.blocks[block.ParentHash()]; !ok { - return errors.New("unknown parent") - } - // Discard any new blocks if the same height already exists - if block.NumberU64() <= f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() { - return nil - } - // Otherwise build our current chain - f.hashes = append(f.hashes, block.Hash()) - f.blocks[block.Hash()] = block - return nil +// broadcastBlock is a nop placeholder for the block broadcasting. +func (f *fetcherTester) broadcastBlock(block *types.Block) { } // chainHeight retrieves the current height (block number) of the chain. @@ -122,6 +107,31 @@ func (f *fetcherTester) chainHeight() uint64 { return f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() } +// insertChain injects a new blocks into the simulated chain. +func (f *fetcherTester) insertChain(blocks types.Blocks) (int, error) { + f.lock.Lock() + defer f.lock.Unlock() + + for i, block := range blocks { + // Make sure the parent in known + if _, ok := f.blocks[block.ParentHash()]; !ok { + return i, errors.New("unknown parent") + } + // Discard any new blocks if the same height already exists + if block.NumberU64() <= f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() { + return i, nil + } + // Otherwise build our current chain + f.hashes = append(f.hashes, block.Hash()) + f.blocks[block.Hash()] = block + } + return 0, nil +} + +// dropPeer is a nop placeholder for the peer removal. +func (f *fetcherTester) dropPeer(peer string) { +} + // peerFetcher retrieves a fetcher associated with a simulated peer. func (f *fetcherTester) makeFetcher(blocks map[common.Hash]*types.Block) blockRequesterFn { // Copy all the blocks to ensure they are not tampered with @@ -330,9 +340,9 @@ func TestImportDeduplication(t *testing.T) { fetcher := tester.makeFetcher(blocks) counter := uint32(0) - tester.fetcher.importBlock = func(peer string, block *types.Block) error { - atomic.AddUint32(&counter, 1) - return tester.importBlock(peer, block) + tester.fetcher.insertChain = func(blocks types.Blocks) (int, error) { + atomic.AddUint32(&counter, uint32(len(blocks))) + return tester.insertChain(blocks) } // Announce the duplicating block, wait for retrieval, and also propagate directly tester.fetcher.Notify("valid", hashes[0], time.Now().Add(-arriveTimeout), fetcher) @@ -400,18 +410,18 @@ func TestCompetingImports(t *testing.T) { first := int32(1) height := uint64(1) - tester.fetcher.importBlock = func(peer string, block *types.Block) error { + tester.fetcher.insertChain = func(blocks types.Blocks) (int, error) { // Check for any phase reordering - if prev := atomic.LoadUint64(&height); block.NumberU64() < prev { - t.Errorf("phase reversal: have %v, want %v", block.NumberU64(), prev) + if prev := atomic.LoadUint64(&height); blocks[0].NumberU64() < prev { + t.Errorf("phase reversal: have %v, want %v", blocks[0].NumberU64(), prev) } - atomic.StoreUint64(&height, block.NumberU64()) + atomic.StoreUint64(&height, blocks[0].NumberU64()) // Sleep a bit on the first import not to race with the enqueues if atomic.CompareAndSwapInt32(&first, 1, 0) { time.Sleep(50 * time.Millisecond) } - return tester.importBlock(peer, block) + return tester.insertChain(blocks) } // Queue up everything but with a missing link for i := 0; i < len(hashesA)-2; i++ { diff --git a/eth/handler.go b/eth/handler.go index b62815532..eeb6a4f14 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -1,10 +1,8 @@ package eth import ( - "errors" "fmt" "math" - "math/big" "sync" "time" @@ -93,16 +91,10 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo // Construct the different synchronisation mechanisms manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.InsertChain, manager.removePeer) - importer := func(peer string, block *types.Block) error { - if p := manager.peers.Peer(peer); p != nil { - return manager.importBlock(manager.peers.Peer(peer), block, nil) - } - return errors.New("unknown peer") - } heighter := func() uint64 { return manager.chainman.CurrentBlock().NumberU64() } - manager.fetcher = fetcher.New(manager.chainman.HasBlock, importer, heighter) + manager.fetcher = fetcher.New(manager.chainman.HasBlock, manager.BroadcastBlock, heighter, manager.chainman.InsertChain, manager.removePeer) return manager } @@ -194,7 +186,7 @@ func (pm *ProtocolManager) handle(p *peer) error { return nil } -func (self *ProtocolManager) handleMsg(p *peer) error { +func (pm *ProtocolManager) handleMsg(p *peer) error { msg, err := p.rw.ReadMsg() if err != nil { return err @@ -224,7 +216,7 @@ func (self *ProtocolManager) handleMsg(p *peer) error { RemoteId: p.ID().String(), }) } - self.txpool.AddTransactions(txs) + pm.txpool.AddTransactions(txs) case GetBlockHashesMsg: var request getBlockHashesMsgData @@ -236,7 +228,7 @@ func (self *ProtocolManager) handleMsg(p *peer) error { request.Amount = uint64(downloader.MaxHashFetch) } - hashes := self.chainman.GetBlockHashesFromHash(request.Hash, request.Amount) + hashes := pm.chainman.GetBlockHashesFromHash(request.Hash, request.Amount) if glog.V(logger.Debug) { if len(hashes) == 0 { @@ -254,7 +246,7 @@ func (self *ProtocolManager) handleMsg(p *peer) error { if err := msgStream.Decode(&hashes); err != nil { break } - err := self.downloader.DeliverHashes(p.id, hashes) + err := pm.downloader.DeliverHashes(p.id, hashes) if err != nil { glog.V(logger.Debug).Infoln(err) } @@ -280,7 +272,7 @@ func (self *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "msg %v: %v", msg, err) } - block := self.chainman.GetBlock(hash) + block := pm.chainman.GetBlock(hash) if block != nil { blocks = append(blocks, block) totalsize += block.Size() @@ -301,8 +293,8 @@ func (self *ProtocolManager) handleMsg(p *peer) error { blocks = nil } // Filter out any explicitly requested blocks, deliver the rest to the downloader - if blocks := self.fetcher.Filter(blocks); len(blocks) > 0 { - self.downloader.DeliverBlocks(p.id, blocks) + if blocks := pm.fetcher.Filter(blocks); len(blocks) > 0 { + pm.downloader.DeliverBlocks(p.id, blocks) } case NewBlockHashesMsg: @@ -321,15 +313,16 @@ func (self *ProtocolManager) handleMsg(p *peer) error { // Schedule all the unknown hashes for retrieval unknown := make([]common.Hash, 0, len(hashes)) for _, hash := range hashes { - if !self.chainman.HasBlock(hash) { + if !pm.chainman.HasBlock(hash) { unknown = append(unknown, hash) } } for _, hash := range unknown { - self.fetcher.Notify(p.id, hash, time.Now(), p.requestBlocks) + pm.fetcher.Notify(p.id, hash, time.Now(), p.requestBlocks) } case NewBlockMsg: + // Retrieve and decode the propagated block var request newBlockMsgData if err := msg.Decode(&request); err != nil { return errResp(ErrDecode, "%v: %v", msg, err) @@ -339,11 +332,24 @@ func (self *ProtocolManager) handleMsg(p *peer) error { } request.Block.ReceivedAt = msg.ReceivedAt - // Try to import the propagated block, also making it fill any fetcher gaps - self.fetcher.Enqueue(p.id, request.Block) - if err := self.importBlock(p, request.Block, request.TD); err != nil { - return err - } + // Mark the block's arrival for whatever reason + _, chainHead, _ := pm.chainman.Status() + jsonlogger.LogJson(&logger.EthChainReceivedNewBlock{ + BlockHash: request.Block.Hash().Hex(), + BlockNumber: request.Block.Number(), + ChainHeadHash: chainHead.Hex(), + BlockPrevHash: request.Block.ParentHash().Hex(), + RemoteId: p.ID().String(), + }) + // Mark the peer as owning the block and schedule it for import + p.blockHashes.Add(request.Block.Hash()) + p.SetHead(request.Block.Hash()) + + pm.fetcher.Enqueue(p.id, request.Block) + + // TODO: Schedule a sync to cover potential gaps (this needs proto update) + p.SetTd(request.TD) + go pm.synchronise(p) default: return errResp(ErrInvalidMsgCode, "%v", msg.Code) @@ -351,61 +357,11 @@ func (self *ProtocolManager) handleMsg(p *peer) error { return nil } -// importBlocks injects a new block retrieved from the given peer into the chain -// manager. -func (pm *ProtocolManager) importBlock(p *peer, block *types.Block, td *big.Int) error { - hash := block.Hash() - - // Mark the block as present at the remote node (don't duplicate already held data) - p.blockHashes.Add(hash) - p.SetHead(hash) - if td != nil { - p.SetTd(td) - } - // Log the block's arrival - _, chainHead, _ := pm.chainman.Status() - jsonlogger.LogJson(&logger.EthChainReceivedNewBlock{ - BlockHash: hash.Hex(), - BlockNumber: block.Number(), - ChainHeadHash: chainHead.Hex(), - BlockPrevHash: block.ParentHash().Hex(), - RemoteId: p.ID().String(), - }) - // If the block's already known or its difficulty is lower than ours, drop - if pm.chainman.HasBlock(hash) { - p.SetTd(pm.chainman.GetBlock(hash).Td) // update the peer's TD to the real value - return nil - } - if td != nil && pm.chainman.Td().Cmp(td) > 0 && new(big.Int).Add(block.Number(), big.NewInt(7)).Cmp(pm.chainman.CurrentBlock().Number()) < 0 { - glog.V(logger.Debug).Infof("[%s] dropped block %v due to low TD %v\n", p.id, block.Number(), td) - return nil - } - // Attempt to insert the newly received block and propagate to our peers - if pm.chainman.HasBlock(block.ParentHash()) { - if _, err := pm.chainman.InsertChain(types.Blocks{block}); err != nil { - glog.V(logger.Error).Infoln("removed peer (", p.id, ") due to block error", err) - return err - } - if td != nil && block.Td.Cmp(td) != 0 { - err := fmt.Errorf("invalid TD on block(%v) from peer(%s): block.td=%v, request.td=%v", block.Number(), p.id, block.Td, td) - glog.V(logger.Error).Infoln(err) - return err - } - pm.BroadcastBlock(hash, block) - return nil - } - // Parent of the block is unknown, try to sync with this peer if it seems to be good - if td != nil { - go pm.synchronise(p) - } - return nil -} - // BroadcastBlock will propagate the block to a subset of its connected peers, // only notifying the rest of the block's appearance. -func (pm *ProtocolManager) BroadcastBlock(hash common.Hash, block *types.Block) { +func (pm *ProtocolManager) BroadcastBlock(block *types.Block) { // Retrieve all the target peers and split between full broadcast or only notification - peers := pm.peers.PeersWithoutBlock(hash) + peers := pm.peers.PeersWithoutBlock(block.Hash()) split := int(math.Sqrt(float64(len(peers)))) transfer := peers[:split] @@ -413,7 +369,7 @@ func (pm *ProtocolManager) BroadcastBlock(hash common.Hash, block *types.Block) // Send out the data transfers and the notifications for _, peer := range notify { - peer.sendNewBlockHashes([]common.Hash{hash}) + peer.sendNewBlockHashes([]common.Hash{block.Hash()}) } glog.V(logger.Detail).Infoln("broadcast hash to", len(notify), "peers.") @@ -442,7 +398,7 @@ func (self *ProtocolManager) minedBroadcastLoop() { for obj := range self.minedBlockSub.Chan() { switch ev := obj.(type) { case core.NewMinedBlockEvent: - self.BroadcastBlock(ev.Block.Hash(), ev.Block) + self.BroadcastBlock(ev.Block) } } } From 629705ad53ceac1bcc5f32f2d7ef51d7626aefef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 16:09:34 +0300 Subject: [PATCH 044/110] eth: clean the block request packet handling a bit --- eth/handler.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/eth/handler.go b/eth/handler.go index eeb6a4f14..f3fe5dfe3 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -252,33 +252,31 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } case GetBlocksMsg: - var blocks []*types.Block - + // Decode the retrieval message msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) if _, err := msgStream.List(); err != nil { return err } + // Gather blocks until the fetch or network limits is reached var ( - i int - totalsize common.StorageSize + hash common.Hash + bytes common.StorageSize + blocks []*types.Block ) for { - i++ - var hash common.Hash err := msgStream.Decode(&hash) if err == rlp.EOL { break } else if err != nil { return errResp(ErrDecode, "msg %v: %v", msg, err) } - - block := pm.chainman.GetBlock(hash) - if block != nil { + // Retrieve the requested block, stopping if enough was found + if block := pm.chainman.GetBlock(hash); block != nil { blocks = append(blocks, block) - totalsize += block.Size() - } - if i == downloader.MaxBlockFetch || totalsize > maxBlockRespSize { - break + bytes += block.Size() + if len(blocks) >= downloader.MaxBlockFetch || bytes > maxBlockRespSize { + break + } } } return p.sendBlocks(blocks) @@ -360,8 +358,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { // BroadcastBlock will propagate the block to a subset of its connected peers, // only notifying the rest of the block's appearance. func (pm *ProtocolManager) BroadcastBlock(block *types.Block) { + hash := block.Hash() + // Retrieve all the target peers and split between full broadcast or only notification - peers := pm.peers.PeersWithoutBlock(block.Hash()) + peers := pm.peers.PeersWithoutBlock(hash) split := int(math.Sqrt(float64(len(peers)))) transfer := peers[:split] @@ -369,14 +369,14 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block) { // Send out the data transfers and the notifications for _, peer := range notify { - peer.sendNewBlockHashes([]common.Hash{block.Hash()}) + peer.sendNewBlockHashes([]common.Hash{hash}) } - glog.V(logger.Detail).Infoln("broadcast hash to", len(notify), "peers.") + glog.V(logger.Detail).Infof("broadcast hash %x to %d peers.", hash[:4], len(notify)) for _, peer := range transfer { peer.sendNewBlock(block) } - glog.V(logger.Detail).Infoln("broadcast block to", len(transfer), "peers. Total processing time:", time.Since(block.ReceivedAt)) + glog.V(logger.Detail).Infof("broadcast block %x to %d peers. Total processing time: %v", hash[:4], len(transfer), time.Since(block.ReceivedAt)) } // BroadcastTx will propagate the block to its connected peers. It will sort From b91b581b80ec99dfa07b7206104faa919210fc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 18:00:19 +0300 Subject: [PATCH 045/110] eth, eth/fetcher: propagate after header verify, announce only on insert --- eth/backend.go | 2 +- eth/fetcher/fetcher.go | 45 +++++++++++++++++---------- eth/fetcher/fetcher_test.go | 18 ++++++----- eth/handler.go | 61 +++++++++++++++++++++++++------------ 4 files changed, 82 insertions(+), 44 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index c621fa260..37fe66abf 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -313,7 +313,7 @@ func New(config *Config) (*Ethereum, error) { eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) - eth.protocolManager = NewProtocolManager(config.ProtocolVersion, config.NetworkId, eth.eventMux, eth.txPool, eth.chainManager) + eth.protocolManager = NewProtocolManager(config.ProtocolVersion, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.chainManager) eth.miner = miner.New(eth, eth.EventMux(), eth.pow) eth.miner.SetGasPrice(config.GasPrice) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index c96471554..d5ff5d77e 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -23,14 +23,17 @@ var ( errTerminated = errors.New("terminated") ) -// hashCheckFn is a callback type for verifying a hash's presence in the local chain. -type hashCheckFn func(common.Hash) bool +// blockRetrievalFn is a callback type for retrieving a block from the local chain. +type blockRetrievalFn func(common.Hash) *types.Block // blockRequesterFn is a callback type for sending a block retrieval request. type blockRequesterFn func([]common.Hash) error +// blockValidatorFn is a callback type to verify a block's header for fast propagation. +type blockValidatorFn func(block *types.Block, parent *types.Block) error + // blockBroadcasterFn is a callback type for broadcasting a block to connected peers. -type blockBroadcasterFn func(block *types.Block) +type blockBroadcasterFn func(block *types.Block, propagate bool) // chainHeightFn is a callback type to retrieve the current chain height. type chainHeightFn func() uint64 @@ -76,7 +79,8 @@ type Fetcher struct { queued map[common.Hash]struct{} // Presence set of already queued blocks (to dedup imports) // Callbacks - hasBlock hashCheckFn // Checks if a block is present in the chain + getBlock blockRetrievalFn // Retrieves a block from the local chain + validateBlock blockValidatorFn // Checks if a block's headers have a valid proof of work broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers chainHeight chainHeightFn // Retrieves the current chain's height insertChain chainInsertFn // Injects a batch of blocks into the chain @@ -84,7 +88,7 @@ type Fetcher struct { } // New creates a block fetcher to retrieve blocks based on hash announcements. -func New(hasBlock hashCheckFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher { +func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher { return &Fetcher{ notify: make(chan *announce), inject: make(chan *inject), @@ -95,7 +99,8 @@ func New(hasBlock hashCheckFn, broadcastBlock blockBroadcasterFn, chainHeight ch fetching: make(map[common.Hash]*announce), queue: prque.New(), queued: make(map[common.Hash]struct{}), - hasBlock: hasBlock, + getBlock: getBlock, + validateBlock: validateBlock, broadcastBlock: broadcastBlock, chainHeight: chainHeight, insertChain: insertChain, @@ -197,7 +202,7 @@ func (f *Fetcher) loop() { break } // Otherwise if fresh and still unknown, try and import - if number <= height || f.hasBlock(op.block.Hash()) { + if number <= height || f.getBlock(op.block.Hash()) != nil { continue } f.insert(op.origin, op.block) @@ -235,7 +240,7 @@ func (f *Fetcher) loop() { for hash, announces := range f.announced { if time.Since(announces[0].time) > arriveTimeout { announce := announces[rand.Intn(len(announces))] - if !f.hasBlock(hash) { + if f.getBlock(hash) == nil { request[announce.origin] = append(request[announce.origin], hash) f.fetching[hash] = announce } @@ -265,7 +270,7 @@ func (f *Fetcher) loop() { // Filter explicitly requested blocks from hash announcements if _, ok := f.fetching[hash]; ok { // Discard if already imported by other means - if !f.hasBlock(hash) { + if f.getBlock(hash) == nil { explicit = append(explicit, block) } else { delete(f.fetching, hash) @@ -313,7 +318,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { // Discard any past or too distant blocks if dist := int64(block.NumberU64()) - int64(f.chainHeight()); dist <= 0 || dist > maxQueueDist { - glog.Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) + glog.V(logger.Detail).Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) return } // Schedule the block for future importing @@ -321,7 +326,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { f.queued[hash] = struct{}{} f.queue.Push(&inject{origin: peer, block: block}, -float32(block.NumberU64())) - if glog.V(logger.Detail) { + if glog.V(logger.Debug) { glog.Infof("Peer %s: queued block #%d [%x], total %v", peer, block.NumberU64(), hash.Bytes()[:4], f.queue.Size()) } } @@ -339,16 +344,24 @@ func (f *Fetcher) insert(peer string, block *types.Block) { defer func() { f.done <- hash }() // If the parent's unknown, abort insertion - if !f.hasBlock(block.ParentHash()) { + parent := f.getBlock(block.ParentHash()) + if parent == nil { return } - // Run the actual import and log any issues - if _, err := f.insertChain(types.Blocks{block}); err != nil { - glog.V(logger.Detail).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err) + // Quickly validate the header and propagate the block if it passes + if err := f.validateBlock(block, parent); err != nil { + glog.V(logger.Debug).Infof("Peer %s: block #%d [%x] verification failed: %v", peer, block.NumberU64(), hash[:4], err) f.dropPeer(peer) return } + go f.broadcastBlock(block, true) + + // Run the actual import and log any issues + if _, err := f.insertChain(types.Blocks{block}); err != nil { + glog.V(logger.Warn).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err) + return + } // If import succeeded, broadcast the block - go f.broadcastBlock(block) + go f.broadcastBlock(block, false) }() } diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 3e8df1804..cdf875c5c 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -80,23 +80,27 @@ func newTester() *fetcherTester { hashes: []common.Hash{knownHash}, blocks: map[common.Hash]*types.Block{knownHash: genesis}, } - tester.fetcher = New(tester.hasBlock, tester.broadcastBlock, tester.chainHeight, tester.insertChain, tester.dropPeer) + tester.fetcher = New(tester.getBlock, tester.verifyBlock, tester.broadcastBlock, tester.chainHeight, tester.insertChain, tester.dropPeer) tester.fetcher.Start() return tester } -// hasBlock checks if a block is pres ent in the testers canonical chain. -func (f *fetcherTester) hasBlock(hash common.Hash) bool { +// getBlock retrieves a block from the tester's block chain. +func (f *fetcherTester) getBlock(hash common.Hash) *types.Block { f.lock.RLock() defer f.lock.RUnlock() - _, ok := f.blocks[hash] - return ok + return f.blocks[hash] +} + +// verifyBlock is a nop placeholder for the block header verification. +func (f *fetcherTester) verifyBlock(block *types.Block, parent *types.Block) error { + return nil } // broadcastBlock is a nop placeholder for the block broadcasting. -func (f *fetcherTester) broadcastBlock(block *types.Block) { +func (f *fetcherTester) broadcastBlock(block *types.Block, propagate bool) { } // chainHeight retrieves the current height (block number) of the chain. @@ -257,7 +261,7 @@ func TestPendingDeduplication(t *testing.T) { return nil } // Announce the same block many times until it's fetched (wait for any pending ops) - for !tester.hasBlock(hashes[0]) { + for tester.getBlock(hashes[0]) == nil { tester.fetcher.Notify("repeater", hashes[0], time.Now().Add(-arriveTimeout), wrapper) time.Sleep(time.Millisecond) } diff --git a/eth/handler.go b/eth/handler.go index f3fe5dfe3..88e340256 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -6,6 +6,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/pow" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -67,7 +69,7 @@ type ProtocolManager struct { // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the ethereum network. -func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpool txPool, chainman *core.ChainManager) *ProtocolManager { +func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, chainman *core.ChainManager) *ProtocolManager { // Create the protocol manager and initialize peer handlers manager := &ProtocolManager{ eventMux: mux, @@ -91,10 +93,13 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo // Construct the different synchronisation mechanisms manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.InsertChain, manager.removePeer) + validator := func(block *types.Block, parent *types.Block) error { + return core.ValidateHeader(pow, block.Header(), parent.Header(), true) + } heighter := func() uint64 { return manager.chainman.CurrentBlock().NumberU64() } - manager.fetcher = fetcher.New(manager.chainman.HasBlock, manager.BroadcastBlock, heighter, manager.chainman.InsertChain, manager.removePeer) + manager.fetcher = fetcher.New(manager.chainman.GetBlock, validator, manager.BroadcastBlock, heighter, manager.chainman.InsertChain, manager.removePeer) return manager } @@ -261,6 +266,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { var ( hash common.Hash bytes common.StorageSize + hashes []common.Hash blocks []*types.Block ) for { @@ -270,6 +276,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } else if err != nil { return errResp(ErrDecode, "msg %v: %v", msg, err) } + hashes = append(hashes, hash) + // Retrieve the requested block, stopping if enough was found if block := pm.chainman.GetBlock(hash); block != nil { blocks = append(blocks, block) @@ -279,6 +287,15 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } } } + if glog.V(logger.Detail) && len(blocks) == 0 && len(hashes) > 0 { + list := "[" + for _, hash := range hashes { + list += fmt.Sprintf("%x, ", hash[:4]) + } + list = list[:len(list)-2] + "]" + + glog.Infof("Peer %s: no blocks found for requested hashes %s", p.id, list) + } return p.sendBlocks(blocks) case BlocksMsg: @@ -290,6 +307,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { glog.V(logger.Detail).Infoln("Decode error", err) blocks = nil } + // Update the receive timestamp of each block + for i:=0; i 0 { pm.downloader.DeliverBlocks(p.id, blocks) @@ -355,28 +376,27 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return nil } -// BroadcastBlock will propagate the block to a subset of its connected peers, -// only notifying the rest of the block's appearance. -func (pm *ProtocolManager) BroadcastBlock(block *types.Block) { +// BroadcastBlock will either propagate a block to a subset of it's peers, or +// will only announce it's availability (depending what's requested). +func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) { hash := block.Hash() - - // Retrieve all the target peers and split between full broadcast or only notification peers := pm.peers.PeersWithoutBlock(hash) - split := int(math.Sqrt(float64(len(peers)))) - transfer := peers[:split] - notify := peers[split:] - - // Send out the data transfers and the notifications - for _, peer := range notify { - peer.sendNewBlockHashes([]common.Hash{hash}) + // If propagation is requested, send to a subset of the peer + if propagate { + transfer := peers[:int(math.Sqrt(float64(len(peers))))] + for _, peer := range transfer { + peer.sendNewBlock(block) + } + glog.V(logger.Detail).Infof("propagated block %x to %d peers in %v", hash[:4], len(transfer), time.Since(block.ReceivedAt)) } - glog.V(logger.Detail).Infof("broadcast hash %x to %d peers.", hash[:4], len(notify)) - - for _, peer := range transfer { - peer.sendNewBlock(block) + // Otherwise if the block is indeed in out own chain, announce it + if pm.chainman.HasBlock(hash) { + for _, peer := range peers { + peer.sendNewBlockHashes([]common.Hash{hash}) + } + glog.V(logger.Detail).Infof("announced block %x to %d peers in %v", hash[:4], len(peers), time.Since(block.ReceivedAt)) } - glog.V(logger.Detail).Infof("broadcast block %x to %d peers. Total processing time: %v", hash[:4], len(transfer), time.Since(block.ReceivedAt)) } // BroadcastTx will propagate the block to its connected peers. It will sort @@ -398,7 +418,8 @@ func (self *ProtocolManager) minedBroadcastLoop() { for obj := range self.minedBlockSub.Chan() { switch ev := obj.(type) { case core.NewMinedBlockEvent: - self.BroadcastBlock(ev.Block) + self.BroadcastBlock(ev.Block, false) + self.BroadcastBlock(ev.Block, true) } } } From 90d45f0397666cce42657849257a6f4f7cd2381c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 18:25:27 +0300 Subject: [PATCH 046/110] eth: fix test breakage from the previous commit --- eth/handler.go | 1 - eth/protocol_test.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/eth/handler.go b/eth/handler.go index 88e340256..a5986b779 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -7,7 +7,6 @@ import ( "time" "github.com/ethereum/go-ethereum/pow" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" diff --git a/eth/protocol_test.go b/eth/protocol_test.go index 69d487c71..6e0eef59c 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -167,7 +167,7 @@ func newProtocolManagerForTesting(txAdded chan<- []*types.Transaction) *Protocol db, _ = ethdb.NewMemDatabase() chain, _ = core.NewChainManager(core.GenesisBlock(0, db), db, db, core.FakePow{}, em) txpool = &fakeTxPool{added: txAdded} - pm = NewProtocolManager(ProtocolVersion, 0, em, txpool, chain) + pm = NewProtocolManager(ProtocolVersion, 0, em, txpool, core.FakePow{}, chain) ) pm.Start() return pm From ecd19919c5ec7118862fc88e2bfac19d4abbff53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 19:43:47 +0300 Subject: [PATCH 047/110] eth/fetcher: allow backward uncle imports too --- eth/fetcher/fetcher.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index d5ff5d77e..98170cf79 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -16,6 +16,7 @@ import ( const ( arriveTimeout = 500 * time.Millisecond // Time allowance before an announced block is explicitly requested fetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block + maxUncleDist = 7 // Maximum allowed backward distance from the chain head maxQueueDist = 256 // Maximum allowed distance from the chain head to queue ) @@ -202,7 +203,7 @@ func (f *Fetcher) loop() { break } // Otherwise if fresh and still unknown, try and import - if number <= height || f.getBlock(op.block.Hash()) != nil { + if number+maxUncleDist < height || f.getBlock(op.block.Hash()) != nil { continue } f.insert(op.origin, op.block) @@ -317,7 +318,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { hash := block.Hash() // Discard any past or too distant blocks - if dist := int64(block.NumberU64()) - int64(f.chainHeight()); dist <= 0 || dist > maxQueueDist { + if dist := int64(block.NumberU64()) - int64(f.chainHeight()); dist < -maxUncleDist || dist > maxQueueDist { glog.V(logger.Detail).Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) return } From 13c25036ea6afc0b13d1d07be6bc298f2ee24216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 18 Jun 2015 20:10:07 +0300 Subject: [PATCH 048/110] eth/fetcher: since uncles are allowed, drop phase test --- eth/fetcher/fetcher_test.go | 51 ------------------------------------- 1 file changed, 51 deletions(-) diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index cdf875c5c..0d069ac65 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -395,54 +395,3 @@ func TestDistantDiscarding(t *testing.T) { t.Fatalf("fetcher queued future block") } } - -// Tests that if multiple uncles (i.e. blocks at the same height) are queued for -// importing, then they will get inserted in phases, previous heights needing to -// complete before the next numbered blocks can begin. -func TestCompetingImports(t *testing.T) { - // Generate a few soft-forks for concurrent imports - hashesA := createHashes(16, knownHash) - hashesB := createHashes(16, knownHash) - hashesC := createHashes(16, knownHash) - - blocksA := createBlocksFromHashes(hashesA) - blocksB := createBlocksFromHashes(hashesB) - blocksC := createBlocksFromHashes(hashesC) - - // Create a tester, and override the import to check number reversals - tester := newTester() - - first := int32(1) - height := uint64(1) - tester.fetcher.insertChain = func(blocks types.Blocks) (int, error) { - // Check for any phase reordering - if prev := atomic.LoadUint64(&height); blocks[0].NumberU64() < prev { - t.Errorf("phase reversal: have %v, want %v", blocks[0].NumberU64(), prev) - } - atomic.StoreUint64(&height, blocks[0].NumberU64()) - - // Sleep a bit on the first import not to race with the enqueues - if atomic.CompareAndSwapInt32(&first, 1, 0) { - time.Sleep(50 * time.Millisecond) - } - return tester.insertChain(blocks) - } - // Queue up everything but with a missing link - for i := 0; i < len(hashesA)-2; i++ { - tester.fetcher.Enqueue("chain A", blocksA[hashesA[i]]) - tester.fetcher.Enqueue("chain B", blocksB[hashesB[i]]) - tester.fetcher.Enqueue("chain C", blocksC[hashesC[i]]) - } - // Add the three missing links, and wait for a full import - tester.fetcher.Enqueue("chain A", blocksA[hashesA[len(hashesA)-2]]) - tester.fetcher.Enqueue("chain B", blocksB[hashesB[len(hashesB)-2]]) - tester.fetcher.Enqueue("chain C", blocksC[hashesC[len(hashesC)-2]]) - - start := time.Now() - for len(tester.hashes) != len(hashesA) && time.Since(start) < time.Second { - time.Sleep(50 * time.Millisecond) - } - if len(tester.hashes) != len(hashesA) { - t.Fatalf("chain length mismatch: have %v, want %v", len(tester.hashes), len(hashesA)) - } -} From 6415ed0730f1e752036e0c79f913e133c318c231 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 8 Jun 2015 16:03:21 -0400 Subject: [PATCH 049/110] Require a first argument of test type --- cmd/ethtest/main.go | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index c2c94d6c4..c33db45d2 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -225,9 +225,29 @@ func main() { helper.Logger.SetLogLevel(5) vm.Debug = true - if len(os.Args) > 1 { - os.Exit(RunVmTest(strings.NewReader(os.Args[1]))) - } else { - os.Exit(RunVmTest(os.Stdin)) + if len(os.Args) < 2 { + glog.Exit("Must specify test type") } + + test := os.Args[1] + + var code int + switch test { + case "vm", "VMTests": + glog.Exit("VMTests not yet implemented") + case "state", "StateTest": + if len(os.Args) > 2 { + code = RunVmTest(strings.NewReader(os.Args[2])) + } else { + code = RunVmTest(os.Stdin) + } + case "tx", "TransactionTests": + glog.Exit("TransactionTests not yet implemented") + case "bc", "BlockChainTest": + glog.Exit("BlockChainTest not yet implemented") + default: + glog.Exit("Invalid test type specified") + } + + os.Exit(code) } From 7b9fbb088a74de746dc3f0aa76dbbc8985c2b12c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 11:55:36 -0400 Subject: [PATCH 050/110] Flatten vm directory --- tests/{vm/gh_test.go => vm.go} | 0 tests/vm/.ethtest | 0 tests/vm/nowarn.go | 3 - tests/vm_test.go | 387 +++++++++++++++++++++++++++++++++ 4 files changed, 387 insertions(+), 3 deletions(-) rename tests/{vm/gh_test.go => vm.go} (100%) delete mode 100644 tests/vm/.ethtest delete mode 100644 tests/vm/nowarn.go create mode 100644 tests/vm_test.go diff --git a/tests/vm/gh_test.go b/tests/vm.go similarity index 100% rename from tests/vm/gh_test.go rename to tests/vm.go diff --git a/tests/vm/.ethtest b/tests/vm/.ethtest deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/vm/nowarn.go b/tests/vm/nowarn.go deleted file mode 100644 index 2a45a6cc6..000000000 --- a/tests/vm/nowarn.go +++ /dev/null @@ -1,3 +0,0 @@ -// This silences the warning given by 'go install ./...'. - -package vm diff --git a/tests/vm_test.go b/tests/vm_test.go new file mode 100644 index 000000000..2f76084d0 --- /dev/null +++ b/tests/vm_test.go @@ -0,0 +1,387 @@ +package vm + +import ( + "bytes" + "math/big" + "os" + "path/filepath" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/tests/helper" +) + +type Account struct { + Balance string + Code string + Nonce string + Storage map[string]string +} + +type Log struct { + AddressF string `json:"address"` + DataF string `json:"data"` + TopicsF []string `json:"topics"` + BloomF string `json:"bloom"` +} + +func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } +func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } +func (self Log) RlpData() interface{} { return nil } +func (self Log) Topics() [][]byte { + t := make([][]byte, len(self.TopicsF)) + for i, topic := range self.TopicsF { + t[i] = common.Hex2Bytes(topic) + } + return t +} + +func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { + obj := state.NewStateObject(common.HexToAddress(addr), db) + obj.SetBalance(common.Big(account.Balance)) + + if common.IsHex(account.Code) { + account.Code = account.Code[2:] + } + obj.SetCode(common.Hex2Bytes(account.Code)) + obj.SetNonce(common.Big(account.Nonce).Uint64()) + + return obj +} + +type Env struct { + CurrentCoinbase string + CurrentDifficulty string + CurrentGasLimit string + CurrentNumber string + CurrentTimestamp interface{} + PreviousHash string +} + +type VmTest struct { + Callcreates interface{} + //Env map[string]string + Env Env + Exec map[string]string + Transaction map[string]string + Logs []Log + Gas string + Out string + Post map[string]Account + Pre map[string]Account + PostStateRoot string +} + +func RunVmTest(p string, t *testing.T) { + + tests := make(map[string]VmTest) + helper.CreateFileTests(t, p, &tests) + + for name, test := range tests { + /* + vm.Debug = true + glog.SetV(4) + glog.SetToStderr(true) + if name != "Call50000_sha256" { + continue + } + */ + db, _ := ethdb.NewMemDatabase() + statedb := state.New(common.Hash{}, db) + for addr, account := range test.Pre { + obj := StateObjectFromAccount(db, addr, account) + statedb.SetStateObject(obj) + for a, v := range account.Storage { + obj.SetState(common.HexToHash(a), common.NewValue(helper.FromHex(v))) + } + } + + // XXX Yeah, yeah... + env := make(map[string]string) + env["currentCoinbase"] = test.Env.CurrentCoinbase + env["currentDifficulty"] = test.Env.CurrentDifficulty + env["currentGasLimit"] = test.Env.CurrentGasLimit + env["currentNumber"] = test.Env.CurrentNumber + env["previousHash"] = test.Env.PreviousHash + if n, ok := test.Env.CurrentTimestamp.(float64); ok { + env["currentTimestamp"] = strconv.Itoa(int(n)) + } else { + env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) + } + + var ( + ret []byte + gas *big.Int + err error + logs state.Logs + ) + + isVmTest := len(test.Exec) > 0 + if isVmTest { + ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec) + } else { + ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction) + } + + switch name { + // the memory required for these tests (4294967297 bytes) would take too much time. + // on 19 May 2015 decided to skip these tests their output. + case "mload32bitBound_return", "mload32bitBound_return2": + default: + rexp := helper.FromHex(test.Out) + if bytes.Compare(rexp, ret) != 0 { + t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) + } + } + + if isVmTest { + if len(test.Gas) == 0 && err == nil { + t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) + } else { + gexp := common.Big(test.Gas) + if gexp.Cmp(gas) != 0 { + t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) + } + } + } + + for addr, account := range test.Post { + obj := statedb.GetStateObject(common.HexToAddress(addr)) + if obj == nil { + continue + } + + if len(test.Exec) == 0 { + if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { + t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) + } + + if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { + t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) + } + + } + + for addr, value := range account.Storage { + v := obj.GetState(common.HexToHash(addr)).Bytes() + vexp := helper.FromHex(value) + + if bytes.Compare(v, vexp) != 0 { + t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) + } + } + } + + if !isVmTest { + statedb.Sync() + //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { + if common.HexToHash(test.PostStateRoot) != statedb.Root() { + t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) + } + } + + if len(test.Logs) > 0 { + if len(test.Logs) != len(logs) { + t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) + } else { + for i, log := range test.Logs { + if common.HexToAddress(log.AddressF) != logs[i].Address { + t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) + } + + if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { + t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) + } + + if len(log.TopicsF) != len(logs[i].Topics) { + t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) + } else { + for j, topic := range log.TopicsF { + if common.HexToHash(topic) != logs[i].Topics[j] { + t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) + } + } + } + genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) + + if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { + t.Errorf("'%s' bloom mismatch", name) + } + } + } + } + //fmt.Println(string(statedb.Dump())) + } + logger.Flush() +} + +// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. +func TestVMArithmetic(t *testing.T) { + const fn = "../files/VMTests/vmArithmeticTest.json" + RunVmTest(fn, t) +} + +func TestBitwiseLogicOperation(t *testing.T) { + const fn = "../files/VMTests/vmBitwiseLogicOperationTest.json" + RunVmTest(fn, t) +} + +func TestBlockInfo(t *testing.T) { + const fn = "../files/VMTests/vmBlockInfoTest.json" + RunVmTest(fn, t) +} + +func TestEnvironmentalInfo(t *testing.T) { + const fn = "../files/VMTests/vmEnvironmentalInfoTest.json" + RunVmTest(fn, t) +} + +func TestFlowOperation(t *testing.T) { + const fn = "../files/VMTests/vmIOandFlowOperationsTest.json" + RunVmTest(fn, t) +} + +func TestLogTest(t *testing.T) { + const fn = "../files/VMTests/vmLogTest.json" + RunVmTest(fn, t) +} + +func TestPerformance(t *testing.T) { + const fn = "../files/VMTests/vmPerformanceTest.json" + RunVmTest(fn, t) +} + +func TestPushDupSwap(t *testing.T) { + const fn = "../files/VMTests/vmPushDupSwapTest.json" + RunVmTest(fn, t) +} + +func TestVMSha3(t *testing.T) { + const fn = "../files/VMTests/vmSha3Test.json" + RunVmTest(fn, t) +} + +func TestVm(t *testing.T) { + const fn = "../files/VMTests/vmtests.json" + RunVmTest(fn, t) +} + +func TestVmLog(t *testing.T) { + const fn = "../files/VMTests/vmLogTest.json" + RunVmTest(fn, t) +} + +func TestInputLimits(t *testing.T) { + const fn = "../files/VMTests/vmInputLimits.json" + RunVmTest(fn, t) +} + +func TestInputLimitsLight(t *testing.T) { + const fn = "../files/VMTests/vmInputLimitsLight.json" + RunVmTest(fn, t) +} + +func TestStateSystemOperations(t *testing.T) { + const fn = "../files/StateTests/stSystemOperationsTest.json" + RunVmTest(fn, t) +} + +func TestStateExample(t *testing.T) { + const fn = "../files/StateTests/stExample.json" + RunVmTest(fn, t) +} + +func TestStatePreCompiledContracts(t *testing.T) { + const fn = "../files/StateTests/stPreCompiledContracts.json" + RunVmTest(fn, t) +} + +func TestStateRecursiveCreate(t *testing.T) { + const fn = "../files/StateTests/stRecursiveCreate.json" + RunVmTest(fn, t) +} + +func TestStateSpecial(t *testing.T) { + const fn = "../files/StateTests/stSpecialTest.json" + RunVmTest(fn, t) +} + +func TestStateRefund(t *testing.T) { + const fn = "../files/StateTests/stRefundTest.json" + RunVmTest(fn, t) +} + +func TestStateBlockHash(t *testing.T) { + const fn = "../files/StateTests/stBlockHashTest.json" + RunVmTest(fn, t) +} + +func TestStateInitCode(t *testing.T) { + const fn = "../files/StateTests/stInitCodeTest.json" + RunVmTest(fn, t) +} + +func TestStateLog(t *testing.T) { + const fn = "../files/StateTests/stLogTests.json" + RunVmTest(fn, t) +} + +func TestStateTransaction(t *testing.T) { + const fn = "../files/StateTests/stTransactionTest.json" + RunVmTest(fn, t) +} + +func TestCallCreateCallCode(t *testing.T) { + const fn = "../files/StateTests/stCallCreateCallCodeTest.json" + RunVmTest(fn, t) +} + +func TestMemory(t *testing.T) { + const fn = "../files/StateTests/stMemoryTest.json" + RunVmTest(fn, t) +} + +func TestMemoryStress(t *testing.T) { + if os.Getenv("TEST_VM_COMPLEX") == "" { + t.Skip() + } + const fn = "../files/StateTests/stMemoryStressTest.json" + RunVmTest(fn, t) +} + +func TestQuadraticComplexity(t *testing.T) { + if os.Getenv("TEST_VM_COMPLEX") == "" { + t.Skip() + } + const fn = "../files/StateTests/stQuadraticComplexityTest.json" + RunVmTest(fn, t) +} + +func TestSolidity(t *testing.T) { + const fn = "../files/StateTests/stSolidityTest.json" + RunVmTest(fn, t) +} + +func TestWallet(t *testing.T) { + const fn = "../files/StateTests/stWalletTest.json" + RunVmTest(fn, t) +} + +func TestStateTestsRandom(t *testing.T) { + fns, _ := filepath.Glob("../files/StateTests/RandomTests/*") + for _, fn := range fns { + RunVmTest(fn, t) + } +} + +func TestVMRandom(t *testing.T) { + fns, _ := filepath.Glob("../files/VMTests/RandomTests/*") + for _, fn := range fns { + RunVmTest(fn, t) + } +} From a67a15528aa5da902a17d49f5dad19db3975032a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 12:04:56 -0400 Subject: [PATCH 051/110] Split tests from helper code --- tests/block_test.go | 69 ------- tests/block_test_util.go | 66 +++++++ tests/state_test.go | 96 ++++++++++ tests/vm_test.go | 311 +------------------------------ tests/{vm.go => vm_test_util.go} | 183 +----------------- 5 files changed, 170 insertions(+), 555 deletions(-) create mode 100644 tests/state_test.go rename tests/{vm.go => vm_test_util.go} (60%) diff --git a/tests/block_test.go b/tests/block_test.go index d5136efce..c017b746e 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -1,14 +1,7 @@ package tests import ( - "path/filepath" "testing" - - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" ) // TODO: refactor test setup & execution to better align with vm and tx tests @@ -50,65 +43,3 @@ func TestBcTotalDifficulty(t *testing.T) { func TestBcWallet(t *testing.T) { runBlockTestsInFile("files/BlockTests/bcWalletTest.json", []string{}, t) } - -func runBlockTestsInFile(filepath string, snafus []string, t *testing.T) { - bt, err := LoadBlockTests(filepath) - if err != nil { - t.Fatal(err) - } - - notWorking := make(map[string]bool, 100) - for _, name := range snafus { - notWorking[name] = true - } - - for name, test := range bt { - if !notWorking[name] { - runBlockTest(name, test, t) - } - } -} - -func runBlockTest(name string, test *BlockTest, t *testing.T) { - cfg := testEthConfig() - ethereum, err := eth.New(cfg) - if err != nil { - t.Fatalf("%v", err) - } - - err = ethereum.Start() - if err != nil { - t.Fatalf("%v", err) - } - - // import the genesis block - ethereum.ResetWithGenesisBlock(test.Genesis) - - // import pre accounts - statedb, err := test.InsertPreState(ethereum) - if err != nil { - t.Fatalf("InsertPreState: %v", err) - } - - err = test.TryBlocksInsert(ethereum.ChainManager()) - if err != nil { - t.Fatal(err) - } - - if err = test.ValidatePostState(statedb); err != nil { - t.Fatal("post state validation failed: %v", err) - } - t.Log("Test passed: ", name) -} - -func testEthConfig() *eth.Config { - ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore")) - - return ð.Config{ - DataDir: common.DefaultDataDir(), - Verbosity: 5, - Etherbase: "primary", - AccountManager: accounts.NewManager(ks), - NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }, - } -} diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 200fcbd59..224c14283 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -7,17 +7,21 @@ import ( "fmt" "io/ioutil" "math/big" + "path/filepath" "runtime" "strconv" "strings" + "testing" "time" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" ) @@ -83,6 +87,68 @@ type btTransaction struct { Value string } +func runBlockTestsInFile(filepath string, snafus []string, t *testing.T) { + bt, err := LoadBlockTests(filepath) + if err != nil { + t.Fatal(err) + } + + notWorking := make(map[string]bool, 100) + for _, name := range snafus { + notWorking[name] = true + } + + for name, test := range bt { + if !notWorking[name] { + runBlockTest(name, test, t) + } + } +} + +func runBlockTest(name string, test *BlockTest, t *testing.T) { + cfg := testEthConfig() + ethereum, err := eth.New(cfg) + if err != nil { + t.Fatalf("%v", err) + } + + err = ethereum.Start() + if err != nil { + t.Fatalf("%v", err) + } + + // import the genesis block + ethereum.ResetWithGenesisBlock(test.Genesis) + + // import pre accounts + statedb, err := test.InsertPreState(ethereum) + if err != nil { + t.Fatalf("InsertPreState: %v", err) + } + + err = test.TryBlocksInsert(ethereum.ChainManager()) + if err != nil { + t.Fatal(err) + } + + if err = test.ValidatePostState(statedb); err != nil { + t.Fatal("post state validation failed: %v", err) + } + t.Log("Test passed: ", name) +} + +func testEthConfig() *eth.Config { + ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore")) + + return ð.Config{ + DataDir: common.DefaultDataDir(), + Verbosity: 5, + Etherbase: "primary", + AccountManager: accounts.NewManager(ks), + NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }, + } +} + // LoadBlockTests loads a block test JSON file. func LoadBlockTests(file string) (map[string]*BlockTest, error) { bt := make(map[string]*btJSON) diff --git a/tests/state_test.go b/tests/state_test.go new file mode 100644 index 000000000..5e7be124b --- /dev/null +++ b/tests/state_test.go @@ -0,0 +1,96 @@ +package tests + +import "testing" + +func TestStateSystemOperations(t *testing.T) { + const fn = "../files/StateTests/stSystemOperationsTest.json" + RunVmTest(fn, t) +} + +func TestStateExample(t *testing.T) { + const fn = "../files/StateTests/stExample.json" + RunVmTest(fn, t) +} + +func TestStatePreCompiledContracts(t *testing.T) { + const fn = "../files/StateTests/stPreCompiledContracts.json" + RunVmTest(fn, t) +} + +func TestStateRecursiveCreate(t *testing.T) { + const fn = "../files/StateTests/stRecursiveCreate.json" + RunVmTest(fn, t) +} + +func TestStateSpecial(t *testing.T) { + const fn = "../files/StateTests/stSpecialTest.json" + RunVmTest(fn, t) +} + +func TestStateRefund(t *testing.T) { + const fn = "../files/StateTests/stRefundTest.json" + RunVmTest(fn, t) +} + +func TestStateBlockHash(t *testing.T) { + const fn = "../files/StateTests/stBlockHashTest.json" + RunVmTest(fn, t) +} + +func TestStateInitCode(t *testing.T) { + const fn = "../files/StateTests/stInitCodeTest.json" + RunVmTest(fn, t) +} + +func TestStateLog(t *testing.T) { + const fn = "../files/StateTests/stLogTests.json" + RunVmTest(fn, t) +} + +func TestStateTransaction(t *testing.T) { + const fn = "../files/StateTests/stTransactionTest.json" + RunVmTest(fn, t) +} + +func TestCallCreateCallCode(t *testing.T) { + const fn = "../files/StateTests/stCallCreateCallCodeTest.json" + RunVmTest(fn, t) +} + +func TestMemory(t *testing.T) { + const fn = "../files/StateTests/stMemoryTest.json" + RunVmTest(fn, t) +} + +func TestMemoryStress(t *testing.T) { + if os.Getenv("TEST_VM_COMPLEX") == "" { + t.Skip() + } + const fn = "../files/StateTests/stMemoryStressTest.json" + RunVmTest(fn, t) +} + +func TestQuadraticComplexity(t *testing.T) { + if os.Getenv("TEST_VM_COMPLEX") == "" { + t.Skip() + } + const fn = "../files/StateTests/stQuadraticComplexityTest.json" + RunVmTest(fn, t) +} + +func TestSolidity(t *testing.T) { + const fn = "../files/StateTests/stSolidityTest.json" + RunVmTest(fn, t) +} + +func TestWallet(t *testing.T) { + const fn = "../files/StateTests/stWalletTest.json" + RunVmTest(fn, t) +} + +func TestStateTestsRandom(t *testing.T) { + fns, _ := filepath.Glob("../files/StateTests/RandomTests/*") + for _, fn := range fns { + RunVmTest(fn, t) + } +} diff --git a/tests/vm_test.go b/tests/vm_test.go index 2f76084d0..b42f83df8 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -1,225 +1,9 @@ -package vm +package tests import ( - "bytes" - "math/big" - "os" - "path/filepath" - "strconv" "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/tests/helper" ) -type Account struct { - Balance string - Code string - Nonce string - Storage map[string]string -} - -type Log struct { - AddressF string `json:"address"` - DataF string `json:"data"` - TopicsF []string `json:"topics"` - BloomF string `json:"bloom"` -} - -func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } -func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } -func (self Log) RlpData() interface{} { return nil } -func (self Log) Topics() [][]byte { - t := make([][]byte, len(self.TopicsF)) - for i, topic := range self.TopicsF { - t[i] = common.Hex2Bytes(topic) - } - return t -} - -func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { - obj := state.NewStateObject(common.HexToAddress(addr), db) - obj.SetBalance(common.Big(account.Balance)) - - if common.IsHex(account.Code) { - account.Code = account.Code[2:] - } - obj.SetCode(common.Hex2Bytes(account.Code)) - obj.SetNonce(common.Big(account.Nonce).Uint64()) - - return obj -} - -type Env struct { - CurrentCoinbase string - CurrentDifficulty string - CurrentGasLimit string - CurrentNumber string - CurrentTimestamp interface{} - PreviousHash string -} - -type VmTest struct { - Callcreates interface{} - //Env map[string]string - Env Env - Exec map[string]string - Transaction map[string]string - Logs []Log - Gas string - Out string - Post map[string]Account - Pre map[string]Account - PostStateRoot string -} - -func RunVmTest(p string, t *testing.T) { - - tests := make(map[string]VmTest) - helper.CreateFileTests(t, p, &tests) - - for name, test := range tests { - /* - vm.Debug = true - glog.SetV(4) - glog.SetToStderr(true) - if name != "Call50000_sha256" { - continue - } - */ - db, _ := ethdb.NewMemDatabase() - statedb := state.New(common.Hash{}, db) - for addr, account := range test.Pre { - obj := StateObjectFromAccount(db, addr, account) - statedb.SetStateObject(obj) - for a, v := range account.Storage { - obj.SetState(common.HexToHash(a), common.NewValue(helper.FromHex(v))) - } - } - - // XXX Yeah, yeah... - env := make(map[string]string) - env["currentCoinbase"] = test.Env.CurrentCoinbase - env["currentDifficulty"] = test.Env.CurrentDifficulty - env["currentGasLimit"] = test.Env.CurrentGasLimit - env["currentNumber"] = test.Env.CurrentNumber - env["previousHash"] = test.Env.PreviousHash - if n, ok := test.Env.CurrentTimestamp.(float64); ok { - env["currentTimestamp"] = strconv.Itoa(int(n)) - } else { - env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) - } - - var ( - ret []byte - gas *big.Int - err error - logs state.Logs - ) - - isVmTest := len(test.Exec) > 0 - if isVmTest { - ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec) - } else { - ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction) - } - - switch name { - // the memory required for these tests (4294967297 bytes) would take too much time. - // on 19 May 2015 decided to skip these tests their output. - case "mload32bitBound_return", "mload32bitBound_return2": - default: - rexp := helper.FromHex(test.Out) - if bytes.Compare(rexp, ret) != 0 { - t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) - } - } - - if isVmTest { - if len(test.Gas) == 0 && err == nil { - t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) - } else { - gexp := common.Big(test.Gas) - if gexp.Cmp(gas) != 0 { - t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) - } - } - } - - for addr, account := range test.Post { - obj := statedb.GetStateObject(common.HexToAddress(addr)) - if obj == nil { - continue - } - - if len(test.Exec) == 0 { - if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { - t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) - } - - if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { - t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) - } - - } - - for addr, value := range account.Storage { - v := obj.GetState(common.HexToHash(addr)).Bytes() - vexp := helper.FromHex(value) - - if bytes.Compare(v, vexp) != 0 { - t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) - } - } - } - - if !isVmTest { - statedb.Sync() - //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { - if common.HexToHash(test.PostStateRoot) != statedb.Root() { - t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) - } - } - - if len(test.Logs) > 0 { - if len(test.Logs) != len(logs) { - t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) - } else { - for i, log := range test.Logs { - if common.HexToAddress(log.AddressF) != logs[i].Address { - t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) - } - - if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { - t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) - } - - if len(log.TopicsF) != len(logs[i].Topics) { - t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) - } else { - for j, topic := range log.TopicsF { - if common.HexToHash(topic) != logs[i].Topics[j] { - t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) - } - } - } - genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) - - if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { - t.Errorf("'%s' bloom mismatch", name) - } - } - } - } - //fmt.Println(string(statedb.Dump())) - } - logger.Flush() -} - // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. func TestVMArithmetic(t *testing.T) { const fn = "../files/VMTests/vmArithmeticTest.json" @@ -286,99 +70,6 @@ func TestInputLimitsLight(t *testing.T) { RunVmTest(fn, t) } -func TestStateSystemOperations(t *testing.T) { - const fn = "../files/StateTests/stSystemOperationsTest.json" - RunVmTest(fn, t) -} - -func TestStateExample(t *testing.T) { - const fn = "../files/StateTests/stExample.json" - RunVmTest(fn, t) -} - -func TestStatePreCompiledContracts(t *testing.T) { - const fn = "../files/StateTests/stPreCompiledContracts.json" - RunVmTest(fn, t) -} - -func TestStateRecursiveCreate(t *testing.T) { - const fn = "../files/StateTests/stRecursiveCreate.json" - RunVmTest(fn, t) -} - -func TestStateSpecial(t *testing.T) { - const fn = "../files/StateTests/stSpecialTest.json" - RunVmTest(fn, t) -} - -func TestStateRefund(t *testing.T) { - const fn = "../files/StateTests/stRefundTest.json" - RunVmTest(fn, t) -} - -func TestStateBlockHash(t *testing.T) { - const fn = "../files/StateTests/stBlockHashTest.json" - RunVmTest(fn, t) -} - -func TestStateInitCode(t *testing.T) { - const fn = "../files/StateTests/stInitCodeTest.json" - RunVmTest(fn, t) -} - -func TestStateLog(t *testing.T) { - const fn = "../files/StateTests/stLogTests.json" - RunVmTest(fn, t) -} - -func TestStateTransaction(t *testing.T) { - const fn = "../files/StateTests/stTransactionTest.json" - RunVmTest(fn, t) -} - -func TestCallCreateCallCode(t *testing.T) { - const fn = "../files/StateTests/stCallCreateCallCodeTest.json" - RunVmTest(fn, t) -} - -func TestMemory(t *testing.T) { - const fn = "../files/StateTests/stMemoryTest.json" - RunVmTest(fn, t) -} - -func TestMemoryStress(t *testing.T) { - if os.Getenv("TEST_VM_COMPLEX") == "" { - t.Skip() - } - const fn = "../files/StateTests/stMemoryStressTest.json" - RunVmTest(fn, t) -} - -func TestQuadraticComplexity(t *testing.T) { - if os.Getenv("TEST_VM_COMPLEX") == "" { - t.Skip() - } - const fn = "../files/StateTests/stQuadraticComplexityTest.json" - RunVmTest(fn, t) -} - -func TestSolidity(t *testing.T) { - const fn = "../files/StateTests/stSolidityTest.json" - RunVmTest(fn, t) -} - -func TestWallet(t *testing.T) { - const fn = "../files/StateTests/stWalletTest.json" - RunVmTest(fn, t) -} - -func TestStateTestsRandom(t *testing.T) { - fns, _ := filepath.Glob("../files/StateTests/RandomTests/*") - for _, fn := range fns { - RunVmTest(fn, t) - } -} - func TestVMRandom(t *testing.T) { fns, _ := filepath.Glob("../files/VMTests/RandomTests/*") for _, fn := range fns { diff --git a/tests/vm.go b/tests/vm_test_util.go similarity index 60% rename from tests/vm.go rename to tests/vm_test_util.go index be9e89d9c..f91070736 100644 --- a/tests/vm.go +++ b/tests/vm_test_util.go @@ -1,10 +1,8 @@ -package vm +package tests import ( "bytes" "math/big" - "os" - "path/filepath" "strconv" "testing" @@ -84,12 +82,12 @@ func RunVmTest(p string, t *testing.T) { for name, test := range tests { /* - vm.Debug = true - glog.SetV(4) - glog.SetToStderr(true) - if name != "Call50000_sha256" { - continue - } + vm.Debug = true + glog.SetV(4) + glog.SetToStderr(true) + if name != "Call50000_sha256" { + continue + } */ db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) @@ -219,170 +217,3 @@ func RunVmTest(p string, t *testing.T) { } logger.Flush() } - -// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. -func TestVMArithmetic(t *testing.T) { - const fn = "../files/VMTests/vmArithmeticTest.json" - RunVmTest(fn, t) -} - -func TestBitwiseLogicOperation(t *testing.T) { - const fn = "../files/VMTests/vmBitwiseLogicOperationTest.json" - RunVmTest(fn, t) -} - -func TestBlockInfo(t *testing.T) { - const fn = "../files/VMTests/vmBlockInfoTest.json" - RunVmTest(fn, t) -} - -func TestEnvironmentalInfo(t *testing.T) { - const fn = "../files/VMTests/vmEnvironmentalInfoTest.json" - RunVmTest(fn, t) -} - -func TestFlowOperation(t *testing.T) { - const fn = "../files/VMTests/vmIOandFlowOperationsTest.json" - RunVmTest(fn, t) -} - -func TestLogTest(t *testing.T) { - const fn = "../files/VMTests/vmLogTest.json" - RunVmTest(fn, t) -} - -func TestPerformance(t *testing.T) { - const fn = "../files/VMTests/vmPerformanceTest.json" - RunVmTest(fn, t) -} - -func TestPushDupSwap(t *testing.T) { - const fn = "../files/VMTests/vmPushDupSwapTest.json" - RunVmTest(fn, t) -} - -func TestVMSha3(t *testing.T) { - const fn = "../files/VMTests/vmSha3Test.json" - RunVmTest(fn, t) -} - -func TestVm(t *testing.T) { - const fn = "../files/VMTests/vmtests.json" - RunVmTest(fn, t) -} - -func TestVmLog(t *testing.T) { - const fn = "../files/VMTests/vmLogTest.json" - RunVmTest(fn, t) -} - -func TestInputLimits(t *testing.T) { - const fn = "../files/VMTests/vmInputLimits.json" - RunVmTest(fn, t) -} - -func TestInputLimitsLight(t *testing.T) { - const fn = "../files/VMTests/vmInputLimitsLight.json" - RunVmTest(fn, t) -} - -func TestStateSystemOperations(t *testing.T) { - const fn = "../files/StateTests/stSystemOperationsTest.json" - RunVmTest(fn, t) -} - -func TestStateExample(t *testing.T) { - const fn = "../files/StateTests/stExample.json" - RunVmTest(fn, t) -} - -func TestStatePreCompiledContracts(t *testing.T) { - const fn = "../files/StateTests/stPreCompiledContracts.json" - RunVmTest(fn, t) -} - -func TestStateRecursiveCreate(t *testing.T) { - const fn = "../files/StateTests/stRecursiveCreate.json" - RunVmTest(fn, t) -} - -func TestStateSpecial(t *testing.T) { - const fn = "../files/StateTests/stSpecialTest.json" - RunVmTest(fn, t) -} - -func TestStateRefund(t *testing.T) { - const fn = "../files/StateTests/stRefundTest.json" - RunVmTest(fn, t) -} - -func TestStateBlockHash(t *testing.T) { - const fn = "../files/StateTests/stBlockHashTest.json" - RunVmTest(fn, t) -} - -func TestStateInitCode(t *testing.T) { - const fn = "../files/StateTests/stInitCodeTest.json" - RunVmTest(fn, t) -} - -func TestStateLog(t *testing.T) { - const fn = "../files/StateTests/stLogTests.json" - RunVmTest(fn, t) -} - -func TestStateTransaction(t *testing.T) { - const fn = "../files/StateTests/stTransactionTest.json" - RunVmTest(fn, t) -} - -func TestCallCreateCallCode(t *testing.T) { - const fn = "../files/StateTests/stCallCreateCallCodeTest.json" - RunVmTest(fn, t) -} - -func TestMemory(t *testing.T) { - const fn = "../files/StateTests/stMemoryTest.json" - RunVmTest(fn, t) -} - -func TestMemoryStress(t *testing.T) { - if os.Getenv("TEST_VM_COMPLEX") == "" { - t.Skip() - } - const fn = "../files/StateTests/stMemoryStressTest.json" - RunVmTest(fn, t) -} - -func TestQuadraticComplexity(t *testing.T) { - if os.Getenv("TEST_VM_COMPLEX") == "" { - t.Skip() - } - const fn = "../files/StateTests/stQuadraticComplexityTest.json" - RunVmTest(fn, t) -} - -func TestSolidity(t *testing.T) { - const fn = "../files/StateTests/stSolidityTest.json" - RunVmTest(fn, t) -} - -func TestWallet(t *testing.T) { - const fn = "../files/StateTests/stWalletTest.json" - RunVmTest(fn, t) -} - -func TestStateTestsRandom(t *testing.T) { - fns, _ := filepath.Glob("../files/StateTests/RandomTests/*") - for _, fn := range fns { - RunVmTest(fn, t) - } -} - -func TestVMRandom(t *testing.T) { - t.Skip() // fucked as of 2015-06-09. unskip once unfucked /Gustav - fns, _ := filepath.Glob("../files/VMTests/RandomTests/*") - for _, fn := range fns { - RunVmTest(fn, t) - } -} From e82100367f794856a8807b5fcfe9f0043902a294 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 12:34:38 -0400 Subject: [PATCH 052/110] Fix paths --- tests/block_test.go | 24 ++++++++++++---------- tests/state_test.go | 42 ++++++++++++++++++++++----------------- tests/transaction_test.go | 9 ++++++--- tests/vm_test.go | 31 ++++++++++++++++------------- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/tests/block_test.go b/tests/block_test.go index c017b746e..1f2e5a15b 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -1,45 +1,49 @@ package tests import ( + "path/filepath" "testing" ) +var baseDir = filepath.Join(".", "files") +var blockTestDir = filepath.Join(baseDir, "BlockTests") + // TODO: refactor test setup & execution to better align with vm and tx tests func TestBcValidBlockTests(t *testing.T) { // SimpleTx3 genesis block does not validate against calculated state root // as of 2015-06-09. unskip once working /Gustav - runBlockTestsInFile("files/BlockTests/bcValidBlockTest.json", []string{"SimpleTx3"}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}, t) } func TestBcUncleTests(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcUncleTest.json", []string{}, t) - runBlockTestsInFile("files/BlockTests/bcBruncleTest.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcBruncleTest.json"), []string{}, t) } func TestBcUncleHeaderValidityTests(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcUncleHeaderValiditiy.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), []string{}, t) } func TestBcInvalidHeaderTests(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcInvalidHeaderTest.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), []string{}, t) } func TestBcInvalidRLPTests(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcInvalidRLPTest.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), []string{}, t) } func TestBcRPCAPITests(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcRPC_API_Test.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcRPC_API_Test.json"), []string{}, t) } func TestBcForkBlockTests(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcForkBlockTest.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcForkBlockTest.json"), []string{}, t) } func TestBcTotalDifficulty(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcTotalDifficultyTest.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), []string{}, t) } func TestBcWallet(t *testing.T) { - runBlockTestsInFile("files/BlockTests/bcWalletTest.json", []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcWalletTest.json"), []string{}, t) } diff --git a/tests/state_test.go b/tests/state_test.go index 5e7be124b..fa000ec53 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -1,64 +1,70 @@ package tests -import "testing" +import ( + "os" + "path/filepath" + "testing" +) + +var stateTestDir = filepath.Join(baseDir, "StateTests") func TestStateSystemOperations(t *testing.T) { - const fn = "../files/StateTests/stSystemOperationsTest.json" + fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") RunVmTest(fn, t) } func TestStateExample(t *testing.T) { - const fn = "../files/StateTests/stExample.json" + fn := filepath.Join(stateTestDir, "stExample.json") RunVmTest(fn, t) } func TestStatePreCompiledContracts(t *testing.T) { - const fn = "../files/StateTests/stPreCompiledContracts.json" + fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json") RunVmTest(fn, t) } func TestStateRecursiveCreate(t *testing.T) { - const fn = "../files/StateTests/stRecursiveCreate.json" + fn := filepath.Join(stateTestDir, "stRecursiveCreate.json") RunVmTest(fn, t) } func TestStateSpecial(t *testing.T) { - const fn = "../files/StateTests/stSpecialTest.json" + fn := filepath.Join(stateTestDir, "stSpecialTest.json") RunVmTest(fn, t) } func TestStateRefund(t *testing.T) { - const fn = "../files/StateTests/stRefundTest.json" + fn := filepath.Join(stateTestDir, "stRefundTest.json") RunVmTest(fn, t) } func TestStateBlockHash(t *testing.T) { - const fn = "../files/StateTests/stBlockHashTest.json" + fn := filepath.Join(stateTestDir, "stBlockHashTest.json") RunVmTest(fn, t) } func TestStateInitCode(t *testing.T) { - const fn = "../files/StateTests/stInitCodeTest.json" + fn := filepath.Join(stateTestDir, "stInitCodeTest.json") RunVmTest(fn, t) } func TestStateLog(t *testing.T) { - const fn = "../files/StateTests/stLogTests.json" + fn := filepath.Join(stateTestDir, "stLogTests.json") RunVmTest(fn, t) } func TestStateTransaction(t *testing.T) { - const fn = "../files/StateTests/stTransactionTest.json" + fn := filepath.Join(stateTestDir, "stTransactionTest.json") RunVmTest(fn, t) } func TestCallCreateCallCode(t *testing.T) { - const fn = "../files/StateTests/stCallCreateCallCodeTest.json" + fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json") RunVmTest(fn, t) } func TestMemory(t *testing.T) { - const fn = "../files/StateTests/stMemoryTest.json" + fn := filepath.Join(stateTestDir, "stMemoryTest.json") RunVmTest(fn, t) } @@ -66,7 +72,7 @@ func TestMemoryStress(t *testing.T) { if os.Getenv("TEST_VM_COMPLEX") == "" { t.Skip() } - const fn = "../files/StateTests/stMemoryStressTest.json" + fn := filepath.Join(stateTestDir, "stMemoryStressTest.json") RunVmTest(fn, t) } @@ -74,22 +80,22 @@ func TestQuadraticComplexity(t *testing.T) { if os.Getenv("TEST_VM_COMPLEX") == "" { t.Skip() } - const fn = "../files/StateTests/stQuadraticComplexityTest.json" + fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json") RunVmTest(fn, t) } func TestSolidity(t *testing.T) { - const fn = "../files/StateTests/stSolidityTest.json" + fn := filepath.Join(stateTestDir, "stSolidityTest.json") RunVmTest(fn, t) } func TestWallet(t *testing.T) { - const fn = "../files/StateTests/stWalletTest.json" + fn := filepath.Join(stateTestDir, "stWalletTest.json") RunVmTest(fn, t) } func TestStateTestsRandom(t *testing.T) { - fns, _ := filepath.Glob("../files/StateTests/RandomTests/*") + fns, _ := filepath.Glob("./files/StateTests/RandomTests/*") for _, fn := range fns { RunVmTest(fn, t) } diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 7ae1c8788..05942d3bf 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -1,9 +1,12 @@ package tests import ( + "path/filepath" "testing" ) +var transactionTestDir = filepath.Join(baseDir, "TransactionTests") + func TestTransactions(t *testing.T) { notWorking := make(map[string]bool, 100) @@ -17,7 +20,7 @@ func TestTransactions(t *testing.T) { } var err error - err = RunTransactionTests("./files/TransactionTests/ttTransactionTest.json", + err = RunTransactionTests(filepath.Join(transactionTestDir, "ttTransactionTest.json"), notWorking) if err != nil { t.Fatal(err) @@ -27,7 +30,7 @@ func TestTransactions(t *testing.T) { func TestWrongRLPTransactions(t *testing.T) { notWorking := make(map[string]bool, 100) var err error - err = RunTransactionTests("./files/TransactionTests/ttWrongRLPTransaction.json", + err = RunTransactionTests(filepath.Join(transactionTestDir, "ttWrongRLPTransaction.json"), notWorking) if err != nil { t.Fatal(err) @@ -37,7 +40,7 @@ func TestWrongRLPTransactions(t *testing.T) { func Test10MBtx(t *testing.T) { notWorking := make(map[string]bool, 100) var err error - err = RunTransactionTests("./files/TransactionTests/tt10mbDataField.json", + err = RunTransactionTests(filepath.Join(transactionTestDir, "tt10mbDataField.json"), notWorking) if err != nil { t.Fatal(err) diff --git a/tests/vm_test.go b/tests/vm_test.go index b42f83df8..faa3205bc 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -1,77 +1,80 @@ package tests import ( + "path/filepath" "testing" ) +var vmTestDir = filepath.Join(baseDir, "VMTests") + // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. func TestVMArithmetic(t *testing.T) { - const fn = "../files/VMTests/vmArithmeticTest.json" + fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") RunVmTest(fn, t) } func TestBitwiseLogicOperation(t *testing.T) { - const fn = "../files/VMTests/vmBitwiseLogicOperationTest.json" + fn := filepath.Join(vmTestDir, "vmBitwiseLogicOperationTest.json") RunVmTest(fn, t) } func TestBlockInfo(t *testing.T) { - const fn = "../files/VMTests/vmBlockInfoTest.json" + fn := filepath.Join(vmTestDir, "vmBlockInfoTest.json") RunVmTest(fn, t) } func TestEnvironmentalInfo(t *testing.T) { - const fn = "../files/VMTests/vmEnvironmentalInfoTest.json" + fn := filepath.Join(vmTestDir, "vmEnvironmentalInfoTest.json") RunVmTest(fn, t) } func TestFlowOperation(t *testing.T) { - const fn = "../files/VMTests/vmIOandFlowOperationsTest.json" + fn := filepath.Join(vmTestDir, "vmIOandFlowOperationsTest.json") RunVmTest(fn, t) } func TestLogTest(t *testing.T) { - const fn = "../files/VMTests/vmLogTest.json" + fn := filepath.Join(vmTestDir, "vmLogTest.json") RunVmTest(fn, t) } func TestPerformance(t *testing.T) { - const fn = "../files/VMTests/vmPerformanceTest.json" + fn := filepath.Join(vmTestDir, "vmPerformanceTest.json") RunVmTest(fn, t) } func TestPushDupSwap(t *testing.T) { - const fn = "../files/VMTests/vmPushDupSwapTest.json" + fn := filepath.Join(vmTestDir, "vmPushDupSwapTest.json") RunVmTest(fn, t) } func TestVMSha3(t *testing.T) { - const fn = "../files/VMTests/vmSha3Test.json" + fn := filepath.Join(vmTestDir, "vmSha3Test.json") RunVmTest(fn, t) } func TestVm(t *testing.T) { - const fn = "../files/VMTests/vmtests.json" + fn := filepath.Join(vmTestDir, "vmtests.json") RunVmTest(fn, t) } func TestVmLog(t *testing.T) { - const fn = "../files/VMTests/vmLogTest.json" + fn := filepath.Join(vmTestDir, "vmLogTest.json") RunVmTest(fn, t) } func TestInputLimits(t *testing.T) { - const fn = "../files/VMTests/vmInputLimits.json" + fn := filepath.Join(vmTestDir, "vmInputLimits.json") RunVmTest(fn, t) } func TestInputLimitsLight(t *testing.T) { - const fn = "../files/VMTests/vmInputLimitsLight.json" + fn := filepath.Join(vmTestDir, "vmInputLimitsLight.json") RunVmTest(fn, t) } func TestVMRandom(t *testing.T) { - fns, _ := filepath.Glob("../files/VMTests/RandomTests/*") + fns, _ := filepath.Glob(filepath.Join(baseDir, "RandomTests", "*")) for _, fn := range fns { RunVmTest(fn, t) } From 1b26d4f220689dac18d560a4c1ecb3b29d99deb0 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 13:00:54 -0400 Subject: [PATCH 053/110] Flatten helper directory --- tests/helper/common.go | 11 ---------- tests/helper/init.go | 16 -------------- tests/helper/trie.go | 31 ---------------------------- tests/{helper/readers.go => init.go} | 13 +++++++++++- tests/{helper => }/vm.go | 6 +++--- tests/vm_test_util.go | 15 +++++++------- 6 files changed, 22 insertions(+), 70 deletions(-) delete mode 100644 tests/helper/common.go delete mode 100644 tests/helper/init.go delete mode 100644 tests/helper/trie.go rename tests/{helper/readers.go => init.go} (69%) rename tests/{helper => }/vm.go (98%) diff --git a/tests/helper/common.go b/tests/helper/common.go deleted file mode 100644 index 21ea2261f..000000000 --- a/tests/helper/common.go +++ /dev/null @@ -1,11 +0,0 @@ -package helper - -import "github.com/ethereum/go-ethereum/common" - -func FromHex(h string) []byte { - if common.IsHex(h) { - h = h[2:] - } - - return common.Hex2Bytes(h) -} diff --git a/tests/helper/init.go b/tests/helper/init.go deleted file mode 100644 index 73d563e02..000000000 --- a/tests/helper/init.go +++ /dev/null @@ -1,16 +0,0 @@ -package helper - -import ( - "log" - "os" - - logpkg "github.com/ethereum/go-ethereum/logger" -) - -var Logger *logpkg.StdLogSystem -var Log = logpkg.NewLogger("TEST") - -func init() { - Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel) - logpkg.AddLogSystem(Logger) -} diff --git a/tests/helper/trie.go b/tests/helper/trie.go deleted file mode 100644 index 9e666d333..000000000 --- a/tests/helper/trie.go +++ /dev/null @@ -1,31 +0,0 @@ -package helper - -import "github.com/ethereum/go-ethereum/trie" - -type MemDatabase struct { - db map[string][]byte -} - -func NewMemDatabase() (*MemDatabase, error) { - db := &MemDatabase{db: make(map[string][]byte)} - return db, nil -} -func (db *MemDatabase) Put(key []byte, value []byte) { - db.db[string(key)] = value -} -func (db *MemDatabase) Get(key []byte) ([]byte, error) { - return db.db[string(key)], nil -} -func (db *MemDatabase) Delete(key []byte) error { - delete(db.db, string(key)) - return nil -} -func (db *MemDatabase) Print() {} -func (db *MemDatabase) Close() {} -func (db *MemDatabase) LastKnownTD() []byte { return nil } - -func NewTrie() *trie.Trie { - db, _ := NewMemDatabase() - - return trie.New(nil, db) -} diff --git a/tests/helper/readers.go b/tests/init.go similarity index 69% rename from tests/helper/readers.go rename to tests/init.go index 03313aeda..b487f81c3 100644 --- a/tests/helper/readers.go +++ b/tests/init.go @@ -1,14 +1,25 @@ -package helper +package tests import ( "encoding/json" "io" "io/ioutil" + // "log" "net/http" "os" "testing" + + // logpkg "github.com/ethereum/go-ethereum/logger" ) +// var Logger *logpkg.StdLogSystem +// var Log = logpkg.NewLogger("TEST") + +// func init() { +// Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel) +// logpkg.AddLogSystem(Logger) +// } + func readJSON(t *testing.T, reader io.Reader, value interface{}) { data, err := ioutil.ReadAll(reader) err = json.Unmarshal(data, &value) diff --git a/tests/helper/vm.go b/tests/vm.go similarity index 98% rename from tests/helper/vm.go rename to tests/vm.go index e29a2d8ee..52e498ccc 100644 --- a/tests/helper/vm.go +++ b/tests/vm.go @@ -1,4 +1,4 @@ -package helper +package tests import ( "errors" @@ -144,7 +144,7 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Log var ( to = common.HexToAddress(exec["address"]) from = common.HexToAddress(exec["caller"]) - data = FromHex(exec["data"]) + data = common.FromHex(exec["data"]) gas = common.Big(exec["gas"]) price = common.Big(exec["gasPrice"]) value = common.Big(exec["value"]) @@ -166,7 +166,7 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Log func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { var ( keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) - data = FromHex(tx["data"]) + data = common.FromHex(tx["data"]) gas = common.Big(tx["gasLimit"]) price = common.Big(tx["gasPrice"]) value = common.Big(tx["value"]) diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index f91070736..cf95db80f 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/tests/helper" ) type Account struct { @@ -52,7 +51,7 @@ func StateObjectFromAccount(db common.Database, addr string, account Account) *s return obj } -type Env struct { +type VmEnv struct { CurrentCoinbase string CurrentDifficulty string CurrentGasLimit string @@ -64,7 +63,7 @@ type Env struct { type VmTest struct { Callcreates interface{} //Env map[string]string - Env Env + Env VmEnv Exec map[string]string Transaction map[string]string Logs []Log @@ -78,7 +77,7 @@ type VmTest struct { func RunVmTest(p string, t *testing.T) { tests := make(map[string]VmTest) - helper.CreateFileTests(t, p, &tests) + CreateFileTests(t, p, &tests) for name, test := range tests { /* @@ -121,9 +120,9 @@ func RunVmTest(p string, t *testing.T) { isVmTest := len(test.Exec) > 0 if isVmTest { - ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec) + ret, logs, gas, err = RunVm(statedb, env, test.Exec) } else { - ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction) + ret, logs, gas, err = RunState(statedb, env, test.Transaction) } switch name { @@ -131,7 +130,7 @@ func RunVmTest(p string, t *testing.T) { // on 19 May 2015 decided to skip these tests their output. case "mload32bitBound_return", "mload32bitBound_return2": default: - rexp := helper.FromHex(test.Out) + rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } @@ -192,7 +191,7 @@ func RunVmTest(p string, t *testing.T) { t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) } - if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { + if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) } From 7c6ef0ddac91564f31ef852fd4ef1e821db17c2e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 14:38:39 -0400 Subject: [PATCH 054/110] Separate and identify tests runners --- tests/block_test_util.go | 3 +- tests/state_test.go | 34 ++--- tests/state_test_util.go | 181 +++++++++++++++++++++++++ tests/transaction_test_util.go | 2 +- tests/vm.go | 220 ------------------------------- tests/vm_test_util.go | 234 ++++++++++++++++++++++++++------- 6 files changed, 389 insertions(+), 285 deletions(-) create mode 100644 tests/state_test_util.go delete mode 100644 tests/vm.go diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 224c14283..e60607c0f 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -134,7 +134,8 @@ func runBlockTest(name string, test *BlockTest, t *testing.T) { if err = test.ValidatePostState(statedb); err != nil { t.Fatal("post state validation failed: %v", err) } - t.Log("Test passed: ", name) + fmt.Println("Block test passed: ", name) + // t.Log("Block test passed: ", name) } func testEthConfig() *eth.Config { diff --git a/tests/state_test.go b/tests/state_test.go index fa000ec53..dbef7bd0c 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -10,62 +10,62 @@ var stateTestDir = filepath.Join(baseDir, "StateTests") func TestStateSystemOperations(t *testing.T) { fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateExample(t *testing.T) { fn := filepath.Join(stateTestDir, "stExample.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStatePreCompiledContracts(t *testing.T) { fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateRecursiveCreate(t *testing.T) { fn := filepath.Join(stateTestDir, "stRecursiveCreate.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateSpecial(t *testing.T) { fn := filepath.Join(stateTestDir, "stSpecialTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateRefund(t *testing.T) { fn := filepath.Join(stateTestDir, "stRefundTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateBlockHash(t *testing.T) { fn := filepath.Join(stateTestDir, "stBlockHashTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateInitCode(t *testing.T) { fn := filepath.Join(stateTestDir, "stInitCodeTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateLog(t *testing.T) { fn := filepath.Join(stateTestDir, "stLogTests.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateTransaction(t *testing.T) { fn := filepath.Join(stateTestDir, "stTransactionTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestCallCreateCallCode(t *testing.T) { fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestMemory(t *testing.T) { fn := filepath.Join(stateTestDir, "stMemoryTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestMemoryStress(t *testing.T) { @@ -73,7 +73,7 @@ func TestMemoryStress(t *testing.T) { t.Skip() } fn := filepath.Join(stateTestDir, "stMemoryStressTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestQuadraticComplexity(t *testing.T) { @@ -81,22 +81,22 @@ func TestQuadraticComplexity(t *testing.T) { t.Skip() } fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestSolidity(t *testing.T) { fn := filepath.Join(stateTestDir, "stSolidityTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestWallet(t *testing.T) { fn := filepath.Join(stateTestDir, "stWalletTest.json") - RunVmTest(fn, t) + RunStateTest(fn, t) } func TestStateTestsRandom(t *testing.T) { fns, _ := filepath.Glob("./files/StateTests/RandomTests/*") for _, fn := range fns { - RunVmTest(fn, t) + RunStateTest(fn, t) } } diff --git a/tests/state_test_util.go b/tests/state_test_util.go new file mode 100644 index 000000000..1f481147e --- /dev/null +++ b/tests/state_test_util.go @@ -0,0 +1,181 @@ +package tests + +import ( + "bytes" + // "errors" + "fmt" + "math/big" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + // "github.com/ethereum/go-ethereum/logger" +) + +func RunStateTest(p string, t *testing.T) { + + tests := make(map[string]VmTest) + CreateFileTests(t, p, &tests) + + for name, test := range tests { + /* + vm.Debug = true + glog.SetV(4) + glog.SetToStderr(true) + if name != "Call50000_sha256" { + continue + } + */ + db, _ := ethdb.NewMemDatabase() + statedb := state.New(common.Hash{}, db) + for addr, account := range test.Pre { + obj := StateObjectFromAccount(db, addr, account) + statedb.SetStateObject(obj) + for a, v := range account.Storage { + obj.SetState(common.HexToHash(a), common.NewValue(common.FromHex(v))) + } + } + + // XXX Yeah, yeah... + env := make(map[string]string) + env["currentCoinbase"] = test.Env.CurrentCoinbase + env["currentDifficulty"] = test.Env.CurrentDifficulty + env["currentGasLimit"] = test.Env.CurrentGasLimit + env["currentNumber"] = test.Env.CurrentNumber + env["previousHash"] = test.Env.PreviousHash + if n, ok := test.Env.CurrentTimestamp.(float64); ok { + env["currentTimestamp"] = strconv.Itoa(int(n)) + } else { + env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) + } + + var ( + ret []byte + // gas *big.Int + // err error + logs state.Logs + ) + + ret, logs, _, _ = RunState(statedb, env, test.Transaction) + + switch name { + // the memory required for these tests (4294967297 bytes) would take too much time. + // on 19 May 2015 decided to skip these tests their output. + case "mload32bitBound_return", "mload32bitBound_return2": + default: + rexp := common.FromHex(test.Out) + if bytes.Compare(rexp, ret) != 0 { + t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) + } + } + + for addr, account := range test.Post { + obj := statedb.GetStateObject(common.HexToAddress(addr)) + if obj == nil { + continue + } + + // if len(test.Exec) == 0 { + if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { + t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) + } + + // if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { + // t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) + // } + + // } + + for addr, value := range account.Storage { + v := obj.GetState(common.HexToHash(addr)).Bytes() + vexp := common.FromHex(value) + + if bytes.Compare(v, vexp) != 0 { + t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) + } + } + } + + statedb.Sync() + //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { + if common.HexToHash(test.PostStateRoot) != statedb.Root() { + t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) + } + + if len(test.Logs) > 0 { + if len(test.Logs) != len(logs) { + t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) + } else { + for i, log := range test.Logs { + if common.HexToAddress(log.AddressF) != logs[i].Address { + t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) + } + + if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { + t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) + } + + if len(log.TopicsF) != len(logs[i].Topics) { + t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) + } else { + for j, topic := range log.TopicsF { + if common.HexToHash(topic) != logs[i].Topics[j] { + t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) + } + } + } + genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) + + if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { + t.Errorf("'%s' bloom mismatch", name) + } + } + } + } + + fmt.Println("State test passed: ", name) + //fmt.Println(string(statedb.Dump())) + } + // logger.Flush() +} + +func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { + var ( + keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) + data = common.FromHex(tx["data"]) + gas = common.Big(tx["gasLimit"]) + price = common.Big(tx["gasPrice"]) + value = common.Big(tx["value"]) + nonce = common.Big(tx["nonce"]).Uint64() + caddr = common.HexToAddress(env["currentCoinbase"]) + ) + + var to *common.Address + if len(tx["to"]) > 2 { + t := common.HexToAddress(tx["to"]) + to = &t + } + // Set pre compiled contracts + vm.Precompiled = vm.PrecompiledContracts() + + snapshot := statedb.Copy() + coinbase := statedb.GetOrNewStateObject(caddr) + coinbase.SetGasPool(common.Big(env["currentGasLimit"])) + + message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce) + vmenv := NewEnvFromMap(statedb, env, tx) + vmenv.origin = common.BytesToAddress(keyPair.Address()) + ret, _, err := core.ApplyMessage(vmenv, message, coinbase) + if core.IsNonceErr(err) || core.IsInvalidTxErr(err) { + statedb.Set(snapshot) + } + statedb.Update() + + return ret, vmenv.state.Logs(), vmenv.Gas, err +} diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 82038c3e8..a6cea972a 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -42,7 +42,7 @@ func RunTransactionTests(file string, notWorking map[string]bool) error { if err = runTest(in); err != nil { return fmt.Errorf("bad test %s: %v", name, err) } - fmt.Println("Test passed:", name) + fmt.Println("Transaction test passed:", name) } } return nil diff --git a/tests/vm.go b/tests/vm.go deleted file mode 100644 index 52e498ccc..000000000 --- a/tests/vm.go +++ /dev/null @@ -1,220 +0,0 @@ -package tests - -import ( - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" -) - -type Env struct { - depth int - state *state.StateDB - skipTransfer bool - initial bool - Gas *big.Int - - origin common.Address - //parent common.Hash - coinbase common.Address - - number *big.Int - time int64 - difficulty *big.Int - gasLimit *big.Int - - vmTest bool - logs []vm.StructLog -} - -func NewEnv(state *state.StateDB) *Env { - return &Env{ - state: state, - } -} - -func (self *Env) StructLogs() []vm.StructLog { - return self.logs -} - -func (self *Env) AddStructLog(log vm.StructLog) { - self.logs = append(self.logs, log) -} - -func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { - env := NewEnv(state) - - env.origin = common.HexToAddress(exeValues["caller"]) - //env.parent = common.Hex2Bytes(envValues["previousHash"]) - env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) - env.number = common.Big(envValues["currentNumber"]) - env.time = common.Big(envValues["currentTimestamp"]).Int64() - env.difficulty = common.Big(envValues["currentDifficulty"]) - env.gasLimit = common.Big(envValues["currentGasLimit"]) - env.Gas = new(big.Int) - - return env -} - -func (self *Env) Origin() common.Address { return self.origin } -func (self *Env) BlockNumber() *big.Int { return self.number } - -//func (self *Env) PrevHash() []byte { return self.parent } -func (self *Env) Coinbase() common.Address { return self.coinbase } -func (self *Env) Time() int64 { return self.time } -func (self *Env) Difficulty() *big.Int { return self.difficulty } -func (self *Env) State() *state.StateDB { return self.state } -func (self *Env) GasLimit() *big.Int { return self.gasLimit } -func (self *Env) VmType() vm.Type { return vm.StdVmTy } -func (self *Env) GetHash(n uint64) common.Hash { - return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) -} -func (self *Env) AddLog(log *state.Log) { - self.state.AddLog(log) -} -func (self *Env) Depth() int { return self.depth } -func (self *Env) SetDepth(i int) { self.depth = i } -func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { - if self.skipTransfer { - // ugly hack - if self.initial { - self.initial = false - return nil - } - - if from.Balance().Cmp(amount) < 0 { - return errors.New("Insufficient balance in account") - } - - return nil - } - return vm.Transfer(from, to, amount) -} - -func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution { - exec := core.NewExecution(self, addr, data, gas, price, value) - - return exec -} - -func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - if self.vmTest && self.depth > 0 { - caller.ReturnGas(gas, price) - - return nil, nil - } - exe := self.vm(&addr, data, gas, price, value) - ret, err := exe.Call(addr, caller) - self.Gas = exe.Gas - - return ret, err - -} -func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - if self.vmTest && self.depth > 0 { - caller.ReturnGas(gas, price) - - return nil, nil - } - - caddr := caller.Address() - exe := self.vm(&caddr, data, gas, price, value) - return exe.Call(addr, caller) -} - -func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { - exe := self.vm(nil, data, gas, price, value) - if self.vmTest { - caller.ReturnGas(gas, price) - - nonce := self.state.GetNonce(caller.Address()) - obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) - - return nil, nil, obj - } else { - return exe.Create(caller) - } -} - -func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) { - var ( - to = common.HexToAddress(exec["address"]) - from = common.HexToAddress(exec["caller"]) - data = common.FromHex(exec["data"]) - gas = common.Big(exec["gas"]) - price = common.Big(exec["gasPrice"]) - value = common.Big(exec["value"]) - ) - // Reset the pre-compiled contracts for VM tests. - vm.Precompiled = make(map[string]*vm.PrecompiledAccount) - - caller := state.GetOrNewStateObject(from) - - vmenv := NewEnvFromMap(state, env, exec) - vmenv.vmTest = true - vmenv.skipTransfer = true - vmenv.initial = true - ret, err := vmenv.Call(caller, to, data, gas, price, value) - - return ret, vmenv.state.Logs(), vmenv.Gas, err -} - -func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { - var ( - keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) - data = common.FromHex(tx["data"]) - gas = common.Big(tx["gasLimit"]) - price = common.Big(tx["gasPrice"]) - value = common.Big(tx["value"]) - nonce = common.Big(tx["nonce"]).Uint64() - caddr = common.HexToAddress(env["currentCoinbase"]) - ) - - var to *common.Address - if len(tx["to"]) > 2 { - t := common.HexToAddress(tx["to"]) - to = &t - } - // Set pre compiled contracts - vm.Precompiled = vm.PrecompiledContracts() - - snapshot := statedb.Copy() - coinbase := statedb.GetOrNewStateObject(caddr) - coinbase.SetGasPool(common.Big(env["currentGasLimit"])) - - message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce) - vmenv := NewEnvFromMap(statedb, env, tx) - vmenv.origin = common.BytesToAddress(keyPair.Address()) - ret, _, err := core.ApplyMessage(vmenv, message, coinbase) - if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) { - statedb.Set(snapshot) - } - statedb.Update() - - return ret, vmenv.state.Logs(), vmenv.Gas, err -} - -type Message struct { - from common.Address - to *common.Address - value, gas, price *big.Int - data []byte - nonce uint64 -} - -func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { - return Message{from, to, value, gas, price, data, nonce} -} - -func (self Message) Hash() []byte { return nil } -func (self Message) From() (common.Address, error) { return self.from, nil } -func (self Message) To() *common.Address { return self.to } -func (self Message) GasPrice() *big.Int { return self.price } -func (self Message) Gas() *big.Int { return self.gas } -func (self Message) Value() *big.Int { return self.value } -func (self Message) Nonce() uint64 { return self.nonce } -func (self Message) Data() []byte { return self.data } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index cf95db80f..3852ba4bf 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -2,15 +2,20 @@ package tests import ( "bytes" + "errors" + "fmt" "math/big" "strconv" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/logger" + // "github.com/ethereum/go-ethereum/logger" ) type Account struct { @@ -118,32 +123,19 @@ func RunVmTest(p string, t *testing.T) { logs state.Logs ) - isVmTest := len(test.Exec) > 0 - if isVmTest { - ret, logs, gas, err = RunVm(statedb, env, test.Exec) + ret, logs, gas, err = RunVm(statedb, env, test.Exec) + + rexp := common.FromHex(test.Out) + if bytes.Compare(rexp, ret) != 0 { + t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) + } + + if len(test.Gas) == 0 && err == nil { + t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) } else { - ret, logs, gas, err = RunState(statedb, env, test.Transaction) - } - - switch name { - // the memory required for these tests (4294967297 bytes) would take too much time. - // on 19 May 2015 decided to skip these tests their output. - case "mload32bitBound_return", "mload32bitBound_return2": - default: - rexp := common.FromHex(test.Out) - if bytes.Compare(rexp, ret) != 0 { - t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) - } - } - - if isVmTest { - if len(test.Gas) == 0 && err == nil { - t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) - } else { - gexp := common.Big(test.Gas) - if gexp.Cmp(gas) != 0 { - t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) - } + gexp := common.Big(test.Gas) + if gexp.Cmp(gas) != 0 { + t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) } } @@ -153,17 +145,6 @@ func RunVmTest(p string, t *testing.T) { continue } - if len(test.Exec) == 0 { - if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { - t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) - } - - if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { - t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) - } - - } - for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)) vexp := common.HexToHash(value) @@ -174,14 +155,6 @@ func RunVmTest(p string, t *testing.T) { } } - if !isVmTest { - statedb.Sync() - //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { - if common.HexToHash(test.PostStateRoot) != statedb.Root() { - t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) - } - } - if len(test.Logs) > 0 { if len(test.Logs) != len(logs) { t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) @@ -212,7 +185,176 @@ func RunVmTest(p string, t *testing.T) { } } } + + fmt.Println("VM test passed: ", name) + //fmt.Println(string(statedb.Dump())) } - logger.Flush() + // logger.Flush() } + +type Env struct { + depth int + state *state.StateDB + skipTransfer bool + initial bool + Gas *big.Int + + origin common.Address + //parent common.Hash + coinbase common.Address + + number *big.Int + time int64 + difficulty *big.Int + gasLimit *big.Int + + logs state.Logs + + vmTest bool +} + +func NewEnv(state *state.StateDB) *Env { + return &Env{ + state: state, + } +} + +func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { + env := NewEnv(state) + + env.origin = common.HexToAddress(exeValues["caller"]) + //env.parent = common.Hex2Bytes(envValues["previousHash"]) + env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) + env.number = common.Big(envValues["currentNumber"]) + env.time = common.Big(envValues["currentTimestamp"]).Int64() + env.difficulty = common.Big(envValues["currentDifficulty"]) + env.gasLimit = common.Big(envValues["currentGasLimit"]) + env.Gas = new(big.Int) + + return env +} + +func (self *Env) Origin() common.Address { return self.origin } +func (self *Env) BlockNumber() *big.Int { return self.number } + +//func (self *Env) PrevHash() []byte { return self.parent } +func (self *Env) Coinbase() common.Address { return self.coinbase } +func (self *Env) Time() int64 { return self.time } +func (self *Env) Difficulty() *big.Int { return self.difficulty } +func (self *Env) State() *state.StateDB { return self.state } +func (self *Env) GasLimit() *big.Int { return self.gasLimit } +func (self *Env) VmType() vm.Type { return vm.StdVmTy } +func (self *Env) GetHash(n uint64) common.Hash { + return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) +} +func (self *Env) AddLog(log *state.Log) { + self.state.AddLog(log) +} +func (self *Env) Depth() int { return self.depth } +func (self *Env) SetDepth(i int) { self.depth = i } +func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { + if self.skipTransfer { + // ugly hack + if self.initial { + self.initial = false + return nil + } + + if from.Balance().Cmp(amount) < 0 { + return errors.New("Insufficient balance in account") + } + + return nil + } + return vm.Transfer(from, to, amount) +} + +func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution { + exec := core.NewExecution(self, addr, data, gas, price, value) + + return exec +} + +func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { + if self.vmTest && self.depth > 0 { + caller.ReturnGas(gas, price) + + return nil, nil + } + exe := self.vm(&addr, data, gas, price, value) + ret, err := exe.Call(addr, caller) + self.Gas = exe.Gas + + return ret, err + +} +func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { + if self.vmTest && self.depth > 0 { + caller.ReturnGas(gas, price) + + return nil, nil + } + + caddr := caller.Address() + exe := self.vm(&caddr, data, gas, price, value) + return exe.Call(addr, caller) +} + +func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { + exe := self.vm(nil, data, gas, price, value) + if self.vmTest { + caller.ReturnGas(gas, price) + + nonce := self.state.GetNonce(caller.Address()) + obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) + + return nil, nil, obj + } else { + return exe.Create(caller) + } +} + +func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) { + var ( + to = common.HexToAddress(exec["address"]) + from = common.HexToAddress(exec["caller"]) + data = common.FromHex(exec["data"]) + gas = common.Big(exec["gas"]) + price = common.Big(exec["gasPrice"]) + value = common.Big(exec["value"]) + ) + // Reset the pre-compiled contracts for VM tests. + vm.Precompiled = make(map[string]*vm.PrecompiledAccount) + + caller := state.GetOrNewStateObject(from) + + vmenv := NewEnvFromMap(state, env, exec) + vmenv.vmTest = true + vmenv.skipTransfer = true + vmenv.initial = true + ret, err := vmenv.Call(caller, to, data, gas, price, value) + + return ret, vmenv.state.Logs(), vmenv.Gas, err +} + +type Message struct { + from common.Address + to *common.Address + value, gas, price *big.Int + data []byte + nonce uint64 +} + +func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { + return Message{from, to, value, gas, price, data, nonce} +} + +func (self Message) Hash() []byte { return nil } +func (self Message) From() (common.Address, error) { return self.from, nil } +func (self Message) To() *common.Address { return self.to } +func (self Message) GasPrice() *big.Int { return self.price } +func (self Message) Gas() *big.Int { return self.gas } +func (self Message) Value() *big.Int { return self.value } +func (self Message) Nonce() uint64 { return self.nonce } +func (self Message) Data() []byte { return self.data } From 24554629b162d20a1f945386a45e3221c58adc2b Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 15:02:16 -0400 Subject: [PATCH 055/110] DRY log check --- tests/state_test_util.go | 74 ++++++++++++++++++++++------------------ tests/vm_test_util.go | 35 ++++--------------- 2 files changed, 47 insertions(+), 62 deletions(-) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 1f481147e..91a8367e7 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -75,22 +75,20 @@ func RunStateTest(p string, t *testing.T) { } } + // check post state for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { continue } - // if len(test.Exec) == 0 { if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) } - // if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { - // t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) - // } - - // } + if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { + t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) + } for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)).Bytes() @@ -108,34 +106,11 @@ func RunStateTest(p string, t *testing.T) { t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) } + // check logs if len(test.Logs) > 0 { - if len(test.Logs) != len(logs) { - t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) - } else { - for i, log := range test.Logs { - if common.HexToAddress(log.AddressF) != logs[i].Address { - t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) - } - - if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { - t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) - } - - if len(log.TopicsF) != len(logs[i].Topics) { - t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) - } else { - for j, topic := range log.TopicsF { - if common.HexToHash(topic) != logs[i].Topics[j] { - t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) - } - } - } - genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) - - if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { - t.Errorf("'%s' bloom mismatch", name) - } - } + lerr := CheckLogs(test.Logs, logs, t) + if lerr != nil { + t.Errorf("'%s' ", name, lerr.Error()) } } @@ -145,6 +120,39 @@ func RunStateTest(p string, t *testing.T) { // logger.Flush() } +func CheckLogs(tlog []Log, logs state.Logs, t *testing.T) error { + + if len(tlog) != len(logs) { + return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) + } else { + for i, log := range tlog { + if common.HexToAddress(log.AddressF) != logs[i].Address { + return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) + } + + if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { + return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) + } + + if len(log.TopicsF) != len(logs[i].Topics) { + return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) + } else { + for j, topic := range log.TopicsF { + if common.HexToHash(topic) != logs[i].Topics[j] { + return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) + } + } + } + genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) + + if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { + return fmt.Errorf("bloom mismatch") + } + } + } + return nil +} + func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { var ( keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 3852ba4bf..6743a0872 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" + // "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" @@ -125,11 +125,13 @@ func RunVmTest(p string, t *testing.T) { ret, logs, gas, err = RunVm(statedb, env, test.Exec) + // Compare expectedand actual return rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } + // Check gas usage if len(test.Gas) == 0 && err == nil { t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) } else { @@ -139,6 +141,7 @@ func RunVmTest(p string, t *testing.T) { } } + // check post state for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { @@ -155,35 +158,9 @@ func RunVmTest(p string, t *testing.T) { } } + // check logs if len(test.Logs) > 0 { - if len(test.Logs) != len(logs) { - t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) - } else { - for i, log := range test.Logs { - if common.HexToAddress(log.AddressF) != logs[i].Address { - t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) - } - - if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { - t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) - } - - if len(log.TopicsF) != len(logs[i].Topics) { - t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) - } else { - for j, topic := range log.TopicsF { - if common.HexToHash(topic) != logs[i].Topics[j] { - t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) - } - } - } - genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) - - if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { - t.Errorf("'%s' bloom mismatch", name) - } - } - } + CheckLogs(test.Logs, logs, t) } fmt.Println("VM test passed: ", name) From c5d6fcbaba545d1078f5411dc67208d5d388222e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 16:10:33 -0400 Subject: [PATCH 056/110] Return error up stack instead of passing testing var down --- tests/block_test.go | 22 ++++++------- tests/block_test_util.go | 23 ++++++++------ tests/init.go | 33 +++++++++++-------- tests/state_test.go | 68 ++++++++++++++++++++++++++++++---------- tests/state_test_util.go | 23 +++++++------- tests/vm_test.go | 56 ++++++++++++++++++++++++--------- tests/vm_test_util.go | 18 ++++++----- 7 files changed, 159 insertions(+), 84 deletions(-) diff --git a/tests/block_test.go b/tests/block_test.go index 1f2e5a15b..33d4caec6 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -10,40 +10,38 @@ var blockTestDir = filepath.Join(baseDir, "BlockTests") // TODO: refactor test setup & execution to better align with vm and tx tests func TestBcValidBlockTests(t *testing.T) { - // SimpleTx3 genesis block does not validate against calculated state root - // as of 2015-06-09. unskip once working /Gustav - runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}) } func TestBcUncleTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleTest.json"), []string{}, t) - runBlockTestsInFile(filepath.Join(blockTestDir, "bcBruncleTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleTest.json"), []string{}) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcBruncleTest.json"), []string{}) } func TestBcUncleHeaderValidityTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), []string{}) } func TestBcInvalidHeaderTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), []string{}) } func TestBcInvalidRLPTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), []string{}) } func TestBcRPCAPITests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcRPC_API_Test.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcRPC_API_Test.json"), []string{}) } func TestBcForkBlockTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcForkBlockTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcForkBlockTest.json"), []string{}) } func TestBcTotalDifficulty(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), []string{}) } func TestBcWallet(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcWalletTest.json"), []string{}, t) + runBlockTestsInFile(filepath.Join(blockTestDir, "bcWalletTest.json"), []string{}) } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index e60607c0f..ec532d178 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -11,7 +11,6 @@ import ( "runtime" "strconv" "strings" - "testing" "time" "github.com/ethereum/go-ethereum/accounts" @@ -87,10 +86,10 @@ type btTransaction struct { Value string } -func runBlockTestsInFile(filepath string, snafus []string, t *testing.T) { +func runBlockTestsInFile(filepath string, snafus []string) error { bt, err := LoadBlockTests(filepath) if err != nil { - t.Fatal(err) + return nil } notWorking := make(map[string]bool, 100) @@ -100,21 +99,24 @@ func runBlockTestsInFile(filepath string, snafus []string, t *testing.T) { for name, test := range bt { if !notWorking[name] { - runBlockTest(name, test, t) + if err := runBlockTest(name, test); err != nil { + return err + } } } + return nil } -func runBlockTest(name string, test *BlockTest, t *testing.T) { +func runBlockTest(name string, test *BlockTest) error { cfg := testEthConfig() ethereum, err := eth.New(cfg) if err != nil { - t.Fatalf("%v", err) + return err } err = ethereum.Start() if err != nil { - t.Fatalf("%v", err) + return err } // import the genesis block @@ -123,19 +125,20 @@ func runBlockTest(name string, test *BlockTest, t *testing.T) { // import pre accounts statedb, err := test.InsertPreState(ethereum) if err != nil { - t.Fatalf("InsertPreState: %v", err) + return fmt.Errorf("InsertPreState: %v", err) } err = test.TryBlocksInsert(ethereum.ChainManager()) if err != nil { - t.Fatal(err) + return err } if err = test.ValidatePostState(statedb); err != nil { - t.Fatal("post state validation failed: %v", err) + return fmt.Errorf("post state validation failed: %v", err) } fmt.Println("Block test passed: ", name) // t.Log("Block test passed: ", name) + return nil } func testEthConfig() *eth.Config { diff --git a/tests/init.go b/tests/init.go index b487f81c3..4a176698f 100644 --- a/tests/init.go +++ b/tests/init.go @@ -1,13 +1,14 @@ package tests import ( + "bytes" "encoding/json" + "fmt" "io" "io/ioutil" // "log" "net/http" "os" - "testing" // logpkg "github.com/ethereum/go-ethereum/logger" ) @@ -20,34 +21,40 @@ import ( // logpkg.AddLogSystem(Logger) // } -func readJSON(t *testing.T, reader io.Reader, value interface{}) { +func readJSON(reader io.Reader, value interface{}) error { data, err := ioutil.ReadAll(reader) err = json.Unmarshal(data, &value) if err != nil { - t.Error(err) + return err } + return nil } -func CreateHttpTests(t *testing.T, uri string, value interface{}) { +func CreateHttpTests(uri string, value interface{}) error { resp, err := http.Get(uri) if err != nil { - t.Error(err) - - return + return err } defer resp.Body.Close() - readJSON(t, resp.Body, value) + err = readJSON(resp.Body, value) + if err != nil { + return err + } + return nil } -func CreateFileTests(t *testing.T, fn string, value interface{}) { +func CreateFileTests(fn string, value interface{}) error { file, err := os.Open(fn) if err != nil { - t.Error(err) - - return + return err } defer file.Close() - readJSON(t, file, value) + err = readJSON(file, value) + if err != nil { + return err + } + return nil +} } diff --git a/tests/state_test.go b/tests/state_test.go index dbef7bd0c..5c16a3e91 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -10,62 +10,86 @@ var stateTestDir = filepath.Join(baseDir, "StateTests") func TestStateSystemOperations(t *testing.T) { fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateExample(t *testing.T) { fn := filepath.Join(stateTestDir, "stExample.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStatePreCompiledContracts(t *testing.T) { fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateRecursiveCreate(t *testing.T) { fn := filepath.Join(stateTestDir, "stRecursiveCreate.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateSpecial(t *testing.T) { fn := filepath.Join(stateTestDir, "stSpecialTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateRefund(t *testing.T) { fn := filepath.Join(stateTestDir, "stRefundTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateBlockHash(t *testing.T) { fn := filepath.Join(stateTestDir, "stBlockHashTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateInitCode(t *testing.T) { fn := filepath.Join(stateTestDir, "stInitCodeTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateLog(t *testing.T) { fn := filepath.Join(stateTestDir, "stLogTests.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateTransaction(t *testing.T) { fn := filepath.Join(stateTestDir, "stTransactionTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestCallCreateCallCode(t *testing.T) { fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestMemory(t *testing.T) { fn := filepath.Join(stateTestDir, "stMemoryTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestMemoryStress(t *testing.T) { @@ -73,7 +97,9 @@ func TestMemoryStress(t *testing.T) { t.Skip() } fn := filepath.Join(stateTestDir, "stMemoryStressTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestQuadraticComplexity(t *testing.T) { @@ -81,22 +107,30 @@ func TestQuadraticComplexity(t *testing.T) { t.Skip() } fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestSolidity(t *testing.T) { fn := filepath.Join(stateTestDir, "stSolidityTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestWallet(t *testing.T) { fn := filepath.Join(stateTestDir, "stWalletTest.json") - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } func TestStateTestsRandom(t *testing.T) { fns, _ := filepath.Glob("./files/StateTests/RandomTests/*") for _, fn := range fns { - RunStateTest(fn, t) + if err := RunStateTest(fn); err != nil { + t.Error(err) + } } } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 91a8367e7..de4af6d82 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -6,22 +6,22 @@ import ( "fmt" "math/big" "strconv" - "testing" + // "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" + // "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" // "github.com/ethereum/go-ethereum/logger" ) -func RunStateTest(p string, t *testing.T) { +func RunStateTest(p string) error { tests := make(map[string]VmTest) - CreateFileTests(t, p, &tests) + CreateFileTests(p, &tests) for name, test := range tests { /* @@ -38,7 +38,7 @@ func RunStateTest(p string, t *testing.T) { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) for a, v := range account.Storage { - obj.SetState(common.HexToHash(a), common.NewValue(common.FromHex(v))) + obj.SetState(common.HexToHash(a), common.HexToHash(s)) } } @@ -64,6 +64,7 @@ func RunStateTest(p string, t *testing.T) { ret, logs, _, _ = RunState(statedb, env, test.Transaction) + // Compare expected and actual return switch name { // the memory required for these tests (4294967297 bytes) would take too much time. // on 19 May 2015 decided to skip these tests their output. @@ -71,7 +72,7 @@ func RunStateTest(p string, t *testing.T) { default: rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { - t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) + return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } } @@ -83,11 +84,11 @@ func RunStateTest(p string, t *testing.T) { } if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { - t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) + return fmt.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) } if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { - t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) + return fmt.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) } for addr, value := range account.Storage { @@ -95,7 +96,7 @@ func RunStateTest(p string, t *testing.T) { vexp := common.FromHex(value) if bytes.Compare(v, vexp) != 0 { - t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) + return fmt.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) } } } @@ -103,14 +104,14 @@ func RunStateTest(p string, t *testing.T) { statedb.Sync() //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { if common.HexToHash(test.PostStateRoot) != statedb.Root() { - t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) + return fmt.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) } // check logs if len(test.Logs) > 0 { lerr := CheckLogs(test.Logs, logs, t) if lerr != nil { - t.Errorf("'%s' ", name, lerr.Error()) + return fmt.Errorf("'%s' ", name, lerr.Error()) } } diff --git a/tests/vm_test.go b/tests/vm_test.go index faa3205bc..194e7b6fa 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -10,72 +10,100 @@ var vmTestDir = filepath.Join(baseDir, "VMTests") // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. func TestVMArithmetic(t *testing.T) { fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestBitwiseLogicOperation(t *testing.T) { fn := filepath.Join(vmTestDir, "vmBitwiseLogicOperationTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestBlockInfo(t *testing.T) { fn := filepath.Join(vmTestDir, "vmBlockInfoTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestEnvironmentalInfo(t *testing.T) { fn := filepath.Join(vmTestDir, "vmEnvironmentalInfoTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestFlowOperation(t *testing.T) { fn := filepath.Join(vmTestDir, "vmIOandFlowOperationsTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestLogTest(t *testing.T) { fn := filepath.Join(vmTestDir, "vmLogTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestPerformance(t *testing.T) { fn := filepath.Join(vmTestDir, "vmPerformanceTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestPushDupSwap(t *testing.T) { fn := filepath.Join(vmTestDir, "vmPushDupSwapTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestVMSha3(t *testing.T) { fn := filepath.Join(vmTestDir, "vmSha3Test.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestVm(t *testing.T) { fn := filepath.Join(vmTestDir, "vmtests.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestVmLog(t *testing.T) { fn := filepath.Join(vmTestDir, "vmLogTest.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestInputLimits(t *testing.T) { fn := filepath.Join(vmTestDir, "vmInputLimits.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestInputLimitsLight(t *testing.T) { fn := filepath.Join(vmTestDir, "vmInputLimitsLight.json") - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } func TestVMRandom(t *testing.T) { fns, _ := filepath.Glob(filepath.Join(baseDir, "RandomTests", "*")) for _, fn := range fns { - RunVmTest(fn, t) + if err := RunVmTest(fn); err != nil { + t.Error(err) + } } } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 6743a0872..5d9635afd 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -6,7 +6,7 @@ import ( "fmt" "math/big" "strconv" - "testing" + // "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -79,10 +79,13 @@ type VmTest struct { PostStateRoot string } -func RunVmTest(p string, t *testing.T) { +func RunVmTest(p string) error { tests := make(map[string]VmTest) - CreateFileTests(t, p, &tests) + err := CreateFileTests(p, &tests) + if err != nil { + return err + } for name, test := range tests { /* @@ -128,16 +131,16 @@ func RunVmTest(p string, t *testing.T) { // Compare expectedand actual return rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { - t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) + return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } // Check gas usage if len(test.Gas) == 0 && err == nil { - t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) + return fmt.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) } else { gexp := common.Big(test.Gas) if gexp.Cmp(gas) != 0 { - t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) + return fmt.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) } } @@ -153,7 +156,7 @@ func RunVmTest(p string, t *testing.T) { vexp := common.HexToHash(value) if v != vexp { - t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) + return t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) } } } @@ -168,6 +171,7 @@ func RunVmTest(p string, t *testing.T) { //fmt.Println(string(statedb.Dump())) } // logger.Flush() + return nil } type Env struct { From b6d40a931286b4c998f58ad074db0a692aeace6e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 16:29:42 -0400 Subject: [PATCH 057/110] Cleanup/reorg --- tests/block_test.go | 4 - tests/init.go | 21 ++-- tests/state_test.go | 2 - tests/state_test_util.go | 39 +----- tests/transaction_test.go | 2 - tests/util.go | 252 ++++++++++++++++++++++++++++++++++++++ tests/vm_test.go | 2 - tests/vm_test_util.go | 216 +------------------------------- 8 files changed, 265 insertions(+), 273 deletions(-) create mode 100644 tests/util.go diff --git a/tests/block_test.go b/tests/block_test.go index 33d4caec6..f1a92be49 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -5,10 +5,6 @@ import ( "testing" ) -var baseDir = filepath.Join(".", "files") -var blockTestDir = filepath.Join(baseDir, "BlockTests") - -// TODO: refactor test setup & execution to better align with vm and tx tests func TestBcValidBlockTests(t *testing.T) { runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}) } diff --git a/tests/init.go b/tests/init.go index 4a176698f..e6644ae60 100644 --- a/tests/init.go +++ b/tests/init.go @@ -1,25 +1,21 @@ package tests import ( - "bytes" "encoding/json" - "fmt" "io" "io/ioutil" - // "log" "net/http" "os" - - // logpkg "github.com/ethereum/go-ethereum/logger" + "path/filepath" ) -// var Logger *logpkg.StdLogSystem -// var Log = logpkg.NewLogger("TEST") - -// func init() { -// Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel) -// logpkg.AddLogSystem(Logger) -// } +var ( + baseDir = filepath.Join(".", "files") + blockTestDir = filepath.Join(baseDir, "BlockTests") + stateTestDir = filepath.Join(baseDir, "StateTests") + transactionTestDir = filepath.Join(baseDir, "TransactionTests") + vmTestDir = filepath.Join(baseDir, "VMTests") +) func readJSON(reader io.Reader, value interface{}) error { data, err := ioutil.ReadAll(reader) @@ -57,4 +53,3 @@ func CreateFileTests(fn string, value interface{}) error { } return nil } -} diff --git a/tests/state_test.go b/tests/state_test.go index 5c16a3e91..9c3d6f209 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -6,8 +6,6 @@ import ( "testing" ) -var stateTestDir = filepath.Join(baseDir, "StateTests") - func TestStateSystemOperations(t *testing.T) { fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") if err := RunStateTest(fn); err != nil { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index de4af6d82..29d7cebe8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -2,20 +2,16 @@ package tests import ( "bytes" - // "errors" "fmt" "math/big" "strconv" - // "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - // "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" - // "github.com/ethereum/go-ethereum/logger" ) func RunStateTest(p string) error { @@ -109,7 +105,7 @@ func RunStateTest(p string) error { // check logs if len(test.Logs) > 0 { - lerr := CheckLogs(test.Logs, logs, t) + lerr := checkLogs(test.Logs, logs) if lerr != nil { return fmt.Errorf("'%s' ", name, lerr.Error()) } @@ -118,39 +114,6 @@ func RunStateTest(p string) error { fmt.Println("State test passed: ", name) //fmt.Println(string(statedb.Dump())) } - // logger.Flush() -} - -func CheckLogs(tlog []Log, logs state.Logs, t *testing.T) error { - - if len(tlog) != len(logs) { - return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) - } else { - for i, log := range tlog { - if common.HexToAddress(log.AddressF) != logs[i].Address { - return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) - } - - if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { - return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) - } - - if len(log.TopicsF) != len(logs[i].Topics) { - return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) - } else { - for j, topic := range log.TopicsF { - if common.HexToHash(topic) != logs[i].Topics[j] { - return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) - } - } - } - genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) - - if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { - return fmt.Errorf("bloom mismatch") - } - } - } return nil } diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 05942d3bf..e1237dee2 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -5,8 +5,6 @@ import ( "testing" ) -var transactionTestDir = filepath.Join(baseDir, "TransactionTests") - func TestTransactions(t *testing.T) { notWorking := make(map[string]bool, 100) diff --git a/tests/util.go b/tests/util.go new file mode 100644 index 000000000..6554c4b94 --- /dev/null +++ b/tests/util.go @@ -0,0 +1,252 @@ +package tests + +import ( + "bytes" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" +) + +func checkLogs(tlog []Log, logs state.Logs) error { + + if len(tlog) != len(logs) { + return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) + } else { + for i, log := range tlog { + if common.HexToAddress(log.AddressF) != logs[i].Address { + return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) + } + + if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { + return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) + } + + if len(log.TopicsF) != len(logs[i].Topics) { + return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) + } else { + for j, topic := range log.TopicsF { + if common.HexToHash(topic) != logs[i].Topics[j] { + return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) + } + } + } + genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) + + if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { + return fmt.Errorf("bloom mismatch") + } + } + } + return nil +} + +type Account struct { + Balance string + Code string + Nonce string + Storage map[string]string +} + +type Log struct { + AddressF string `json:"address"` + DataF string `json:"data"` + TopicsF []string `json:"topics"` + BloomF string `json:"bloom"` +} + +func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } +func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } +func (self Log) RlpData() interface{} { return nil } +func (self Log) Topics() [][]byte { + t := make([][]byte, len(self.TopicsF)) + for i, topic := range self.TopicsF { + t[i] = common.Hex2Bytes(topic) + } + return t +} + +func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { + obj := state.NewStateObject(common.HexToAddress(addr), db) + obj.SetBalance(common.Big(account.Balance)) + + if common.IsHex(account.Code) { + account.Code = account.Code[2:] + } + obj.SetCode(common.Hex2Bytes(account.Code)) + obj.SetNonce(common.Big(account.Nonce).Uint64()) + + return obj +} + +type VmEnv struct { + CurrentCoinbase string + CurrentDifficulty string + CurrentGasLimit string + CurrentNumber string + CurrentTimestamp interface{} + PreviousHash string +} + +type VmTest struct { + Callcreates interface{} + //Env map[string]string + Env VmEnv + Exec map[string]string + Transaction map[string]string + Logs []Log + Gas string + Out string + Post map[string]Account + Pre map[string]Account + PostStateRoot string +} + +type Env struct { + depth int + state *state.StateDB + skipTransfer bool + initial bool + Gas *big.Int + + origin common.Address + //parent common.Hash + coinbase common.Address + + number *big.Int + time int64 + difficulty *big.Int + gasLimit *big.Int + + logs state.Logs + + vmTest bool +} + +func NewEnv(state *state.StateDB) *Env { + return &Env{ + state: state, + } +} + +func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { + env := NewEnv(state) + + env.origin = common.HexToAddress(exeValues["caller"]) + //env.parent = common.Hex2Bytes(envValues["previousHash"]) + env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) + env.number = common.Big(envValues["currentNumber"]) + env.time = common.Big(envValues["currentTimestamp"]).Int64() + env.difficulty = common.Big(envValues["currentDifficulty"]) + env.gasLimit = common.Big(envValues["currentGasLimit"]) + env.Gas = new(big.Int) + + return env +} + +func (self *Env) Origin() common.Address { return self.origin } +func (self *Env) BlockNumber() *big.Int { return self.number } + +//func (self *Env) PrevHash() []byte { return self.parent } +func (self *Env) Coinbase() common.Address { return self.coinbase } +func (self *Env) Time() int64 { return self.time } +func (self *Env) Difficulty() *big.Int { return self.difficulty } +func (self *Env) State() *state.StateDB { return self.state } +func (self *Env) GasLimit() *big.Int { return self.gasLimit } +func (self *Env) VmType() vm.Type { return vm.StdVmTy } +func (self *Env) GetHash(n uint64) common.Hash { + return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) +} +func (self *Env) AddLog(log *state.Log) { + self.state.AddLog(log) +} +func (self *Env) Depth() int { return self.depth } +func (self *Env) SetDepth(i int) { self.depth = i } +func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { + if self.skipTransfer { + // ugly hack + if self.initial { + self.initial = false + return nil + } + + if from.Balance().Cmp(amount) < 0 { + return errors.New("Insufficient balance in account") + } + + return nil + } + return vm.Transfer(from, to, amount) +} + +func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution { + exec := core.NewExecution(self, addr, data, gas, price, value) + + return exec +} + +func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { + if self.vmTest && self.depth > 0 { + caller.ReturnGas(gas, price) + + return nil, nil + } + exe := self.vm(&addr, data, gas, price, value) + ret, err := exe.Call(addr, caller) + self.Gas = exe.Gas + + return ret, err + +} +func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { + if self.vmTest && self.depth > 0 { + caller.ReturnGas(gas, price) + + return nil, nil + } + + caddr := caller.Address() + exe := self.vm(&caddr, data, gas, price, value) + return exe.Call(addr, caller) +} + +func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { + exe := self.vm(nil, data, gas, price, value) + if self.vmTest { + caller.ReturnGas(gas, price) + + nonce := self.state.GetNonce(caller.Address()) + obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) + + return nil, nil, obj + } else { + return exe.Create(caller) + } +} + +type Message struct { + from common.Address + to *common.Address + value, gas, price *big.Int + data []byte + nonce uint64 +} + +func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { + return Message{from, to, value, gas, price, data, nonce} +} + +func (self Message) Hash() []byte { return nil } +func (self Message) From() (common.Address, error) { return self.from, nil } +func (self Message) To() *common.Address { return self.to } +func (self Message) GasPrice() *big.Int { return self.price } +func (self Message) Gas() *big.Int { return self.gas } +func (self Message) Value() *big.Int { return self.value } +func (self Message) Nonce() uint64 { return self.nonce } +func (self Message) Data() []byte { return self.data } diff --git a/tests/vm_test.go b/tests/vm_test.go index 194e7b6fa..d16d65aac 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -5,8 +5,6 @@ import ( "testing" ) -var vmTestDir = filepath.Join(baseDir, "VMTests") - // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. func TestVMArithmetic(t *testing.T) { fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 5d9635afd..066217620 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -2,83 +2,16 @@ package tests import ( "bytes" - "errors" "fmt" "math/big" "strconv" - // "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - // "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" - // "github.com/ethereum/go-ethereum/logger" ) -type Account struct { - Balance string - Code string - Nonce string - Storage map[string]string -} - -type Log struct { - AddressF string `json:"address"` - DataF string `json:"data"` - TopicsF []string `json:"topics"` - BloomF string `json:"bloom"` -} - -func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } -func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } -func (self Log) RlpData() interface{} { return nil } -func (self Log) Topics() [][]byte { - t := make([][]byte, len(self.TopicsF)) - for i, topic := range self.TopicsF { - t[i] = common.Hex2Bytes(topic) - } - return t -} - -func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { - obj := state.NewStateObject(common.HexToAddress(addr), db) - obj.SetBalance(common.Big(account.Balance)) - - if common.IsHex(account.Code) { - account.Code = account.Code[2:] - } - obj.SetCode(common.Hex2Bytes(account.Code)) - obj.SetNonce(common.Big(account.Nonce).Uint64()) - - return obj -} - -type VmEnv struct { - CurrentCoinbase string - CurrentDifficulty string - CurrentGasLimit string - CurrentNumber string - CurrentTimestamp interface{} - PreviousHash string -} - -type VmTest struct { - Callcreates interface{} - //Env map[string]string - Env VmEnv - Exec map[string]string - Transaction map[string]string - Logs []Log - Gas string - Out string - Post map[string]Account - Pre map[string]Account - PostStateRoot string -} - func RunVmTest(p string) error { tests := make(map[string]VmTest) @@ -163,139 +96,19 @@ func RunVmTest(p string) error { // check logs if len(test.Logs) > 0 { - CheckLogs(test.Logs, logs, t) + lerr := checkLogs(test.Logs, logs) + if lerr != nil { + return fmt.Errorf("'%s' ", name, lerr.Error()) + } } fmt.Println("VM test passed: ", name) //fmt.Println(string(statedb.Dump())) } - // logger.Flush() return nil } -type Env struct { - depth int - state *state.StateDB - skipTransfer bool - initial bool - Gas *big.Int - - origin common.Address - //parent common.Hash - coinbase common.Address - - number *big.Int - time int64 - difficulty *big.Int - gasLimit *big.Int - - logs state.Logs - - vmTest bool -} - -func NewEnv(state *state.StateDB) *Env { - return &Env{ - state: state, - } -} - -func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { - env := NewEnv(state) - - env.origin = common.HexToAddress(exeValues["caller"]) - //env.parent = common.Hex2Bytes(envValues["previousHash"]) - env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) - env.number = common.Big(envValues["currentNumber"]) - env.time = common.Big(envValues["currentTimestamp"]).Int64() - env.difficulty = common.Big(envValues["currentDifficulty"]) - env.gasLimit = common.Big(envValues["currentGasLimit"]) - env.Gas = new(big.Int) - - return env -} - -func (self *Env) Origin() common.Address { return self.origin } -func (self *Env) BlockNumber() *big.Int { return self.number } - -//func (self *Env) PrevHash() []byte { return self.parent } -func (self *Env) Coinbase() common.Address { return self.coinbase } -func (self *Env) Time() int64 { return self.time } -func (self *Env) Difficulty() *big.Int { return self.difficulty } -func (self *Env) State() *state.StateDB { return self.state } -func (self *Env) GasLimit() *big.Int { return self.gasLimit } -func (self *Env) VmType() vm.Type { return vm.StdVmTy } -func (self *Env) GetHash(n uint64) common.Hash { - return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) -} -func (self *Env) AddLog(log *state.Log) { - self.state.AddLog(log) -} -func (self *Env) Depth() int { return self.depth } -func (self *Env) SetDepth(i int) { self.depth = i } -func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { - if self.skipTransfer { - // ugly hack - if self.initial { - self.initial = false - return nil - } - - if from.Balance().Cmp(amount) < 0 { - return errors.New("Insufficient balance in account") - } - - return nil - } - return vm.Transfer(from, to, amount) -} - -func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution { - exec := core.NewExecution(self, addr, data, gas, price, value) - - return exec -} - -func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - if self.vmTest && self.depth > 0 { - caller.ReturnGas(gas, price) - - return nil, nil - } - exe := self.vm(&addr, data, gas, price, value) - ret, err := exe.Call(addr, caller) - self.Gas = exe.Gas - - return ret, err - -} -func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - if self.vmTest && self.depth > 0 { - caller.ReturnGas(gas, price) - - return nil, nil - } - - caddr := caller.Address() - exe := self.vm(&caddr, data, gas, price, value) - return exe.Call(addr, caller) -} - -func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { - exe := self.vm(nil, data, gas, price, value) - if self.vmTest { - caller.ReturnGas(gas, price) - - nonce := self.state.GetNonce(caller.Address()) - obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) - - return nil, nil, obj - } else { - return exe.Create(caller) - } -} - func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) { var ( to = common.HexToAddress(exec["address"]) @@ -318,24 +131,3 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Log return ret, vmenv.state.Logs(), vmenv.Gas, err } - -type Message struct { - from common.Address - to *common.Address - value, gas, price *big.Int - data []byte - nonce uint64 -} - -func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { - return Message{from, to, value, gas, price, data, nonce} -} - -func (self Message) Hash() []byte { return nil } -func (self Message) From() (common.Address, error) { return self.from, nil } -func (self Message) To() *common.Address { return self.to } -func (self Message) GasPrice() *big.Int { return self.price } -func (self Message) Gas() *big.Int { return self.gas } -func (self Message) Value() *big.Int { return self.value } -func (self Message) Nonce() uint64 { return self.nonce } -func (self Message) Data() []byte { return self.data } From ac0637c41332de1f49fb0955f4fbe0fb908a77d5 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 17:04:06 -0400 Subject: [PATCH 058/110] More consistent test interfaces + test skipping --- tests/block_test.go | 50 +++++++++++++++++++++++++++------- tests/block_test_util.go | 27 ++++++++++-------- tests/init.go | 5 ++++ tests/state_test_util.go | 36 ++++++++++++------------ tests/transaction_test.go | 25 ++--------------- tests/transaction_test_util.go | 27 ++++++++++++------ tests/vm_test_util.go | 16 +++++------ 7 files changed, 108 insertions(+), 78 deletions(-) diff --git a/tests/block_test.go b/tests/block_test.go index f1a92be49..9d21ba28d 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -6,38 +6,68 @@ import ( ) func TestBcValidBlockTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcValidBlockTest.json")) + if err != nil { + t.Fatal(err) + } } func TestBcUncleTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleTest.json"), []string{}) - runBlockTestsInFile(filepath.Join(blockTestDir, "bcBruncleTest.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleTest.json")) + if err != nil { + t.Fatal(err) + } + err = RunBlockTest(filepath.Join(blockTestDir, "bcBruncleTest.json")) + if err != nil { + t.Fatal(err) + } } func TestBcUncleHeaderValidityTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json")) + if err != nil { + t.Fatal(err) + } } func TestBcInvalidHeaderTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json")) + if err != nil { + t.Fatal(err) + } } func TestBcInvalidRLPTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidRLPTest.json")) + if err != nil { + t.Fatal(err) + } } func TestBcRPCAPITests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcRPC_API_Test.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcRPC_API_Test.json")) + if err != nil { + t.Fatal(err) + } } func TestBcForkBlockTests(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcForkBlockTest.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcForkBlockTest.json")) + if err != nil { + t.Fatal(err) + } } func TestBcTotalDifficulty(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json")) + if err != nil { + t.Fatal(err) + } } func TestBcWallet(t *testing.T) { - runBlockTestsInFile(filepath.Join(blockTestDir, "bcWalletTest.json"), []string{}) + err := RunBlockTest(filepath.Join(blockTestDir, "bcWalletTest.json")) + if err != nil { + t.Fatal(err) + } } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index ec532d178..a04019111 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -86,28 +86,35 @@ type btTransaction struct { Value string } -func runBlockTestsInFile(filepath string, snafus []string) error { +func RunBlockTest(filepath string) error { bt, err := LoadBlockTests(filepath) if err != nil { return nil } - notWorking := make(map[string]bool, 100) - for _, name := range snafus { - notWorking[name] = true + // map skipped tests to boolean set + skipTest := make(map[string]bool, len(blockSkipTests)) + for _, name := range blockSkipTests { + skipTest[name] = true } for name, test := range bt { - if !notWorking[name] { - if err := runBlockTest(name, test); err != nil { - return err - } + // if the test should be skipped, return + if skipTest[name] { + fmt.Println("Skipping state test", name) + return nil } + // test the block + if err := testBlock(test); err != nil { + return err + } + fmt.Println("Block test passed: ", name) + } return nil } -func runBlockTest(name string, test *BlockTest) error { +func testBlock(test *BlockTest) error { cfg := testEthConfig() ethereum, err := eth.New(cfg) if err != nil { @@ -136,8 +143,6 @@ func runBlockTest(name string, test *BlockTest) error { if err = test.ValidatePostState(statedb); err != nil { return fmt.Errorf("post state validation failed: %v", err) } - fmt.Println("Block test passed: ", name) - // t.Log("Block test passed: ", name) return nil } diff --git a/tests/init.go b/tests/init.go index e6644ae60..74d9499f1 100644 --- a/tests/init.go +++ b/tests/init.go @@ -15,6 +15,11 @@ var ( stateTestDir = filepath.Join(baseDir, "StateTests") transactionTestDir = filepath.Join(baseDir, "TransactionTests") vmTestDir = filepath.Join(baseDir, "VMTests") + + blockSkipTests = []string{} + transSkipTests = []string{"TransactionWithHihghNonce256"} + stateSkipTests = []string{"mload32bitBound_return", "mload32bitBound_return2"} + vmSkipTests = []string{} ) func readJSON(reader io.Reader, value interface{}) error { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 29d7cebe8..b507de47f 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -15,19 +15,19 @@ import ( ) func RunStateTest(p string) error { + skipTest := make(map[string]bool, len(stateSkipTests)) + for _, name := range stateSkipTests { + skipTest[name] = true + } tests := make(map[string]VmTest) CreateFileTests(p, &tests) for name, test := range tests { - /* - vm.Debug = true - glog.SetV(4) - glog.SetToStderr(true) - if name != "Call50000_sha256" { - continue - } - */ + if skipTest[name] { + fmt.Println("Skipping state test", name) + return nil + } db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) for addr, account := range test.Pre { @@ -60,17 +60,17 @@ func RunStateTest(p string) error { ret, logs, _, _ = RunState(statedb, env, test.Transaction) - // Compare expected and actual return - switch name { - // the memory required for these tests (4294967297 bytes) would take too much time. - // on 19 May 2015 decided to skip these tests their output. - case "mload32bitBound_return", "mload32bitBound_return2": - default: - rexp := common.FromHex(test.Out) - if bytes.Compare(rexp, ret) != 0 { - return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) - } + // // Compare expected and actual return + // switch name { + // // the memory required for these tests (4294967297 bytes) would take too much time. + // // on 19 May 2015 decided to skip these tests their output. + // case "mload32bitBound_return", "mload32bitBound_return2": + // default: + rexp := common.FromHex(test.Out) + if bytes.Compare(rexp, ret) != 0 { + return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } + // } // check post state for addr, account := range test.Post { diff --git a/tests/transaction_test.go b/tests/transaction_test.go index e1237dee2..41a20a1bb 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -6,40 +6,21 @@ import ( ) func TestTransactions(t *testing.T) { - notWorking := make(map[string]bool, 100) - - // TODO: all these tests should work! remove them from the array when they work - snafus := []string{ - "TransactionWithHihghNonce256", // fails due to testing upper bound of 256 bit nonce - } - - for _, name := range snafus { - notWorking[name] = true - } - - var err error - err = RunTransactionTests(filepath.Join(transactionTestDir, "ttTransactionTest.json"), - notWorking) + err := RunTransactionTests(filepath.Join(transactionTestDir, "ttTransactionTest.json")) if err != nil { t.Fatal(err) } } func TestWrongRLPTransactions(t *testing.T) { - notWorking := make(map[string]bool, 100) - var err error - err = RunTransactionTests(filepath.Join(transactionTestDir, "ttWrongRLPTransaction.json"), - notWorking) + err := RunTransactionTests(filepath.Join(transactionTestDir, "ttWrongRLPTransaction.json")) if err != nil { t.Fatal(err) } } func Test10MBtx(t *testing.T) { - notWorking := make(map[string]bool, 100) - var err error - err = RunTransactionTests(filepath.Join(transactionTestDir, "tt10mbDataField.json"), - notWorking) + err := RunTransactionTests(filepath.Join(transactionTestDir, "tt10mbDataField.json")) if err != nil { t.Fatal(err) } diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index a6cea972a..65e2c7591 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -30,20 +30,29 @@ type TransactionTest struct { Transaction TtTransaction } -func RunTransactionTests(file string, notWorking map[string]bool) error { +func RunTransactionTests(file string) error { + skipTest := make(map[string]bool, len(transSkipTests)) + for _, name := range transSkipTests { + skipTest[name] = true + } + bt := make(map[string]TransactionTest) if err := LoadJSON(file, &bt); err != nil { return err } - for name, in := range bt { - var err error - // TODO: remove this, we currently ignore some tests which are broken - if !notWorking[name] { - if err = runTest(in); err != nil { - return fmt.Errorf("bad test %s: %v", name, err) - } - fmt.Println("Transaction test passed:", name) + + for name, test := range bt { + // if the test should be skipped, return + if skipTest[name] { + fmt.Println("Skipping state test", name) + return nil } + // test the block + if err := runTest(test); err != nil { + return err + } + fmt.Println("Transaction test passed: ", name) + } return nil } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 066217620..55036ed82 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -13,6 +13,10 @@ import ( ) func RunVmTest(p string) error { + skipTest := make(map[string]bool, len(vmSkipTests)) + for _, name := range vmSkipTests { + skipTest[name] = true + } tests := make(map[string]VmTest) err := CreateFileTests(p, &tests) @@ -21,14 +25,10 @@ func RunVmTest(p string) error { } for name, test := range tests { - /* - vm.Debug = true - glog.SetV(4) - glog.SetToStderr(true) - if name != "Call50000_sha256" { - continue - } - */ + if skipTest[name] { + fmt.Println("Skipping state test", name) + return nil + } db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) for addr, account := range test.Pre { From 6ff956394a26fe13c774797284220b8231ebf809 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 18:11:30 -0400 Subject: [PATCH 059/110] DRY file loading --- tests/block_test_util.go | 56 ++++++++-------------------------- tests/init.go | 32 ++++++++++++++++--- tests/state_test_util.go | 8 +---- tests/transaction_test_util.go | 2 +- tests/vm_test_util.go | 2 +- 5 files changed, 42 insertions(+), 58 deletions(-) diff --git a/tests/block_test_util.go b/tests/block_test_util.go index a04019111..7db47566b 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -3,9 +3,7 @@ package tests import ( "bytes" "encoding/hex" - "encoding/json" "fmt" - "io/ioutil" "math/big" "path/filepath" "runtime" @@ -87,9 +85,9 @@ type btTransaction struct { } func RunBlockTest(filepath string) error { - bt, err := LoadBlockTests(filepath) + bt, err := loadBlockTests(filepath) if err != nil { - return nil + return err } // map skipped tests to boolean set @@ -158,22 +156,6 @@ func testEthConfig() *eth.Config { } } -// LoadBlockTests loads a block test JSON file. -func LoadBlockTests(file string) (map[string]*BlockTest, error) { - bt := make(map[string]*btJSON) - if err := LoadJSON(file, &bt); err != nil { - return nil, err - } - out := make(map[string]*BlockTest) - for name, in := range bt { - var err error - if out[name], err = convertTest(in); err != nil { - return out, fmt.Errorf("bad test %q: %v", name, err) - } - } - return out, nil -} - // InsertPreState populates the given database with the genesis // accounts defined by the test. func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, error) { @@ -467,34 +449,20 @@ func mustConvertUint(in string, base int) uint64 { return out } -// LoadJSON reads the given file and unmarshals its content. -func LoadJSON(file string, val interface{}) error { - content, err := ioutil.ReadFile(file) - if err != nil { - return err +func loadBlockTests(file string) (map[string]*BlockTest, error) { + bt := make(map[string]*btJSON) + if err := readTestFile(file, &bt); err != nil { + return nil, err } - if err := json.Unmarshal(content, val); err != nil { - if syntaxerr, ok := err.(*json.SyntaxError); ok { - line := findLine(content, syntaxerr.Offset) - return fmt.Errorf("JSON syntax error at %v:%v: %v", file, line, err) - } - return fmt.Errorf("JSON unmarshal error in %v: %v", file, err) - } - return nil -} -// findLine returns the line number for the given offset into data. -func findLine(data []byte, offset int64) (line int) { - line = 1 - for i, r := range string(data) { - if int64(i) >= offset { - return - } - if r == '\n' { - line++ + out := make(map[string]*BlockTest) + for name, in := range bt { + var err error + if out[name], err = convertTest(in); err != nil { + return out, fmt.Errorf("bad test %q: %v", name, err) } } - return + return out, nil } // Nothing to see here, please move along... diff --git a/tests/init.go b/tests/init.go index 74d9499f1..aec06396b 100644 --- a/tests/init.go +++ b/tests/init.go @@ -2,6 +2,7 @@ package tests import ( "encoding/json" + "fmt" "io" "io/ioutil" "net/http" @@ -24,14 +25,35 @@ var ( func readJSON(reader io.Reader, value interface{}) error { data, err := ioutil.ReadAll(reader) - err = json.Unmarshal(data, &value) if err != nil { - return err + return fmt.Errorf("Error reading JSON file", err.Error()) + } + + if err = json.Unmarshal(data, &value); err != nil { + if syntaxerr, ok := err.(*json.SyntaxError); ok { + line := findLine(data, syntaxerr.Offset) + return fmt.Errorf("JSON syntax error at line %v: %v", line, err) + } + return fmt.Errorf("JSON unmarshal error: %v", err) } return nil } -func CreateHttpTests(uri string, value interface{}) error { +// findLine returns the line number for the given offset into data. +func findLine(data []byte, offset int64) (line int) { + line = 1 + for i, r := range string(data) { + if int64(i) >= offset { + return + } + if r == '\n' { + line++ + } + } + return +} + +func readHttpFile(uri string, value interface{}) error { resp, err := http.Get(uri) if err != nil { return err @@ -45,7 +67,7 @@ func CreateHttpTests(uri string, value interface{}) error { return nil } -func CreateFileTests(fn string, value interface{}) error { +func readTestFile(fn string, value interface{}) error { file, err := os.Open(fn) if err != nil { return err @@ -54,7 +76,7 @@ func CreateFileTests(fn string, value interface{}) error { err = readJSON(file, value) if err != nil { - return err + return fmt.Errorf("%s in file %s", err.Error(), fn) } return nil } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index b507de47f..cd87ee75e 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -21,7 +21,7 @@ func RunStateTest(p string) error { } tests := make(map[string]VmTest) - CreateFileTests(p, &tests) + readTestFile(p, &tests) for name, test := range tests { if skipTest[name] { @@ -61,16 +61,10 @@ func RunStateTest(p string) error { ret, logs, _, _ = RunState(statedb, env, test.Transaction) // // Compare expected and actual return - // switch name { - // // the memory required for these tests (4294967297 bytes) would take too much time. - // // on 19 May 2015 decided to skip these tests their output. - // case "mload32bitBound_return", "mload32bitBound_return2": - // default: rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } - // } // check post state for addr, account := range test.Post { diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 65e2c7591..2864257b7 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -37,7 +37,7 @@ func RunTransactionTests(file string) error { } bt := make(map[string]TransactionTest) - if err := LoadJSON(file, &bt); err != nil { + if err := readTestFile(file, &bt); err != nil { return err } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 55036ed82..28e0c3f40 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -19,7 +19,7 @@ func RunVmTest(p string) error { } tests := make(map[string]VmTest) - err := CreateFileTests(p, &tests) + err := readTestFile(p, &tests) if err != nil { return err } From 6931267324a4cb00d1edf0b8e85333b744882c2d Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 10 Jun 2015 18:14:04 -0400 Subject: [PATCH 060/110] Wire ethtest to new tests structure --- cmd/ethtest/main.go | 235 ++++++-------------------------------------- 1 file changed, 32 insertions(+), 203 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index c33db45d2..d89271a0c 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -22,208 +22,15 @@ package main import ( - "bytes" - "encoding/json" - "io" - "io/ioutil" - "log" - "math/big" "os" - "strconv" - "strings" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/tests/helper" + "github.com/ethereum/go-ethereum/tests" ) -type Log struct { - AddressF string `json:"address"` - DataF string `json:"data"` - TopicsF []string `json:"topics"` - BloomF string `json:"bloom"` -} - -func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } -func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } -func (self Log) RlpData() interface{} { return nil } -func (self Log) Topics() [][]byte { - t := make([][]byte, len(self.TopicsF)) - for i, topic := range self.TopicsF { - t[i] = common.Hex2Bytes(topic) - } - return t -} - -type Account struct { - Balance string - Code string - Nonce string - Storage map[string]string -} - -func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { - obj := state.NewStateObject(common.HexToAddress(addr), db) - obj.SetBalance(common.Big(account.Balance)) - - if common.IsHex(account.Code) { - account.Code = account.Code[2:] - } - obj.SetCode(common.Hex2Bytes(account.Code)) - obj.SetNonce(common.Big(account.Nonce).Uint64()) - - return obj -} - -type VmTest struct { - Callcreates interface{} - Env Env - Exec map[string]string - Transaction map[string]string - Logs []Log - Gas string - Out string - Post map[string]Account - Pre map[string]Account - PostStateRoot string -} - -type Env struct { - CurrentCoinbase string - CurrentDifficulty string - CurrentGasLimit string - CurrentNumber string - CurrentTimestamp interface{} - PreviousHash string -} - -func RunVmTest(r io.Reader) (failed int) { - tests := make(map[string]VmTest) - - data, _ := ioutil.ReadAll(r) - err := json.Unmarshal(data, &tests) - if err != nil { - log.Fatalln(err) - } - - vm.Debug = true - glog.SetV(4) - glog.SetToStderr(true) - for name, test := range tests { - db, _ := ethdb.NewMemDatabase() - statedb := state.New(common.Hash{}, db) - for addr, account := range test.Pre { - obj := StateObjectFromAccount(db, addr, account) - statedb.SetStateObject(obj) - } - - env := make(map[string]string) - env["currentCoinbase"] = test.Env.CurrentCoinbase - env["currentDifficulty"] = test.Env.CurrentDifficulty - env["currentGasLimit"] = test.Env.CurrentGasLimit - env["currentNumber"] = test.Env.CurrentNumber - env["previousHash"] = test.Env.PreviousHash - if n, ok := test.Env.CurrentTimestamp.(float64); ok { - env["currentTimestamp"] = strconv.Itoa(int(n)) - } else { - env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) - } - - ret, logs, _, _ := helper.RunState(statedb, env, test.Transaction) - statedb.Sync() - - rexp := helper.FromHex(test.Out) - if bytes.Compare(rexp, ret) != 0 { - glog.V(logger.Info).Infof("%s's return failed. Expected %x, got %x\n", name, rexp, ret) - failed = 1 - } - - for addr, account := range test.Post { - obj := statedb.GetStateObject(common.HexToAddress(addr)) - if obj == nil { - continue - } - - if len(test.Exec) == 0 { - if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { - glog.V(logger.Info).Infof("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) - failed = 1 - } - } - - for addr, value := range account.Storage { - v := obj.GetState(common.HexToHash(addr)).Bytes() - vexp := helper.FromHex(value) - - if bytes.Compare(v, vexp) != 0 { - glog.V(logger.Info).Infof("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) - failed = 1 - } - } - } - - statedb.Sync() - //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { - if common.HexToHash(test.PostStateRoot) != statedb.Root() { - glog.V(logger.Info).Infof("%s's : Post state root failed. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) - failed = 1 - } - - if len(test.Logs) > 0 { - if len(test.Logs) != len(logs) { - glog.V(logger.Info).Infof("log length failed. Expected %d, got %d", len(test.Logs), len(logs)) - failed = 1 - } else { - for i, log := range test.Logs { - if common.HexToAddress(log.AddressF) != logs[i].Address { - glog.V(logger.Info).Infof("'%s' log address failed. Expected %v got %x", name, log.AddressF, logs[i].Address) - failed = 1 - } - - if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { - glog.V(logger.Info).Infof("'%s' log data failed. Expected %v got %x", name, log.DataF, logs[i].Data) - failed = 1 - } - - if len(log.TopicsF) != len(logs[i].Topics) { - glog.V(logger.Info).Infof("'%s' log topics length failed. Expected %d got %d", name, len(log.TopicsF), logs[i].Topics) - failed = 1 - } else { - for j, topic := range log.TopicsF { - if common.HexToHash(topic) != logs[i].Topics[j] { - glog.V(logger.Info).Infof("'%s' log topic[%d] failed. Expected %v got %x", name, j, topic, logs[i].Topics[j]) - failed = 1 - } - } - } - genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) - - if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { - glog.V(logger.Info).Infof("'%s' bloom failed.", name) - failed = 1 - } - } - } - } - - if failed == 1 { - glog.V(logger.Info).Infoln(string(statedb.Dump())) - } - - logger.Flush() - } - - return -} - func main() { - helper.Logger.SetLogLevel(5) - vm.Debug = true + // helper.Logger.SetLogLevel(5) + // vm.Debug = true if len(os.Args) < 2 { glog.Exit("Must specify test type") @@ -231,23 +38,45 @@ func main() { test := os.Args[1] - var code int + // var code int switch test { case "vm", "VMTests": - glog.Exit("VMTests not yet implemented") + if len(os.Args) > 2 { + if err := tests.RunVmTest(os.Args[2]); err != nil { + glog.Errorln(err) + } + } else { + glog.Exit("Must supply file argument") + } case "state", "StateTest": if len(os.Args) > 2 { - code = RunVmTest(strings.NewReader(os.Args[2])) + if err := tests.RunStateTest(os.Args[2]); err != nil { + glog.Errorln(err) + } + // code = RunVmTest(strings.NewReader(os.Args[2])) } else { - code = RunVmTest(os.Stdin) + glog.Exit("Must supply file argument") + // code = RunVmTest(os.Stdin) } case "tx", "TransactionTests": - glog.Exit("TransactionTests not yet implemented") + if len(os.Args) > 2 { + if err := tests.RunTransactionTests(os.Args[2]); err != nil { + glog.Errorln(err) + } + } else { + glog.Exit("Must supply file argument") + } case "bc", "BlockChainTest": - glog.Exit("BlockChainTest not yet implemented") + if len(os.Args) > 2 { + if err := tests.RunBlockTest(os.Args[2]); err != nil { + glog.Errorln(err) + } + } else { + glog.Exit("Must supply file argument") + } default: glog.Exit("Invalid test type specified") } - os.Exit(code) + // os.Exit(code) } From 8507c867b9cca2b1d59182baea90ab2844d494a0 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 11 Jun 2015 12:20:30 -0400 Subject: [PATCH 061/110] Fix geth blocktest command --- cmd/geth/blocktestcmd.go | 1 + tests/block_test_util.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/geth/blocktestcmd.go b/cmd/geth/blocktestcmd.go index ffea4400e..116eec2b3 100644 --- a/cmd/geth/blocktestcmd.go +++ b/cmd/geth/blocktestcmd.go @@ -86,6 +86,7 @@ func runBlockTest(ctx *cli.Context) { } func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) { + // TODO remove in favor of logic contained in tests package cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() } cfg.MaxPeers = 0 // disable network diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 7db47566b..787056b89 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -85,7 +85,7 @@ type btTransaction struct { } func RunBlockTest(filepath string) error { - bt, err := loadBlockTests(filepath) + bt, err := LoadBlockTests(filepath) if err != nil { return err } @@ -449,7 +449,7 @@ func mustConvertUint(in string, base int) uint64 { return out } -func loadBlockTests(file string) (map[string]*BlockTest, error) { +func LoadBlockTests(file string) (map[string]*BlockTest, error) { bt := make(map[string]*btJSON) if err := readTestFile(file, &bt); err != nil { return nil, err From c941a39b756783d95526a74374dd2aa4283474fa Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 11 Jun 2015 13:06:56 -0400 Subject: [PATCH 062/110] Cleanup logging --- cmd/ethtest/main.go | 3 ++- tests/block_test_util.go | 6 +++--- tests/init.go | 2 +- tests/state_test_util.go | 5 +++-- tests/transaction_test_util.go | 5 +++-- tests/vm_test_util.go | 6 +++--- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index d89271a0c..07554c89f 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -29,7 +29,8 @@ import ( ) func main() { - // helper.Logger.SetLogLevel(5) + glog.SetToStderr(true) + // vm.Debug = true if len(os.Args) < 2 { diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 787056b89..21fd07db6 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" ) @@ -99,15 +100,14 @@ func RunBlockTest(filepath string) error { for name, test := range bt { // if the test should be skipped, return if skipTest[name] { - fmt.Println("Skipping state test", name) + glog.Infoln("Skipping block test", name) return nil } // test the block if err := testBlock(test); err != nil { return err } - fmt.Println("Block test passed: ", name) - + glog.Infoln("Block test passed: ", name) } return nil } diff --git a/tests/init.go b/tests/init.go index aec06396b..164924ab8 100644 --- a/tests/init.go +++ b/tests/init.go @@ -17,7 +17,7 @@ var ( transactionTestDir = filepath.Join(baseDir, "TransactionTests") vmTestDir = filepath.Join(baseDir, "VMTests") - blockSkipTests = []string{} + blockSkipTests = []string{"SimpleTx3"} transSkipTests = []string{"TransactionWithHihghNonce256"} stateSkipTests = []string{"mload32bitBound_return", "mload32bitBound_return2"} vmSkipTests = []string{} diff --git a/tests/state_test_util.go b/tests/state_test_util.go index cd87ee75e..ad14168c7 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/logger/glog" ) func RunStateTest(p string) error { @@ -25,7 +26,7 @@ func RunStateTest(p string) error { for name, test := range tests { if skipTest[name] { - fmt.Println("Skipping state test", name) + glog.Infoln("Skipping state test", name) return nil } db, _ := ethdb.NewMemDatabase() @@ -105,7 +106,7 @@ func RunStateTest(p string) error { } } - fmt.Println("State test passed: ", name) + glog.Infoln("State test passed: ", name) //fmt.Println(string(statedb.Dump())) } return nil diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 2864257b7..ef133a99d 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" ) @@ -44,14 +45,14 @@ func RunTransactionTests(file string) error { for name, test := range bt { // if the test should be skipped, return if skipTest[name] { - fmt.Println("Skipping state test", name) + glog.Infoln("Skipping transaction test", name) return nil } // test the block if err := runTest(test); err != nil { return err } - fmt.Println("Transaction test passed: ", name) + glog.Infoln("Transaction test passed: ", name) } return nil diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 28e0c3f40..4145d1ebf 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/logger/glog" ) func RunVmTest(p string) error { @@ -26,7 +27,7 @@ func RunVmTest(p string) error { for name, test := range tests { if skipTest[name] { - fmt.Println("Skipping state test", name) + glog.Infoln("Skipping VM test", name) return nil } db, _ := ethdb.NewMemDatabase() @@ -102,8 +103,7 @@ func RunVmTest(p string) error { } } - fmt.Println("VM test passed: ", name) - + glog.Infoln("VM test passed: ", name) //fmt.Println(string(statedb.Dump())) } return nil From 30444db02068210d41060a69b2c591107d9c94b3 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 11 Jun 2015 13:33:58 -0400 Subject: [PATCH 063/110] Add lost rebase changes --- tests/util.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/util.go b/tests/util.go index 6554c4b94..67650c188 100644 --- a/tests/util.go +++ b/tests/util.go @@ -124,7 +124,7 @@ type Env struct { difficulty *big.Int gasLimit *big.Int - logs state.Logs + logs []vm.StructLog vmTest bool } @@ -135,6 +135,14 @@ func NewEnv(state *state.StateDB) *Env { } } +func (self *Env) StructLogs() []vm.StructLog { + return self.logs +} + +func (self *Env) AddStructLog(log vm.StructLog) { + self.logs = append(self.logs, log) +} + func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { env := NewEnv(state) From 516362bcadf7aee1ed132fecfeff1d91805abaaa Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 11 Jun 2015 15:23:49 -0400 Subject: [PATCH 064/110] Allow specifying single depth directory --- cmd/ethtest/main.go | 114 ++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 42 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index 07554c89f..844c15e32 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -22,62 +22,92 @@ package main import ( + "io/ioutil" "os" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/tests" ) +func getFiles(path string) ([]string, error) { + var files []string + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + fi, err := f.Stat() + if err != nil { + return nil, err + } + + switch mode := fi.Mode(); { + case mode.IsDir(): + fi, _ := ioutil.ReadDir(path) + files = make([]string, len(fi)) + for i, v := range fi { + // only go 1 depth and leave directory entires blank + if !v.IsDir() { + files[i] = path + v.Name() + } + } + case mode.IsRegular(): + files = make([]string, 1) + files[0] = path + } + + return files, nil +} + func main() { glog.SetToStderr(true) - + var continueOnError bool = false // vm.Debug = true if len(os.Args) < 2 { glog.Exit("Must specify test type") } - test := os.Args[1] - - // var code int - switch test { - case "vm", "VMTests": - if len(os.Args) > 2 { - if err := tests.RunVmTest(os.Args[2]); err != nil { - glog.Errorln(err) - } - } else { - glog.Exit("Must supply file argument") - } - case "state", "StateTest": - if len(os.Args) > 2 { - if err := tests.RunStateTest(os.Args[2]); err != nil { - glog.Errorln(err) - } - // code = RunVmTest(strings.NewReader(os.Args[2])) - } else { - glog.Exit("Must supply file argument") - // code = RunVmTest(os.Stdin) - } - case "tx", "TransactionTests": - if len(os.Args) > 2 { - if err := tests.RunTransactionTests(os.Args[2]); err != nil { - glog.Errorln(err) - } - } else { - glog.Exit("Must supply file argument") - } - case "bc", "BlockChainTest": - if len(os.Args) > 2 { - if err := tests.RunBlockTest(os.Args[2]); err != nil { - glog.Errorln(err) - } - } else { - glog.Exit("Must supply file argument") - } - default: - glog.Exit("Invalid test type specified") + testtype := os.Args[1] + var pattern string + if len(os.Args) > 2 { + pattern = os.Args[2] } - // os.Exit(code) + files, err := getFiles(pattern) + if err != nil { + glog.Fatal(err) + } + + for _, testfile := range files { + // Skip blank entries + if len(testfile) == 0 { + continue + } + // TODO allow io.Reader to be passed so Stdin can be piped + // RunVmTest(strings.NewReader(os.Args[2])) + // RunVmTest(os.Stdin) + var err error + switch testtype { + case "vm", "VMTests": + err = tests.RunVmTest(testfile) + case "state", "StateTest": + err = tests.RunStateTest(testfile) + case "tx", "TransactionTests": + err = tests.RunTransactionTests(testfile) + case "bc", "BlockChainTest": + err = tests.RunBlockTest(testfile) + default: + glog.Fatalln("Invalid test type specified") + } + + if err != nil { + if continueOnError { + glog.Errorln(err) + } else { + glog.Fatalln(err) + } + } + } } From 49336675f3aeff478022ca6dc56ad39dca25ff47 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 11 Jun 2015 23:08:44 -0400 Subject: [PATCH 065/110] Expand CLI options to allow running all tests --- cmd/ethtest/main.go | 154 +++++++++++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 43 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index 844c15e32..7103a074a 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -22,14 +22,60 @@ package main import ( + "fmt" "io/ioutil" "os" + "path/filepath" + "github.com/codegangsta/cli" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/tests" ) +var ( + continueOnError = false + testExtension = ".json" + defaultTest = "all" + defaultDir = "." + allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"} + + TestFlag = cli.StringFlag{ + Name: "test", + Usage: "Test type (string): VMTests, TransactionTests, StateTests, BlockTests", + Value: defaultTest, + } + FileFlag = cli.StringFlag{ + Name: "file", + Usage: "Test file or directory. Directories are searched for .json files 1 level deep", + Value: defaultDir, + EnvVar: "ETHEREUM_TEST_PATH", + } + ContinueOnErrorFlag = cli.BoolFlag{ + Name: "continue", + Usage: "Continue running tests on error (true) or exit immediately (false)", + } +) + +func runTest(test, file string) error { + // glog.Infoln("runTest", test, file) + var err error + switch test { + case "bc", "BlockTest", "BlockTests", "BlockChainTest": + err = tests.RunBlockTest(file) + case "st", "state", "StateTest", "StateTests": + err = tests.RunStateTest(file) + case "tx", "TransactionTest", "TransactionTests": + err = tests.RunTransactionTests(file) + case "vm", "VMTest", "VMTests": + err = tests.RunVmTest(file) + default: + err = fmt.Errorf("Invalid test type specified:", test) + } + return err +} + func getFiles(path string) ([]string, error) { + // glog.Infoln("getFiles ", path) var files []string f, err := os.Open(path) if err != nil { @@ -48,8 +94,9 @@ func getFiles(path string) ([]string, error) { files = make([]string, len(fi)) for i, v := range fi { // only go 1 depth and leave directory entires blank - if !v.IsDir() { - files[i] = path + v.Name() + if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension { + files[i] = filepath.Join(path, v.Name()) + // glog.Infoln(files[i]) } } case mode.IsRegular(): @@ -60,54 +107,75 @@ func getFiles(path string) ([]string, error) { return files, nil } -func main() { - glog.SetToStderr(true) - var continueOnError bool = false - // vm.Debug = true +func runSuite(c *cli.Context) { + flagTest := c.GlobalString(TestFlag.Name) + flagFile := c.GlobalString(FileFlag.Name) + continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) - if len(os.Args) < 2 { - glog.Exit("Must specify test type") + var tests []string + + if flagTest == defaultTest { + tests = allTests + } else { + tests = []string{flagTest} } - testtype := os.Args[1] - var pattern string - if len(os.Args) > 2 { - pattern = os.Args[2] - } - - files, err := getFiles(pattern) - if err != nil { - glog.Fatal(err) - } - - for _, testfile := range files { - // Skip blank entries - if len(testfile) == 0 { - continue - } - // TODO allow io.Reader to be passed so Stdin can be piped - // RunVmTest(strings.NewReader(os.Args[2])) - // RunVmTest(os.Stdin) + for _, curTest := range tests { + // glog.Infoln("runSuite", curTest, flagFile) var err error - switch testtype { - case "vm", "VMTests": - err = tests.RunVmTest(testfile) - case "state", "StateTest": - err = tests.RunStateTest(testfile) - case "tx", "TransactionTests": - err = tests.RunTransactionTests(testfile) - case "bc", "BlockChainTest": - err = tests.RunBlockTest(testfile) - default: - glog.Fatalln("Invalid test type specified") + var files []string + if flagTest == defaultTest { + files, err = getFiles(filepath.Join(flagFile, curTest)) + + } else { + files, err = getFiles(flagFile) + } + if err != nil { + glog.Fatalln(err) } - if err != nil { - if continueOnError { - glog.Errorln(err) - } else { - glog.Fatalln(err) + if len(files) == 0 { + glog.Warningln("No files matched path") + } + for _, testfile := range files { + // Skip blank entries + if len(testfile) == 0 { + continue } + + // TODO allow io.Reader to be passed so Stdin can be piped + // RunVmTest(strings.NewReader(os.Args[2])) + // RunVmTest(os.Stdin) + err := runTest(curTest, testfile) + if err != nil { + if continueOnError { + glog.Errorln(err) + } else { + glog.Fatalln(err) + } + } + } } } + +func main() { + glog.SetToStderr(true) + + // vm.Debug = true + + app := cli.NewApp() + app.Name = "ethtest" + app.Usage = "go-ethereum test interface" + app.Action = runSuite + app.Flags = []cli.Flag{ + TestFlag, + FileFlag, + ContinueOnErrorFlag, + } + + if err := app.Run(os.Args); err != nil { + glog.Fatalln(err) + } + +} From a86452d22c2206fd05cfa72b547e7014a0859c7c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 12 Jun 2015 09:13:39 -0400 Subject: [PATCH 066/110] Minor cleanup --- cmd/ethtest/main.go | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index 7103a074a..a78111797 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -17,6 +17,7 @@ /** * @authors: * Jeffrey Wilcke + * Taylor Gerring */ package main @@ -52,7 +53,7 @@ var ( } ContinueOnErrorFlag = cli.BoolFlag{ Name: "continue", - Usage: "Continue running tests on error (true) or exit immediately (false)", + Usage: "Continue running tests on error (true) or [default] exit immediately (false)", } ) @@ -75,7 +76,7 @@ func runTest(test, file string) error { } func getFiles(path string) ([]string, error) { - // glog.Infoln("getFiles ", path) + // glog.Infoln("getFiles", path) var files []string f, err := os.Open(path) if err != nil { @@ -96,7 +97,7 @@ func getFiles(path string) ([]string, error) { // only go 1 depth and leave directory entires blank if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension { files[i] = filepath.Join(path, v.Name()) - // glog.Infoln(files[i]) + // glog.Infoln("Found file", files[i]) } } case mode.IsRegular(): @@ -107,28 +108,24 @@ func getFiles(path string) ([]string, error) { return files, nil } -func runSuite(c *cli.Context) { - flagTest := c.GlobalString(TestFlag.Name) - flagFile := c.GlobalString(FileFlag.Name) - continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) - +func runSuite(test, file string) { var tests []string - if flagTest == defaultTest { + if test == defaultTest { tests = allTests } else { - tests = []string{flagTest} + tests = []string{test} } for _, curTest := range tests { - // glog.Infoln("runSuite", curTest, flagFile) + // glog.Infoln("runSuite", curTest, file) var err error var files []string - if flagTest == defaultTest { - files, err = getFiles(filepath.Join(flagFile, curTest)) + if test == defaultTest { + files, err = getFiles(filepath.Join(file, curTest)) } else { - files, err = getFiles(flagFile) + files, err = getFiles(file) } if err != nil { glog.Fatalln(err) @@ -159,15 +156,24 @@ func runSuite(c *cli.Context) { } } +func setupApp(c *cli.Context) { + flagTest := c.GlobalString(TestFlag.Name) + flagFile := c.GlobalString(FileFlag.Name) + continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) + + runSuite(flagTest, flagFile) +} + func main() { glog.SetToStderr(true) - // vm.Debug = true - app := cli.NewApp() app.Name = "ethtest" app.Usage = "go-ethereum test interface" - app.Action = runSuite + app.Action = setupApp + app.Version = "0.2.0" + app.Author = "go-ethereum team" + app.Flags = []cli.Flag{ TestFlag, FileFlag, From 01ec4dbb1251751b8bbf62ddb3b3a02dc50d29fc Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sun, 14 Jun 2015 17:55:03 -0400 Subject: [PATCH 067/110] Add stdin option --- cmd/ethtest/main.go | 60 +++++++---- tests/block_test_util.go | 80 ++++++++++---- tests/init.go | 95 ++++++++++------ tests/state_test_util.go | 192 +++++++++++++++++++-------------- tests/transaction_test_util.go | 41 +++++-- tests/vm_test_util.go | 191 +++++++++++++++++++------------- 6 files changed, 422 insertions(+), 237 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index a78111797..93bf3ce65 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -24,6 +24,7 @@ package main import ( "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -55,28 +56,37 @@ var ( Name: "continue", Usage: "Continue running tests on error (true) or [default] exit immediately (false)", } + ReadStdInFlag = cli.BoolFlag{ + Name: "stdin", + Usage: "Accept input from stdin instead of reading from file", + } ) -func runTest(test, file string) error { - // glog.Infoln("runTest", test, file) +func runTestWithReader(test string, r io.Reader) error { + glog.Infoln("runTest", test) var err error switch test { - case "bc", "BlockTest", "BlockTests", "BlockChainTest": - err = tests.RunBlockTest(file) + case "bt", "BlockTest", "BlockTests", "BlockChainTest": + err = tests.RunBlockTestWithReader(r) case "st", "state", "StateTest", "StateTests": - err = tests.RunStateTest(file) + err = tests.RunStateTestWithReader(r) case "tx", "TransactionTest", "TransactionTests": - err = tests.RunTransactionTests(file) + err = tests.RunTransactionTestsWithReader(r) case "vm", "VMTest", "VMTests": - err = tests.RunVmTest(file) + err = tests.RunVmTestWithReader(r) default: - err = fmt.Errorf("Invalid test type specified:", test) + err = fmt.Errorf("Invalid test type specified: %v", test) } - return err + + if err != nil { + return err + } + + return nil } func getFiles(path string) ([]string, error) { - // glog.Infoln("getFiles", path) + glog.Infoln("getFiles", path) var files []string f, err := os.Open(path) if err != nil { @@ -97,7 +107,7 @@ func getFiles(path string) ([]string, error) { // only go 1 depth and leave directory entires blank if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension { files[i] = filepath.Join(path, v.Name()) - // glog.Infoln("Found file", files[i]) + glog.Infoln("Found file", files[i]) } } case mode.IsRegular(): @@ -118,7 +128,7 @@ func runSuite(test, file string) { } for _, curTest := range tests { - // glog.Infoln("runSuite", curTest, file) + glog.Infoln("runSuite", curTest, file) var err error var files []string if test == defaultTest { @@ -134,16 +144,19 @@ func runSuite(test, file string) { if len(files) == 0 { glog.Warningln("No files matched path") } - for _, testfile := range files { + for _, curFile := range files { // Skip blank entries - if len(testfile) == 0 { + if len(curFile) == 0 { continue } - // TODO allow io.Reader to be passed so Stdin can be piped - // RunVmTest(strings.NewReader(os.Args[2])) - // RunVmTest(os.Stdin) - err := runTest(curTest, testfile) + r, err := os.Open(curFile) + if err != nil { + glog.Fatalln(err) + } + defer r.Close() + + err = runTestWithReader(curTest, r) if err != nil { if continueOnError { glog.Errorln(err) @@ -160,8 +173,16 @@ func setupApp(c *cli.Context) { flagTest := c.GlobalString(TestFlag.Name) flagFile := c.GlobalString(FileFlag.Name) continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) + useStdIn := c.GlobalBool(ReadStdInFlag.Name) - runSuite(flagTest, flagFile) + if !useStdIn { + runSuite(flagTest, flagFile) + } else { + if err := runTestWithReader(flagTest, os.Stdin); err != nil { + glog.Fatalln(err) + } + + } } func main() { @@ -178,6 +199,7 @@ func main() { TestFlag, FileFlag, ContinueOnErrorFlag, + ReadStdInFlag, } if err := app.Run(os.Args); err != nil { diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 21fd07db6..5222b214b 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/hex" "fmt" + "io" "math/big" "path/filepath" "runtime" @@ -85,15 +86,42 @@ type btTransaction struct { Value string } -func RunBlockTest(filepath string) error { - bt, err := LoadBlockTests(filepath) +func RunBlockTestWithReader(r io.Reader) error { + btjs := make(map[string]*btJSON) + if err := readJson(r, &btjs); err != nil { + return err + } + + bt, err := convertBlockTests(btjs) if err != nil { return err } - // map skipped tests to boolean set - skipTest := make(map[string]bool, len(blockSkipTests)) - for _, name := range blockSkipTests { + if err := runBlockTests(bt); err != nil { + return err + } + return nil +} + +func RunBlockTest(file string) error { + btjs := make(map[string]*btJSON) + if err := readJsonFile(file, &btjs); err != nil { + return err + } + + bt, err := convertBlockTests(btjs) + if err != nil { + return err + } + if err := runBlockTests(bt); err != nil { + return err + } + return nil +} + +func runBlockTests(bt map[string]*BlockTest) error { + skipTest := make(map[string]bool, len(BlockSkipTests)) + for _, name := range BlockSkipTests { skipTest[name] = true } @@ -103,17 +131,19 @@ func RunBlockTest(filepath string) error { glog.Infoln("Skipping block test", name) return nil } + // test the block - if err := testBlock(test); err != nil { + if err := runBlockTest(test); err != nil { return err } glog.Infoln("Block test passed: ", name) + } return nil -} -func testBlock(test *BlockTest) error { - cfg := testEthConfig() +} +func runBlockTest(test *BlockTest) error { + cfg := test.makeEthConfig() ethereum, err := eth.New(cfg) if err != nil { return err @@ -144,7 +174,7 @@ func testBlock(test *BlockTest) error { return nil } -func testEthConfig() *eth.Config { +func (test *BlockTest) makeEthConfig() *eth.Config { ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore")) return ð.Config{ @@ -230,7 +260,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error { if b.BlockHeader == nil { return fmt.Errorf("Block insertion should have failed") } - err = validateBlockHeader(b.BlockHeader, cb.Header()) + err = t.validateBlockHeader(b.BlockHeader, cb.Header()) if err != nil { return fmt.Errorf("Block header validation failed: ", err) } @@ -238,7 +268,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error { return nil } -func validateBlockHeader(h *btHeader, h2 *types.Header) error { +func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error { expectedBloom := mustConvertBytes(h.Bloom) if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) { return fmt.Errorf("Bloom: expected: %v, decoded: %v", expectedBloom, h2.Bloom.Bytes()) @@ -341,7 +371,18 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error { return nil } -func convertTest(in *btJSON) (out *BlockTest, err error) { +func convertBlockTests(in map[string]*btJSON) (map[string]*BlockTest, error) { + out := make(map[string]*BlockTest) + for name, test := range in { + var err error + if out[name], err = convertBlockTest(test); err != nil { + return out, fmt.Errorf("bad test %q: %v", name, err) + } + } + return out, nil +} + +func convertBlockTest(in *btJSON) (out *BlockTest, err error) { // the conversion handles errors by catching panics. // you might consider this ugly, but the alternative (passing errors) // would be much harder to read. @@ -450,19 +491,12 @@ func mustConvertUint(in string, base int) uint64 { } func LoadBlockTests(file string) (map[string]*BlockTest, error) { - bt := make(map[string]*btJSON) - if err := readTestFile(file, &bt); err != nil { + btjs := make(map[string]*btJSON) + if err := readJsonFile(file, &btjs); err != nil { return nil, err } - out := make(map[string]*BlockTest) - for name, in := range bt { - var err error - if out[name], err = convertTest(in); err != nil { - return out, fmt.Errorf("bad test %q: %v", name, err) - } - } - return out, nil + return convertBlockTests(btjs) } // Nothing to see here, please move along... diff --git a/tests/init.go b/tests/init.go index 164924ab8..326387341 100644 --- a/tests/init.go +++ b/tests/init.go @@ -8,6 +8,8 @@ import ( "net/http" "os" "path/filepath" + + // "github.com/ethereum/go-ethereum/logger/glog" ) var ( @@ -17,13 +19,40 @@ var ( transactionTestDir = filepath.Join(baseDir, "TransactionTests") vmTestDir = filepath.Join(baseDir, "VMTests") - blockSkipTests = []string{"SimpleTx3"} - transSkipTests = []string{"TransactionWithHihghNonce256"} - stateSkipTests = []string{"mload32bitBound_return", "mload32bitBound_return2"} - vmSkipTests = []string{} + BlockSkipTests = []string{"SimpleTx3"} + TransSkipTests = []string{"TransactionWithHihghNonce256"} + StateSkipTests = []string{"mload32bitBound_return", "mload32bitBound_return2"} + VmSkipTests = []string{} ) -func readJSON(reader io.Reader, value interface{}) error { +// type TestRunner interface { +// // LoadTest() +// RunTest() error +// } + +// func RunTests(bt map[string]TestRunner, skipTests []string) error { +// // map skipped tests to boolean set +// skipTest := make(map[string]bool, len(skipTests)) +// for _, name := range skipTests { +// skipTest[name] = true +// } + +// for name, test := range bt { +// // if the test should be skipped, return +// if skipTest[name] { +// glog.Infoln("Skipping block test", name) +// return nil +// } +// // test the block +// if err := test.RunTest(); err != nil { +// return err +// } +// glog.Infoln("Block test passed: ", name) +// } +// return nil +// } + +func readJson(reader io.Reader, value interface{}) error { data, err := ioutil.ReadAll(reader) if err != nil { return fmt.Errorf("Error reading JSON file", err.Error()) @@ -39,6 +68,34 @@ func readJSON(reader io.Reader, value interface{}) error { return nil } +func readJsonHttp(uri string, value interface{}) error { + resp, err := http.Get(uri) + if err != nil { + return err + } + defer resp.Body.Close() + + err = readJson(resp.Body, value) + if err != nil { + return err + } + return nil +} + +func readJsonFile(fn string, value interface{}) error { + file, err := os.Open(fn) + if err != nil { + return err + } + defer file.Close() + + err = readJson(file, value) + if err != nil { + return fmt.Errorf("%s in file %s", err.Error(), fn) + } + return nil +} + // findLine returns the line number for the given offset into data. func findLine(data []byte, offset int64) (line int) { line = 1 @@ -52,31 +109,3 @@ func findLine(data []byte, offset int64) (line int) { } return } - -func readHttpFile(uri string, value interface{}) error { - resp, err := http.Get(uri) - if err != nil { - return err - } - defer resp.Body.Close() - - err = readJSON(resp.Body, value) - if err != nil { - return err - } - return nil -} - -func readTestFile(fn string, value interface{}) error { - file, err := os.Open(fn) - if err != nil { - return err - } - defer file.Close() - - err = readJSON(file, value) - if err != nil { - return fmt.Errorf("%s in file %s", err.Error(), fn) - } - return nil -} diff --git a/tests/state_test_util.go b/tests/state_test_util.go index ad14168c7..ad3aeea6c 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -3,6 +3,7 @@ package tests import ( "bytes" "fmt" + "io" "math/big" "strconv" @@ -15,101 +16,134 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" ) -func RunStateTest(p string) error { - skipTest := make(map[string]bool, len(stateSkipTests)) - for _, name := range stateSkipTests { - skipTest[name] = true +func RunStateTestWithReader(r io.Reader) error { + tests := make(map[string]VmTest) + if err := readJson(r, &tests); err != nil { + return err } + if err := runStateTests(tests); err != nil { + return err + } + + return nil +} + +func RunStateTest(p string) error { tests := make(map[string]VmTest) - readTestFile(p, &tests) + if err := readJsonFile(p, &tests); err != nil { + return err + } + + if err := runStateTests(tests); err != nil { + return err + } + + return nil + +} + +func runStateTests(tests map[string]VmTest) error { + skipTest := make(map[string]bool, len(StateSkipTests)) + for _, name := range StateSkipTests { + skipTest[name] = true + } for name, test := range tests { if skipTest[name] { glog.Infoln("Skipping state test", name) return nil } - db, _ := ethdb.NewMemDatabase() - statedb := state.New(common.Hash{}, db) - for addr, account := range test.Pre { - obj := StateObjectFromAccount(db, addr, account) - statedb.SetStateObject(obj) - for a, v := range account.Storage { - obj.SetState(common.HexToHash(a), common.HexToHash(s)) - } - } - // XXX Yeah, yeah... - env := make(map[string]string) - env["currentCoinbase"] = test.Env.CurrentCoinbase - env["currentDifficulty"] = test.Env.CurrentDifficulty - env["currentGasLimit"] = test.Env.CurrentGasLimit - env["currentNumber"] = test.Env.CurrentNumber - env["previousHash"] = test.Env.PreviousHash - if n, ok := test.Env.CurrentTimestamp.(float64); ok { - env["currentTimestamp"] = strconv.Itoa(int(n)) - } else { - env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) - } - - var ( - ret []byte - // gas *big.Int - // err error - logs state.Logs - ) - - ret, logs, _, _ = RunState(statedb, env, test.Transaction) - - // // Compare expected and actual return - rexp := common.FromHex(test.Out) - if bytes.Compare(rexp, ret) != 0 { - return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) - } - - // check post state - for addr, account := range test.Post { - obj := statedb.GetStateObject(common.HexToAddress(addr)) - if obj == nil { - continue - } - - if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { - return fmt.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) - } - - if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { - return fmt.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) - } - - for addr, value := range account.Storage { - v := obj.GetState(common.HexToHash(addr)).Bytes() - vexp := common.FromHex(value) - - if bytes.Compare(v, vexp) != 0 { - return fmt.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) - } - } - } - - statedb.Sync() - //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { - if common.HexToHash(test.PostStateRoot) != statedb.Root() { - return fmt.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) - } - - // check logs - if len(test.Logs) > 0 { - lerr := checkLogs(test.Logs, logs) - if lerr != nil { - return fmt.Errorf("'%s' ", name, lerr.Error()) - } + if err := runStateTest(test); err != nil { + return fmt.Errorf("%s: %s\n", name, err.Error()) } glog.Infoln("State test passed: ", name) //fmt.Println(string(statedb.Dump())) } return nil + +} + +func runStateTest(test VmTest) error { + db, _ := ethdb.NewMemDatabase() + statedb := state.New(common.Hash{}, db) + for addr, account := range test.Pre { + obj := StateObjectFromAccount(db, addr, account) + statedb.SetStateObject(obj) + for a, v := range account.Storage { + obj.SetState(common.HexToHash(a), common.HexToHash(v)) + } + } + + // XXX Yeah, yeah... + env := make(map[string]string) + env["currentCoinbase"] = test.Env.CurrentCoinbase + env["currentDifficulty"] = test.Env.CurrentDifficulty + env["currentGasLimit"] = test.Env.CurrentGasLimit + env["currentNumber"] = test.Env.CurrentNumber + env["previousHash"] = test.Env.PreviousHash + if n, ok := test.Env.CurrentTimestamp.(float64); ok { + env["currentTimestamp"] = strconv.Itoa(int(n)) + } else { + env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) + } + + var ( + ret []byte + // gas *big.Int + // err error + logs state.Logs + ) + + ret, logs, _, _ = RunState(statedb, env, test.Transaction) + + // // Compare expected and actual return + rexp := common.FromHex(test.Out) + if bytes.Compare(rexp, ret) != 0 { + return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret) + } + + // check post state + for addr, account := range test.Post { + obj := statedb.GetStateObject(common.HexToAddress(addr)) + if obj == nil { + continue + } + + if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { + return fmt.Errorf("(%x) balance failed. Expected %v, got %v => %v\n", obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) + } + + if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { + return fmt.Errorf("(%x) nonce failed. Expected %v, got %v\n", obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) + } + + for addr, value := range account.Storage { + v := obj.GetState(common.HexToHash(addr)).Bytes() + vexp := common.FromHex(value) + + if bytes.Compare(v, vexp) != 0 { + return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) + } + } + } + + statedb.Sync() + //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { + if common.HexToHash(test.PostStateRoot) != statedb.Root() { + return fmt.Errorf("Post state root error. Expected %s, got %x", test.PostStateRoot, statedb.Root()) + } + + // check logs + if len(test.Logs) > 0 { + if err := checkLogs(test.Logs, logs); err != nil { + return err + } + } + + return nil } func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index ef133a99d..af33f2c58 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "io" "runtime" "github.com/ethereum/go-ethereum/common" @@ -31,14 +32,14 @@ type TransactionTest struct { Transaction TtTransaction } -func RunTransactionTests(file string) error { - skipTest := make(map[string]bool, len(transSkipTests)) - for _, name := range transSkipTests { +func RunTransactionTestsWithReader(r io.Reader) error { + skipTest := make(map[string]bool, len(TransSkipTests)) + for _, name := range TransSkipTests { skipTest[name] = true } bt := make(map[string]TransactionTest) - if err := readTestFile(file, &bt); err != nil { + if err := readJson(r, &bt); err != nil { return err } @@ -49,7 +50,7 @@ func RunTransactionTests(file string) error { return nil } // test the block - if err := runTest(test); err != nil { + if err := runTransactionTest(test); err != nil { return err } glog.Infoln("Transaction test passed: ", name) @@ -58,7 +59,35 @@ func RunTransactionTests(file string) error { return nil } -func runTest(txTest TransactionTest) (err error) { +func RunTransactionTests(file string) error { + skipTest := make(map[string]bool, len(TransSkipTests)) + for _, name := range TransSkipTests { + skipTest[name] = true + } + + bt := make(map[string]TransactionTest) + if err := readJsonFile(file, &bt); err != nil { + return err + } + + for name, test := range bt { + // if the test should be skipped, return + if skipTest[name] { + glog.Infoln("Skipping transaction test", name) + return nil + } + + // test the block + if err := runTransactionTest(test); err != nil { + return err + } + glog.Infoln("Transaction test passed: ", name) + + } + return nil +} + +func runTransactionTest(txTest TransactionTest) (err error) { tx := new(types.Transaction) err = rlp.DecodeBytes(mustConvertBytes(txTest.Rlp), tx) diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 4145d1ebf..f7f1198ec 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -3,6 +3,7 @@ package tests import ( "bytes" "fmt" + "io" "math/big" "strconv" @@ -13,94 +14,53 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" ) -func RunVmTest(p string) error { - skipTest := make(map[string]bool, len(vmSkipTests)) - for _, name := range vmSkipTests { - skipTest[name] = true - } - +func RunVmTestWithReader(r io.Reader) error { tests := make(map[string]VmTest) - err := readTestFile(p, &tests) + err := readJson(r, &tests) if err != nil { return err } + if err != nil { + return err + } + + if err := runVmTests(tests); err != nil { + return err + } + + return nil +} + +func RunVmTest(p string) error { + + tests := make(map[string]VmTest) + err := readJsonFile(p, &tests) + if err != nil { + return err + } + + if err := runVmTests(tests); err != nil { + return err + } + + return nil +} + +func runVmTests(tests map[string]VmTest) error { + skipTest := make(map[string]bool, len(VmSkipTests)) + for _, name := range VmSkipTests { + skipTest[name] = true + } + for name, test := range tests { if skipTest[name] { glog.Infoln("Skipping VM test", name) return nil } - db, _ := ethdb.NewMemDatabase() - statedb := state.New(common.Hash{}, db) - for addr, account := range test.Pre { - obj := StateObjectFromAccount(db, addr, account) - statedb.SetStateObject(obj) - for a, v := range account.Storage { - obj.SetState(common.HexToHash(a), common.HexToHash(v)) - } - } - // XXX Yeah, yeah... - env := make(map[string]string) - env["currentCoinbase"] = test.Env.CurrentCoinbase - env["currentDifficulty"] = test.Env.CurrentDifficulty - env["currentGasLimit"] = test.Env.CurrentGasLimit - env["currentNumber"] = test.Env.CurrentNumber - env["previousHash"] = test.Env.PreviousHash - if n, ok := test.Env.CurrentTimestamp.(float64); ok { - env["currentTimestamp"] = strconv.Itoa(int(n)) - } else { - env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) - } - - var ( - ret []byte - gas *big.Int - err error - logs state.Logs - ) - - ret, logs, gas, err = RunVm(statedb, env, test.Exec) - - // Compare expectedand actual return - rexp := common.FromHex(test.Out) - if bytes.Compare(rexp, ret) != 0 { - return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) - } - - // Check gas usage - if len(test.Gas) == 0 && err == nil { - return fmt.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) - } else { - gexp := common.Big(test.Gas) - if gexp.Cmp(gas) != 0 { - return fmt.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) - } - } - - // check post state - for addr, account := range test.Post { - obj := statedb.GetStateObject(common.HexToAddress(addr)) - if obj == nil { - continue - } - - for addr, value := range account.Storage { - v := obj.GetState(common.HexToHash(addr)) - vexp := common.HexToHash(value) - - if v != vexp { - return t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) - } - } - } - - // check logs - if len(test.Logs) > 0 { - lerr := checkLogs(test.Logs, logs) - if lerr != nil { - return fmt.Errorf("'%s' ", name, lerr.Error()) - } + if err := runVmTest(test); err != nil { + return fmt.Errorf("%s %s", name, err.Error()) } glog.Infoln("VM test passed: ", name) @@ -109,6 +69,83 @@ func RunVmTest(p string) error { return nil } +func runVmTest(test VmTest) error { + db, _ := ethdb.NewMemDatabase() + statedb := state.New(common.Hash{}, db) + for addr, account := range test.Pre { + obj := StateObjectFromAccount(db, addr, account) + statedb.SetStateObject(obj) + for a, v := range account.Storage { + obj.SetState(common.HexToHash(a), common.HexToHash(v)) + } + } + + // XXX Yeah, yeah... + env := make(map[string]string) + env["currentCoinbase"] = test.Env.CurrentCoinbase + env["currentDifficulty"] = test.Env.CurrentDifficulty + env["currentGasLimit"] = test.Env.CurrentGasLimit + env["currentNumber"] = test.Env.CurrentNumber + env["previousHash"] = test.Env.PreviousHash + if n, ok := test.Env.CurrentTimestamp.(float64); ok { + env["currentTimestamp"] = strconv.Itoa(int(n)) + } else { + env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) + } + + var ( + ret []byte + gas *big.Int + err error + logs state.Logs + ) + + ret, logs, gas, err = RunVm(statedb, env, test.Exec) + + // Compare expectedand actual return + rexp := common.FromHex(test.Out) + if bytes.Compare(rexp, ret) != 0 { + return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret) + } + + // Check gas usage + if len(test.Gas) == 0 && err == nil { + return fmt.Errorf("gas unspecified, indicating an error. VM returned (incorrectly) successfull") + } else { + gexp := common.Big(test.Gas) + if gexp.Cmp(gas) != 0 { + return fmt.Errorf("gas failed. Expected %v, got %v\n", gexp, gas) + } + } + + // check post state + for addr, account := range test.Post { + obj := statedb.GetStateObject(common.HexToAddress(addr)) + if obj == nil { + continue + } + + for addr, value := range account.Storage { + v := obj.GetState(common.HexToHash(addr)) + vexp := common.HexToHash(value) + + if v != vexp { + return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.BigD(vexp), v.Big(v)) + } + } + } + + // check logs + if len(test.Logs) > 0 { + lerr := checkLogs(test.Logs, logs) + if lerr != nil { + return lerr + } + } + + return nil +} + func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) { var ( to = common.HexToAddress(exec["address"]) From baea8e87e5dfdcfb7b2fdcef48fa6038d60a6f9c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 18 Jun 2015 22:27:44 +0200 Subject: [PATCH 068/110] Rebase cleanup --- tests/init.go | 29 ----------------------------- tests/vm_test_util.go | 2 +- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/tests/init.go b/tests/init.go index 326387341..9fe98a0d1 100644 --- a/tests/init.go +++ b/tests/init.go @@ -8,8 +8,6 @@ import ( "net/http" "os" "path/filepath" - - // "github.com/ethereum/go-ethereum/logger/glog" ) var ( @@ -25,33 +23,6 @@ var ( VmSkipTests = []string{} ) -// type TestRunner interface { -// // LoadTest() -// RunTest() error -// } - -// func RunTests(bt map[string]TestRunner, skipTests []string) error { -// // map skipped tests to boolean set -// skipTest := make(map[string]bool, len(skipTests)) -// for _, name := range skipTests { -// skipTest[name] = true -// } - -// for name, test := range bt { -// // if the test should be skipped, return -// if skipTest[name] { -// glog.Infoln("Skipping block test", name) -// return nil -// } -// // test the block -// if err := test.RunTest(); err != nil { -// return err -// } -// glog.Infoln("Block test passed: ", name) -// } -// return nil -// } - func readJson(reader io.Reader, value interface{}) error { data, err := ioutil.ReadAll(reader) if err != nil { diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index f7f1198ec..9fccafd8e 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -130,7 +130,7 @@ func runVmTest(test VmTest) error { vexp := common.HexToHash(value) if v != vexp { - return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.BigD(vexp), v.Big(v)) + return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) } } } From 8d3faf69d00420b80d4d737e618b2c7791c10ae9 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 18 Jun 2015 22:38:17 +0200 Subject: [PATCH 069/110] Build error fixes --- build/test-global-coverage.sh | 2 +- tests/state_test_util.go | 9 ++++----- tests/vm_test_util.go | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/build/test-global-coverage.sh b/build/test-global-coverage.sh index 417c829f4..5bb233a31 100755 --- a/build/test-global-coverage.sh +++ b/build/test-global-coverage.sh @@ -16,7 +16,7 @@ for pkg in $(go list ./...); do # drop the namespace prefix. dir=${pkg##github.com/ethereum/go-ethereum/} - if [[ $dir != "tests/vm" ]]; then + if [[ $dir != "tests" ]]; then go test -covermode=count -coverprofile=$dir/profile.tmp $pkg fi if [[ -f $dir/profile.tmp ]]; then diff --git a/tests/state_test_util.go b/tests/state_test_util.go index ad3aeea6c..835ba44f4 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -121,17 +121,16 @@ func runStateTest(test VmTest) error { } for addr, value := range account.Storage { - v := obj.GetState(common.HexToHash(addr)).Bytes() - vexp := common.FromHex(value) + v := obj.GetState(common.HexToHash(addr)) + vexp := common.HexToHash(value) - if bytes.Compare(v, vexp) != 0 { - return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) + if v != vexp { + return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) } } } statedb.Sync() - //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { if common.HexToHash(test.PostStateRoot) != statedb.Root() { return fmt.Errorf("Post state root error. Expected %s, got %x", test.PostStateRoot, statedb.Root()) } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 9fccafd8e..afeedda2a 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -102,7 +102,7 @@ func runVmTest(test VmTest) error { ret, logs, gas, err = RunVm(statedb, env, test.Exec) - // Compare expectedand actual return + // Compare expected and actual return rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret) From a9659e6dcf1f1584e155825d4422eb005ff38c21 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 18 Jun 2015 23:46:42 +0200 Subject: [PATCH 070/110] recover test logic --- tests/state_test_util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 835ba44f4..577935dfa 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -172,7 +172,7 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state. vmenv := NewEnvFromMap(statedb, env, tx) vmenv.origin = common.BytesToAddress(keyPair.Address()) ret, _, err := core.ApplyMessage(vmenv, message, coinbase) - if core.IsNonceErr(err) || core.IsInvalidTxErr(err) { + if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) { statedb.Set(snapshot) } statedb.Update() From 4180ca7fe47359a80e88186b9127e93af685a81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 19 Jun 2015 10:07:37 +0300 Subject: [PATCH 071/110] eth: fix the propagation/announce order for mined blocks --- eth/handler.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eth/handler.go b/eth/handler.go index a5986b779..ad88e9c59 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -6,7 +6,6 @@ import ( "sync" "time" - "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -16,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/rlp" ) @@ -307,7 +307,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { blocks = nil } // Update the receive timestamp of each block - for i:=0; i Date: Fri, 19 Jun 2015 11:38:23 +0200 Subject: [PATCH 072/110] Add --skip option to CLI Disassociates hardcoded tests to skip when running via CLI. Tests still skipped when running `go test` --- cmd/ethtest/main.go | 16 ++++++++++++---- tests/block_test.go | 20 ++++++++++---------- tests/block_test_util.go | 14 +++++++------- tests/state_test.go | 34 +++++++++++++++++----------------- tests/state_test_util.go | 14 +++++++------- tests/transaction_test.go | 6 +++--- tests/transaction_test_util.go | 31 +++++++++++++++++++------------ tests/vm_test.go | 28 ++++++++++++++-------------- tests/vm_test_util.go | 14 +++++++------- 9 files changed, 96 insertions(+), 81 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index 93bf3ce65..c6073ce98 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -28,6 +28,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "github.com/codegangsta/cli" "github.com/ethereum/go-ethereum/logger/glog" @@ -40,6 +41,7 @@ var ( defaultTest = "all" defaultDir = "." allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"} + skipTests = []string{} TestFlag = cli.StringFlag{ Name: "test", @@ -60,6 +62,10 @@ var ( Name: "stdin", Usage: "Accept input from stdin instead of reading from file", } + SkipTestsFlag = cli.StringFlag{ + Name: "skip", + Usage: "Tests names to skip", + } ) func runTestWithReader(test string, r io.Reader) error { @@ -67,13 +73,13 @@ func runTestWithReader(test string, r io.Reader) error { var err error switch test { case "bt", "BlockTest", "BlockTests", "BlockChainTest": - err = tests.RunBlockTestWithReader(r) + err = tests.RunBlockTestWithReader(r, skipTests) case "st", "state", "StateTest", "StateTests": - err = tests.RunStateTestWithReader(r) + err = tests.RunStateTestWithReader(r, skipTests) case "tx", "TransactionTest", "TransactionTests": - err = tests.RunTransactionTestsWithReader(r) + err = tests.RunTransactionTestsWithReader(r, skipTests) case "vm", "VMTest", "VMTests": - err = tests.RunVmTestWithReader(r) + err = tests.RunVmTestWithReader(r, skipTests) default: err = fmt.Errorf("Invalid test type specified: %v", test) } @@ -174,6 +180,7 @@ func setupApp(c *cli.Context) { flagFile := c.GlobalString(FileFlag.Name) continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) useStdIn := c.GlobalBool(ReadStdInFlag.Name) + skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ") if !useStdIn { runSuite(flagTest, flagFile) @@ -200,6 +207,7 @@ func main() { FileFlag, ContinueOnErrorFlag, ReadStdInFlag, + SkipTestsFlag, } if err := app.Run(os.Args); err != nil { diff --git a/tests/block_test.go b/tests/block_test.go index 9d21ba28d..bdf983786 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -6,67 +6,67 @@ import ( ) func TestBcValidBlockTests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcValidBlockTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcValidBlockTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcUncleTests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } - err = RunBlockTest(filepath.Join(blockTestDir, "bcBruncleTest.json")) + err = RunBlockTest(filepath.Join(blockTestDir, "bcBruncleTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcUncleHeaderValidityTests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcInvalidHeaderTests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcInvalidRLPTests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidRLPTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcRPCAPITests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcRPC_API_Test.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcRPC_API_Test.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcForkBlockTests(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcForkBlockTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcForkBlockTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcTotalDifficulty(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcWallet(t *testing.T) { - err := RunBlockTest(filepath.Join(blockTestDir, "bcWalletTest.json")) + err := RunBlockTest(filepath.Join(blockTestDir, "bcWalletTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 5222b214b..5fdc6402e 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -86,7 +86,7 @@ type btTransaction struct { Value string } -func RunBlockTestWithReader(r io.Reader) error { +func RunBlockTestWithReader(r io.Reader, skipTests []string) error { btjs := make(map[string]*btJSON) if err := readJson(r, &btjs); err != nil { return err @@ -97,13 +97,13 @@ func RunBlockTestWithReader(r io.Reader) error { return err } - if err := runBlockTests(bt); err != nil { + if err := runBlockTests(bt, skipTests); err != nil { return err } return nil } -func RunBlockTest(file string) error { +func RunBlockTest(file string, skipTests []string) error { btjs := make(map[string]*btJSON) if err := readJsonFile(file, &btjs); err != nil { return err @@ -113,15 +113,15 @@ func RunBlockTest(file string) error { if err != nil { return err } - if err := runBlockTests(bt); err != nil { + if err := runBlockTests(bt, skipTests); err != nil { return err } return nil } -func runBlockTests(bt map[string]*BlockTest) error { - skipTest := make(map[string]bool, len(BlockSkipTests)) - for _, name := range BlockSkipTests { +func runBlockTests(bt map[string]*BlockTest, skipTests []string) error { + skipTest := make(map[string]bool, len(skipTests)) + for _, name := range skipTests { skipTest[name] = true } diff --git a/tests/state_test.go b/tests/state_test.go index 9c3d6f209..e58f588f4 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -8,84 +8,84 @@ import ( func TestStateSystemOperations(t *testing.T) { fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateExample(t *testing.T) { fn := filepath.Join(stateTestDir, "stExample.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStatePreCompiledContracts(t *testing.T) { fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateRecursiveCreate(t *testing.T) { fn := filepath.Join(stateTestDir, "stRecursiveCreate.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateSpecial(t *testing.T) { fn := filepath.Join(stateTestDir, "stSpecialTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateRefund(t *testing.T) { fn := filepath.Join(stateTestDir, "stRefundTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateBlockHash(t *testing.T) { fn := filepath.Join(stateTestDir, "stBlockHashTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateInitCode(t *testing.T) { fn := filepath.Join(stateTestDir, "stInitCodeTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateLog(t *testing.T) { fn := filepath.Join(stateTestDir, "stLogTests.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestStateTransaction(t *testing.T) { fn := filepath.Join(stateTestDir, "stTransactionTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestCallCreateCallCode(t *testing.T) { fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestMemory(t *testing.T) { fn := filepath.Join(stateTestDir, "stMemoryTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } @@ -95,7 +95,7 @@ func TestMemoryStress(t *testing.T) { t.Skip() } fn := filepath.Join(stateTestDir, "stMemoryStressTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } @@ -105,21 +105,21 @@ func TestQuadraticComplexity(t *testing.T) { t.Skip() } fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestSolidity(t *testing.T) { fn := filepath.Join(stateTestDir, "stSolidityTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } func TestWallet(t *testing.T) { fn := filepath.Join(stateTestDir, "stWalletTest.json") - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } @@ -127,7 +127,7 @@ func TestWallet(t *testing.T) { func TestStateTestsRandom(t *testing.T) { fns, _ := filepath.Glob("./files/StateTests/RandomTests/*") for _, fn := range fns { - if err := RunStateTest(fn); err != nil { + if err := RunStateTest(fn, StateSkipTests); err != nil { t.Error(err) } } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 577935dfa..e9abad788 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -16,26 +16,26 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" ) -func RunStateTestWithReader(r io.Reader) error { +func RunStateTestWithReader(r io.Reader, skipTests []string) error { tests := make(map[string]VmTest) if err := readJson(r, &tests); err != nil { return err } - if err := runStateTests(tests); err != nil { + if err := runStateTests(tests, skipTests); err != nil { return err } return nil } -func RunStateTest(p string) error { +func RunStateTest(p string, skipTests []string) error { tests := make(map[string]VmTest) if err := readJsonFile(p, &tests); err != nil { return err } - if err := runStateTests(tests); err != nil { + if err := runStateTests(tests, skipTests); err != nil { return err } @@ -43,9 +43,9 @@ func RunStateTest(p string) error { } -func runStateTests(tests map[string]VmTest) error { - skipTest := make(map[string]bool, len(StateSkipTests)) - for _, name := range StateSkipTests { +func runStateTests(tests map[string]VmTest, skipTests []string) error { + skipTest := make(map[string]bool, len(skipTests)) + for _, name := range skipTests { skipTest[name] = true } diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 41a20a1bb..70aa65cdd 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -6,21 +6,21 @@ import ( ) func TestTransactions(t *testing.T) { - err := RunTransactionTests(filepath.Join(transactionTestDir, "ttTransactionTest.json")) + err := RunTransactionTests(filepath.Join(transactionTestDir, "ttTransactionTest.json"), TransSkipTests) if err != nil { t.Fatal(err) } } func TestWrongRLPTransactions(t *testing.T) { - err := RunTransactionTests(filepath.Join(transactionTestDir, "ttWrongRLPTransaction.json")) + err := RunTransactionTests(filepath.Join(transactionTestDir, "ttWrongRLPTransaction.json"), TransSkipTests) if err != nil { t.Fatal(err) } } func Test10MBtx(t *testing.T) { - err := RunTransactionTests(filepath.Join(transactionTestDir, "tt10mbDataField.json")) + err := RunTransactionTests(filepath.Join(transactionTestDir, "tt10mbDataField.json"), TransSkipTests) if err != nil { t.Fatal(err) } diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index af33f2c58..45caf26fd 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -32,9 +32,9 @@ type TransactionTest struct { Transaction TtTransaction } -func RunTransactionTestsWithReader(r io.Reader) error { - skipTest := make(map[string]bool, len(TransSkipTests)) - for _, name := range TransSkipTests { +func RunTransactionTestsWithReader(r io.Reader, skipTests []string) error { + skipTest := make(map[string]bool, len(skipTests)) + for _, name := range skipTests { skipTest[name] = true } @@ -59,18 +59,25 @@ func RunTransactionTestsWithReader(r io.Reader) error { return nil } -func RunTransactionTests(file string) error { - skipTest := make(map[string]bool, len(TransSkipTests)) - for _, name := range TransSkipTests { - skipTest[name] = true - } - - bt := make(map[string]TransactionTest) - if err := readJsonFile(file, &bt); err != nil { +func RunTransactionTests(file string, skipTests []string) error { + tests := make(map[string]TransactionTest) + if err := readJsonFile(file, &tests); err != nil { return err } - for name, test := range bt { + if err := runTransactionTests(tests, skipTests); err != nil { + return err + } + return nil +} + +func runTransactionTests(tests map[string]TransactionTest, skipTests []string) error { + skipTest := make(map[string]bool, len(skipTests)) + for _, name := range skipTests { + skipTest[name] = true + } + + for name, test := range tests { // if the test should be skipped, return if skipTest[name] { glog.Infoln("Skipping transaction test", name) diff --git a/tests/vm_test.go b/tests/vm_test.go index d16d65aac..4e417da5a 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -8,91 +8,91 @@ import ( // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. func TestVMArithmetic(t *testing.T) { fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestBitwiseLogicOperation(t *testing.T) { fn := filepath.Join(vmTestDir, "vmBitwiseLogicOperationTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestBlockInfo(t *testing.T) { fn := filepath.Join(vmTestDir, "vmBlockInfoTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestEnvironmentalInfo(t *testing.T) { fn := filepath.Join(vmTestDir, "vmEnvironmentalInfoTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestFlowOperation(t *testing.T) { fn := filepath.Join(vmTestDir, "vmIOandFlowOperationsTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestLogTest(t *testing.T) { fn := filepath.Join(vmTestDir, "vmLogTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestPerformance(t *testing.T) { fn := filepath.Join(vmTestDir, "vmPerformanceTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestPushDupSwap(t *testing.T) { fn := filepath.Join(vmTestDir, "vmPushDupSwapTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestVMSha3(t *testing.T) { fn := filepath.Join(vmTestDir, "vmSha3Test.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestVm(t *testing.T) { fn := filepath.Join(vmTestDir, "vmtests.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestVmLog(t *testing.T) { fn := filepath.Join(vmTestDir, "vmLogTest.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestInputLimits(t *testing.T) { fn := filepath.Join(vmTestDir, "vmInputLimits.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } func TestInputLimitsLight(t *testing.T) { fn := filepath.Join(vmTestDir, "vmInputLimitsLight.json") - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } @@ -100,7 +100,7 @@ func TestInputLimitsLight(t *testing.T) { func TestVMRandom(t *testing.T) { fns, _ := filepath.Glob(filepath.Join(baseDir, "RandomTests", "*")) for _, fn := range fns { - if err := RunVmTest(fn); err != nil { + if err := RunVmTest(fn, VmSkipTests); err != nil { t.Error(err) } } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index afeedda2a..286991764 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -14,7 +14,7 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" ) -func RunVmTestWithReader(r io.Reader) error { +func RunVmTestWithReader(r io.Reader, skipTests []string) error { tests := make(map[string]VmTest) err := readJson(r, &tests) if err != nil { @@ -25,14 +25,14 @@ func RunVmTestWithReader(r io.Reader) error { return err } - if err := runVmTests(tests); err != nil { + if err := runVmTests(tests, skipTests); err != nil { return err } return nil } -func RunVmTest(p string) error { +func RunVmTest(p string, skipTests []string) error { tests := make(map[string]VmTest) err := readJsonFile(p, &tests) @@ -40,16 +40,16 @@ func RunVmTest(p string) error { return err } - if err := runVmTests(tests); err != nil { + if err := runVmTests(tests, skipTests); err != nil { return err } return nil } -func runVmTests(tests map[string]VmTest) error { - skipTest := make(map[string]bool, len(VmSkipTests)) - for _, name := range VmSkipTests { +func runVmTests(tests map[string]VmTest, skipTests []string) error { + skipTest := make(map[string]bool, len(skipTests)) + for _, name := range skipTests { skipTest[name] = true } From d1e589289c56140144241a245e1756dbdc7280a0 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 19 Jun 2015 15:08:53 +0200 Subject: [PATCH 073/110] Expand --test switch --- cmd/ethtest/main.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index c6073ce98..278d2133f 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -71,14 +71,14 @@ var ( func runTestWithReader(test string, r io.Reader) error { glog.Infoln("runTest", test) var err error - switch test { - case "bt", "BlockTest", "BlockTests", "BlockChainTest": + switch strings.ToLower(test) { + case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests": err = tests.RunBlockTestWithReader(r, skipTests) - case "st", "state", "StateTest", "StateTests": + case "st", "state", "statetest", "statetests": err = tests.RunStateTestWithReader(r, skipTests) - case "tx", "TransactionTest", "TransactionTests": + case "tx", "transactiontest", "transactiontests": err = tests.RunTransactionTestsWithReader(r, skipTests) - case "vm", "VMTest", "VMTests": + case "vm", "vmtest", "vmtests": err = tests.RunVmTestWithReader(r, skipTests) default: err = fmt.Errorf("Invalid test type specified: %v", test) From 8c4c7ea19207bf654d545273517b1319e1fc2269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 19 Jun 2015 16:46:16 +0300 Subject: [PATCH 074/110] eth/fetcher: lower max cache size, add timeout slack --- eth/fetcher/fetcher.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 98170cf79..b80182a45 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -3,6 +3,7 @@ package fetcher import ( "errors" + "fmt" "math/rand" "time" @@ -15,9 +16,10 @@ import ( const ( arriveTimeout = 500 * time.Millisecond // Time allowance before an announced block is explicitly requested + gatherSlack = 100 * time.Millisecond // Interval used to collate almost-expired announces with fetches fetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block maxUncleDist = 7 // Maximum allowed backward distance from the chain head - maxQueueDist = 256 // Maximum allowed distance from the chain head to queue + maxQueueDist = 32 // Maximum allowed distance from the chain head to queue ) var ( @@ -239,7 +241,7 @@ func (f *Fetcher) loop() { request := make(map[string][]common.Hash) for hash, announces := range f.announced { - if time.Since(announces[0].time) > arriveTimeout { + if time.Since(announces[0].time) > arriveTimeout-gatherSlack { announce := announces[rand.Intn(len(announces))] if f.getBlock(hash) == nil { request[announce.origin] = append(request[announce.origin], hash) @@ -249,7 +251,16 @@ func (f *Fetcher) loop() { } } // Send out all block requests - for _, hashes := range request { + for peer, hashes := range request { + if glog.V(logger.Detail) && len(hashes) > 0 { + list := "[" + for _, hash := range hashes { + list += fmt.Sprintf("%x, ", hash[:4]) + } + list = list[:len(list)-2] + "]" + + glog.V(logger.Detail).Infof("Peer %s: fetching %s", peer, list) + } go f.fetching[hashes[0]].fetch(hashes) } // Schedule the next fetch if blocks are still pending @@ -319,7 +330,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { // Discard any past or too distant blocks if dist := int64(block.NumberU64()) - int64(f.chainHeight()); dist < -maxUncleDist || dist > maxQueueDist { - glog.V(logger.Detail).Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) + glog.V(logger.Debug).Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) return } // Schedule the block for future importing From 53e042f0c47242afa3e13cfebb35becdacdc69c0 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 19 Jun 2015 18:49:15 +0200 Subject: [PATCH 075/110] Added link to ARM develop build --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index df335f242..a411d9eb8 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ The following builds are build automatically by our build servers after each pus [trusty](https://build.ethdev.com/builds/Linux%20Go%20develop%20deb%20i386-trusty/latest/) | [utopic](https://build.ethdev.com/builds/Linux%20Go%20develop%20deb%20i386-utopic/latest/) * [Windows 64-bit](https://build.ethdev.com/builds/Windows%20Go%20develop%20branch/Geth-Win64-latest.zip) +* [ARM](https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2) Building the source =================== From 42a14b8a09d812dbd7d1b05f145e6881376f320b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Jun 2015 14:37:00 +0200 Subject: [PATCH 076/110] mist: R.I.P. /"""""/""""""". / / \ __ / / \ || /____ / \ || | | In Loving | || | | Memory | || | | | || | | 2014-2015 | || | | * * * * | _||_ | | *\/* *\/* | | TT | | | *_\_ / ...""""""| || |.""....""""""""."" | | \/.."""""..."""\ || /.""".......""""... | |...."""""""........""""""^^^^"......."""""""".." |......"""""""""""""""........"""""...."""""..""-Jeff W. --- cmd/mist/assets/back.png | Bin 1004 -> 0 bytes cmd/mist/assets/backButton.png | Bin 663 -> 0 bytes cmd/mist/assets/backButton@2x.png | Bin 1499 -> 0 bytes cmd/mist/assets/backButtonDisabled.png | Bin 634 -> 0 bytes cmd/mist/assets/backButtonDisabled@2x.png | Bin 1458 -> 0 bytes cmd/mist/assets/backButtonHover.png | Bin 657 -> 0 bytes cmd/mist/assets/backButtonHover@2x.png | Bin 1517 -> 0 bytes cmd/mist/assets/browser.png | Bin 756 -> 0 bytes cmd/mist/assets/browser@2x.png | Bin 1603 -> 0 bytes cmd/mist/assets/bug.png | Bin 1671 -> 0 bytes cmd/mist/assets/close.png | Bin 905 -> 0 bytes cmd/mist/assets/debugger/debugger.qml | 436 - cmd/mist/assets/examples/abi.html | 55 - cmd/mist/assets/examples/balance.html | 40 - cmd/mist/assets/examples/bomb.html | 22 - cmd/mist/assets/examples/coin.html | 147 - cmd/mist/assets/examples/coin.js | 65 - cmd/mist/assets/examples/info.html | 84 - cmd/mist/assets/examples/whisper.html | 70 - cmd/mist/assets/ext/.bowerrc | 5 - cmd/mist/assets/ext/.editorconfig | 12 - cmd/mist/assets/ext/.gitignore | 18 - cmd/mist/assets/ext/.jshintrc | 50 - cmd/mist/assets/ext/.npmignore | 9 - cmd/mist/assets/ext/.travis.yml | 13 - cmd/mist/assets/ext/bignumber.min.js | 4 - cmd/mist/assets/ext/ethereum.js | 1 - cmd/mist/assets/ext/filter.js | 66 - cmd/mist/assets/ext/http.js | 30 - cmd/mist/assets/ext/mist.js | 36 - cmd/mist/assets/facet.png | Bin 27302 -> 0 bytes cmd/mist/assets/heart.png | Bin 4277 -> 0 bytes cmd/mist/assets/html/home.html | 83 - cmd/mist/assets/html/logo.png | Bin 12767 -> 0 bytes cmd/mist/assets/icecream.png | Bin 4643 -> 0 bytes cmd/mist/assets/mining-icon.png | Bin 1029 -> 0 bytes cmd/mist/assets/mining-icon@2x.png | Bin 2312 -> 0 bytes cmd/mist/assets/muted/codemirror.css | 272 - cmd/mist/assets/muted/debugger.html | 53 - cmd/mist/assets/muted/eclipse.css | 23 - cmd/mist/assets/muted/index.html | 80 - cmd/mist/assets/muted/lib/codemirror.js | 7526 ----------------- cmd/mist/assets/muted/lib/go.js | 182 - cmd/mist/assets/muted/lib/matchbrackets.js | 117 - cmd/mist/assets/muted/muted.js | 78 - cmd/mist/assets/net.png | Bin 4669 -> 0 bytes cmd/mist/assets/network.png | Bin 2900 -> 0 bytes cmd/mist/assets/new.png | Bin 4776 -> 0 bytes cmd/mist/assets/pick.png | Bin 932 -> 0 bytes cmd/mist/assets/qml/QmlApp.qml | 22 - cmd/mist/assets/qml/depricated_browser.qml | 486 -- cmd/mist/assets/qml/first_run.qml | 155 - .../assets/qml/fonts/Simple-Line-Icons.ttf | Bin 35304 -> 0 bytes .../assets/qml/fonts/SourceSansPro-Black.ttf | Bin 117460 -> 0 bytes .../qml/fonts/SourceSansPro-BlackIt.ttf | Bin 123840 -> 0 bytes .../assets/qml/fonts/SourceSansPro-Bold.ttf | Bin 119096 -> 0 bytes .../assets/qml/fonts/SourceSansPro-BoldIt.ttf | Bin 123756 -> 0 bytes .../qml/fonts/SourceSansPro-ExtraLight.ttf | Bin 120812 -> 0 bytes .../qml/fonts/SourceSansPro-ExtraLightIt.ttf | Bin 125720 -> 0 bytes .../assets/qml/fonts/SourceSansPro-It.ttf | Bin 124668 -> 0 bytes .../assets/qml/fonts/SourceSansPro-Light.ttf | Bin 121124 -> 0 bytes .../qml/fonts/SourceSansPro-LightIt.ttf | Bin 125480 -> 0 bytes .../qml/fonts/SourceSansPro-Regular.ttf | Bin 120672 -> 0 bytes .../qml/fonts/SourceSansPro-Semibold.ttf | Bin 120036 -> 0 bytes .../qml/fonts/SourceSansPro-SemiboldIt.ttf | Bin 123840 -> 0 bytes .../assets/qml/fonts/SourceSerifPro-Bold.ttf | Bin 113188 -> 0 bytes .../qml/fonts/SourceSerifPro-Regular.ttf | Bin 113640 -> 0 bytes .../qml/fonts/SourceSerifPro-Semibold.ttf | Bin 114352 -> 0 bytes cmd/mist/assets/qml/main.qml | 1030 --- cmd/mist/assets/qml/muted.qml | 74 - cmd/mist/assets/qml/test_app.qml | 70 - cmd/mist/assets/qml/transactions.qml | 9 - cmd/mist/assets/qml/views/browser.qml | 506 -- cmd/mist/assets/qml/views/catalog.qml | 144 - cmd/mist/assets/qml/views/chain.qml | 244 - cmd/mist/assets/qml/views/history.qml | 51 - cmd/mist/assets/qml/views/info.qml | 143 - cmd/mist/assets/qml/views/jeffcoin/jeff.png | Bin 84076 -> 0 bytes .../assets/qml/views/jeffcoin/jeffcoin.qml | 190 - cmd/mist/assets/qml/views/miner.qml | 283 - ...05f39107b64acf34cb35d7edb57f47893187a12.js | 176 - ...9f30ee0ee386c5143b4ccb62073179ca8253c3.css | 4 - .../dapp-styles/fonts/Montserrat-Black.otf | Bin 45336 -> 0 bytes .../dapp-styles/fonts/Montserrat-Bold.otf | Bin 45968 -> 0 bytes .../dapp-styles/fonts/Montserrat-Hairline.otf | Bin 44156 -> 0 bytes .../dapp-styles/fonts/Montserrat-Light.otf | Bin 44792 -> 0 bytes .../dapp-styles/fonts/Montserrat-Regular.otf | Bin 45360 -> 0 bytes .../fonts/SIL Open Font License.txt | 43 - .../dapp-styles/fonts/SourceSansPro-Black.otf | Bin 122372 -> 0 bytes .../fonts/SourceSansPro-BlackIt.otf | Bin 95056 -> 0 bytes .../dapp-styles/fonts/SourceSansPro-Bold.otf | Bin 129212 -> 0 bytes .../fonts/SourceSansPro-BoldIt.otf | Bin 100072 -> 0 bytes .../fonts/SourceSansPro-ExtraLight.otf | Bin 117832 -> 0 bytes .../fonts/SourceSansPro-ExtraLightIt.otf | Bin 90924 -> 0 bytes .../dapp-styles/fonts/SourceSansPro-It.otf | Bin 98820 -> 0 bytes .../dapp-styles/fonts/SourceSansPro-Light.otf | Bin 124476 -> 0 bytes .../fonts/SourceSansPro-LightIt.otf | Bin 95536 -> 0 bytes .../fonts/SourceSansPro-Regular.otf | Bin 127448 -> 0 bytes .../fonts/SourceSansPro-Semibold.otf | Bin 127336 -> 0 bytes .../fonts/SourceSansPro-SemiboldIt.otf | Bin 98352 -> 0 bytes .../qml/views/network-health/index.html | 30 - .../qml/views/network-health/loading.css | 92 - cmd/mist/assets/qml/views/network.qml | 159 - cmd/mist/assets/qml/views/pending_tx.qml | 53 - cmd/mist/assets/qml/views/transaction.qml | 216 - cmd/mist/assets/qml/views/wallet.qml | 190 - cmd/mist/assets/qml/views/whisper.qml | 74 - cmd/mist/assets/tx.png | Bin 4070 -> 0 bytes cmd/mist/assets/util/test.html | 43 - cmd/mist/assets/wallet.png | Bin 1114 -> 0 bytes cmd/mist/bindings.go | 92 - cmd/mist/errors.go | 56 - cmd/mist/gui.go | 462 - cmd/mist/html_container.go | 152 - cmd/mist/main.go | 142 - cmd/mist/qml_container.go | 82 - cmd/mist/ui_lib.go | 281 - ui/filter.go | 1 - ui/qt/filter.go | 1 - ui/qt/qwhisper/message.go | 23 - ui/qt/qwhisper/watch.go | 13 - ui/qt/qwhisper/whisper.go | 113 - ui/qt/qwhisper/whisper_test.go | 15 - ui/qt/webengine/all.cpp | 1 - ui/qt/webengine/cpp/webengine.cpp | 6 - ui/qt/webengine/cpp/webengine.h | 14 - ui/qt/webengine/webengine.go | 18 - 127 files changed, 15536 deletions(-) delete mode 100644 cmd/mist/assets/back.png delete mode 100644 cmd/mist/assets/backButton.png delete mode 100644 cmd/mist/assets/backButton@2x.png delete mode 100644 cmd/mist/assets/backButtonDisabled.png delete mode 100644 cmd/mist/assets/backButtonDisabled@2x.png delete mode 100644 cmd/mist/assets/backButtonHover.png delete mode 100644 cmd/mist/assets/backButtonHover@2x.png delete mode 100644 cmd/mist/assets/browser.png delete mode 100644 cmd/mist/assets/browser@2x.png delete mode 100644 cmd/mist/assets/bug.png delete mode 100644 cmd/mist/assets/close.png delete mode 100644 cmd/mist/assets/debugger/debugger.qml delete mode 100644 cmd/mist/assets/examples/abi.html delete mode 100644 cmd/mist/assets/examples/balance.html delete mode 100644 cmd/mist/assets/examples/bomb.html delete mode 100644 cmd/mist/assets/examples/coin.html delete mode 100644 cmd/mist/assets/examples/coin.js delete mode 100644 cmd/mist/assets/examples/info.html delete mode 100644 cmd/mist/assets/examples/whisper.html delete mode 100644 cmd/mist/assets/ext/.bowerrc delete mode 100644 cmd/mist/assets/ext/.editorconfig delete mode 100644 cmd/mist/assets/ext/.gitignore delete mode 100644 cmd/mist/assets/ext/.jshintrc delete mode 100644 cmd/mist/assets/ext/.npmignore delete mode 100644 cmd/mist/assets/ext/.travis.yml delete mode 100644 cmd/mist/assets/ext/bignumber.min.js delete mode 160000 cmd/mist/assets/ext/ethereum.js delete mode 100644 cmd/mist/assets/ext/filter.js delete mode 100644 cmd/mist/assets/ext/http.js delete mode 100644 cmd/mist/assets/ext/mist.js delete mode 100644 cmd/mist/assets/facet.png delete mode 100644 cmd/mist/assets/heart.png delete mode 100644 cmd/mist/assets/html/home.html delete mode 100644 cmd/mist/assets/html/logo.png delete mode 100644 cmd/mist/assets/icecream.png delete mode 100644 cmd/mist/assets/mining-icon.png delete mode 100644 cmd/mist/assets/mining-icon@2x.png delete mode 100644 cmd/mist/assets/muted/codemirror.css delete mode 100644 cmd/mist/assets/muted/debugger.html delete mode 100644 cmd/mist/assets/muted/eclipse.css delete mode 100644 cmd/mist/assets/muted/index.html delete mode 100644 cmd/mist/assets/muted/lib/codemirror.js delete mode 100644 cmd/mist/assets/muted/lib/go.js delete mode 100644 cmd/mist/assets/muted/lib/matchbrackets.js delete mode 100644 cmd/mist/assets/muted/muted.js delete mode 100644 cmd/mist/assets/net.png delete mode 100644 cmd/mist/assets/network.png delete mode 100644 cmd/mist/assets/new.png delete mode 100644 cmd/mist/assets/pick.png delete mode 100644 cmd/mist/assets/qml/QmlApp.qml delete mode 100644 cmd/mist/assets/qml/depricated_browser.qml delete mode 100644 cmd/mist/assets/qml/first_run.qml delete mode 100755 cmd/mist/assets/qml/fonts/Simple-Line-Icons.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-Black.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-BlackIt.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-Bold.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-BoldIt.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLight.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLightIt.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-It.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-Light.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-LightIt.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-Regular.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-Semibold.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSansPro-SemiboldIt.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSerifPro-Bold.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSerifPro-Regular.ttf delete mode 100644 cmd/mist/assets/qml/fonts/SourceSerifPro-Semibold.ttf delete mode 100644 cmd/mist/assets/qml/main.qml delete mode 100644 cmd/mist/assets/qml/muted.qml delete mode 100644 cmd/mist/assets/qml/test_app.qml delete mode 100644 cmd/mist/assets/qml/transactions.qml delete mode 100644 cmd/mist/assets/qml/views/browser.qml delete mode 100644 cmd/mist/assets/qml/views/catalog.qml delete mode 100644 cmd/mist/assets/qml/views/chain.qml delete mode 100644 cmd/mist/assets/qml/views/history.qml delete mode 100644 cmd/mist/assets/qml/views/info.qml delete mode 100644 cmd/mist/assets/qml/views/jeffcoin/jeff.png delete mode 100644 cmd/mist/assets/qml/views/jeffcoin/jeffcoin.qml delete mode 100644 cmd/mist/assets/qml/views/miner.qml delete mode 100644 cmd/mist/assets/qml/views/network-health/205f39107b64acf34cb35d7edb57f47893187a12.js delete mode 100644 cmd/mist/assets/qml/views/network-health/529f30ee0ee386c5143b4ccb62073179ca8253c3.css delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Black.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Bold.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Hairline.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Light.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Regular.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SIL Open Font License.txt delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Black.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-BlackIt.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Bold.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-BoldIt.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-ExtraLight.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-ExtraLightIt.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-It.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Light.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-LightIt.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Regular.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Semibold.otf delete mode 100644 cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-SemiboldIt.otf delete mode 100755 cmd/mist/assets/qml/views/network-health/index.html delete mode 100644 cmd/mist/assets/qml/views/network-health/loading.css delete mode 100644 cmd/mist/assets/qml/views/network.qml delete mode 100644 cmd/mist/assets/qml/views/pending_tx.qml delete mode 100644 cmd/mist/assets/qml/views/transaction.qml delete mode 100644 cmd/mist/assets/qml/views/wallet.qml delete mode 100644 cmd/mist/assets/qml/views/whisper.qml delete mode 100644 cmd/mist/assets/tx.png delete mode 100644 cmd/mist/assets/util/test.html delete mode 100644 cmd/mist/assets/wallet.png delete mode 100644 cmd/mist/bindings.go delete mode 100644 cmd/mist/errors.go delete mode 100644 cmd/mist/gui.go delete mode 100644 cmd/mist/html_container.go delete mode 100644 cmd/mist/main.go delete mode 100644 cmd/mist/qml_container.go delete mode 100644 cmd/mist/ui_lib.go delete mode 100644 ui/filter.go delete mode 100644 ui/qt/filter.go delete mode 100644 ui/qt/qwhisper/message.go delete mode 100644 ui/qt/qwhisper/watch.go delete mode 100644 ui/qt/qwhisper/whisper.go delete mode 100644 ui/qt/qwhisper/whisper_test.go delete mode 100644 ui/qt/webengine/all.cpp delete mode 100644 ui/qt/webengine/cpp/webengine.cpp delete mode 100644 ui/qt/webengine/cpp/webengine.h delete mode 100644 ui/qt/webengine/webengine.go diff --git a/cmd/mist/assets/back.png b/cmd/mist/assets/back.png deleted file mode 100644 index 38fc84d6ea9203583110c91f2eaf7610061dbbb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1004 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 U7^JihtN;K207*qoM6N<$f+Jcd2><{9 diff --git a/cmd/mist/assets/backButtonDisabled@2x.png b/cmd/mist/assets/backButtonDisabled@2x.png deleted file mode 100644 index 0eaa6daa5e2bbf73f7f34e9d34efeaaa719981e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1458 zcmV;j1x@;iP)Px)Y)M2xRA>e5m`!XOMHI*P!;WJ+aa}tfj_ovY2t1c+3{xM`ENX#+(T0z{g)SsR*?C{7Brq=Blc07IM)d-%Wg zPUHiMch|c}NPg1no42z&@3(Jf-p;HbG^7!MMg$rW_MR zN$))iigK?cNfU6=BrrCyUMM`dXWza*_1;g{nR+Tc4i;u+ZjnXt7_M!i>zOEqWrxFX zKx_e=otg^Ck~A)eqF;R&#+J*);zRv=_x_>U1`d`3=5jf2vml%TLl1EvWPb&s(bs*! z;IaX(txKh?ngx|)GAXw(_6eW{wC*+oU0o@_1!3=JjH$2Nh$~A0Z%ZWJ5k>J~4gj!G zUwiwHn%xR*cnn$wxR}kp47lexoTs(*vtT50L9=P>4WoUHx9ioG0OqsVr{VlH?zGA6 zp6rapzSV4kA~?engzm3Tx*|9? zJ$(~=9tW9=e2bFwbGW~MOpv6q#&Qa9i(1{3G95vDzB(kvPQz<}JOkuq z@OX#nm9dgP5;^MGv13J}xCA|_)$3O3z&6qgRwr*Gaxe0Gkn2W}PQKUd-=N<|^oqQ_ zUTx?VBi9|QhC{A9TLnj}6iO$S!O_F%e#MKq+!F}*8$2RTmunii?ih+StF^6rA5+)f3+(M;l{jp{QMOpp;0Bzhg#@uN~QxhL&U!yI<+w9P_0R`b8mg}qB`Hhv8 z2g~KM4EqA$&hqniXbnS)XjGm`X1c=zsOI7i=IYV%>HjbF@Uy2!R#bODl6fJ{Q2qq@`WE_C+vq;Rr8 zHUPU_PUlJ5a*}PO=mylBo`IgHy4&Zw77T@sqPj^oAP2DJJVIMfvaJ$BfQTZtA3_R6 z-GtMYlD3u{2JMdwBoc3N+X`(6kQ@SH1Bw=`>dJ+-mbC1mHWEn`U%;~LrHWPm(J&yn z1SE~UVHEY7Ov^5OU8bpx1nqC;6@~I=-C_!myaIw|aS}!S+=b)u3H-gH*-j!MlEaIN za(l%ze>4q9E&)mT@Fdk~`31-^Xv&+^=)uVoKPXDCYMVUN1xP*tsX%>2bu7bHL$Mgm zY;}BMW_P;q8%|LaKed~Yx&g^4Aisc8H%{1k-e`+PX{M{6N9db#M8Rt`-XW2L}hYR_4^EM=S>}VpwbeBnm*zLecEz(uT+y{zuJk zwoL=-QIw}pYVN^pgV?TPfZ;bHvt_Jr=eN<;h(IF(jR-U%@E=9sA0t?4q9Ts}%>V!Z M07*qoM6N<$f;hmh*8l(j diff --git a/cmd/mist/assets/backButtonHover.png b/cmd/mist/assets/backButtonHover.png deleted file mode 100644 index 8c5226f5a2b59ee83e8bc95ec5a062521892f792..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 657 zcmV;C0&e|@P)Px%OG!jQR7eeDU>F62LLkE5-xjEb5tlkZz;0x_tBI8Ek5p zunA%l0~%(-z{IqOi<|r0``^FkVN(MVW5FeXEFSLVrN+R_ype;0<7MBpX$*Y){60XJ zu0>V@V-qwm)YDUxnT>5bGc)u5maeW>K*P=gHE)6$fKKD}a;T*xCkq?fW(Gz^$+Fto zyHc{U_kjkK0$ukT-5?krpMgv)Vq(jHnoUzPGcW4s>%RwTDgg37!!(mbNBR3tj0y<& zzjXfm^d<9VyFrC^9usH>~DEN z!G(YS{+$B4EEGc#9svv&GBYw}0o5~wMMtv(U9|*=SL4x-A%&5JZd|?UH>Iy{<=3xY z|9<)URd@B~&7hbi8eq6kT}#Uim_%;<`St5J3lr0}C~t2;qD=!T#4r#jRxK+pf2W|b z@+Q!`ivL+z*N19rvk_}3hJipsJ_0ot7@3%Sib+g7&+z}h9gC{!T(S)WX#^Vj7)X_R z`uY8Ja&@87KAtSs)=uU@JC`S;I#)uv7R(bd8D1Puf!1R7cmOh$qEX=%dWzkU_?`{$3< z%B@?m<{X?}hS>x8o-W#e=A00000NkvXXu0mjfb?Yrw diff --git a/cmd/mist/assets/backButtonHover@2x.png b/cmd/mist/assets/backButtonHover@2x.png deleted file mode 100644 index 406601ebc562a63c6a1480b8589b1ebda9855a02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1517 zcmVPx)r%6OXRA>e5n14)LRTRhDzP7gAO34OJ$_P`LZb)#0ZDMdxM(7fLz2edg&@3TN zgQF8fyM+e_mp?D zWMOGv`x^I0PjcV6=biiR`Sjd(@4L4OMO300h-M&~frw^68PVR+c|~dIlM1CW*E2o+ ztlRBgkQy(dfaNxu1p&^XXazwyHzNr4uCA_YQXo}Q8cS(w=lN8XAbdh_^c=K#etsTG zny95U53aSnu<#y@QrU~vvGfG8_xBC2x3I6T?`m*8+-xN~pw((!q0wqTLx^Mw!>LrW z&pDl^w`65`luF47RLDBScJQp$>pQ`fL2!_Tn)>=-z-6I+44E|e?@GAHnn4ZEzm6GO z#Nt=%*>mxc?CcrQj)#_PaoX7Z{M_N6BNOXGrtrqIpw!@4!G^;-x~gD(Xn9 z)lN0LT%$2DF+Q>(?*Q)XQZ@8zNPs0JB?cYGbtCM(6k4TH%^hrRzMNn-dqtE!z`Z5b z!&0FDs*D_W3Q@O-k$u&*wL=?HQ|CncN9Z=O9=4J^iz|5kRYc`kWP4@hKz2?JTRsMH z--+x=-nFp)Zq8uZEG!-L5Lei2yD(divS=96 zp=TTpw${<`68tFh%cT)Buv8QmKdR)oukoeOQR_8k^X2xAj#129TI*=mz6iK)$tSl2 z%plgf6o7RxxRplZc#F$5F2WJd(MZ8j=K%q+)|~`g95p7XJ#b($#$;k^-MfH0v*d}) zHSi?y`RXx_Yza}kcj82n*XyNMgFbJ^BZGCb*MNYhdV0=3ym@m29-;S5F+4bEY;SF) zopKA=krpmc0BkbXK9-y7L_5uI7cQ8n{gsJ{Ri`^U)xY%je--HYaQy)@hycwfvAfF4 z$F^H6V=N%XxB;iOr6kQygk-om?Fk=OGyQ)F>bCE-FeRI}#EQkb(lj4fPt;^#;RYlgl-x)9L;p8_pP& zTHX8j&YcNA0|zPc%Oa8iDJmeZK-Hr7_kMe8YNj@(r45mf zM5R=|g6)}Y$qMfp)OPE3A@G%(sp`$fyo3Zs$!MW8eraG2`G*JhpH4)GEeAjJe^7t~3rn_^>qO>J!+ zwOZ}}lM=o)7@}T`Hf=6KlCS|ODnQsq_@R(l9X(K$k;q0)3$7c2=cAg>qR_2 zKy|+e!Uns=vXYs>YS{oOARwoq>QJW0exj=CYR1;BmpHZh?85kX-bZe?+|^t{0GeF{m|?zv)p6L-jg+hECN7&M!f|^pe-8UwxHgKB3U8=NECql z5{k0OWF0cAXT}|)0o8zV1jYX!;vECVKmf*}MC4s(F`_z}foKMz8Hi@!f6Tyt(OPuo TI$X5q00000NkvXXu0mjfzx3i{ diff --git a/cmd/mist/assets/browser.png b/cmd/mist/assets/browser.png deleted file mode 100644 index 074c9ae3cf6ee974ee1e28cd7e203c711f792461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 756 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 B;2{72 diff --git a/cmd/mist/assets/close.png b/cmd/mist/assets/close.png deleted file mode 100644 index 88df442c5c3e31aafb95e16c363f08a89de0f29a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 905 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM%9|WRD45bDP46hOx7_4S6Fo+k-*%fF5l;AAz zh%9Dc;1&j9Muu5)B!GrRW`;zRMELqxCFkerC8p#jrRr7W764TzCHb_`sNdc^+B->Ug!Z$#{Ilm}X!Bo#g&p^qJOF==wrYI%ND#*nR zsvXF)RmvzSDX`MlFE20GD>v55FG|-pw6wI;H!#vSGSUUA&@HaaD@m--%_~-h7y>iL zCAB!YD6^m>Ge1uOWNuW^rA6E#WYIKx_J=?u2N z+Gk8%19Q?N!w!lslXh{j-}YK|oA2ckuH7tu+g35=JvRTg$$sc(0pt|;;-PO{+JgfH|EO*WgDT=;%Af^Ati{|DM@uy3C zzrWkl!h7RDuAhTh@1hrWeUHO$a82H)@Sjn2*>2W1P8VNB9hi5aEKs~-t41QLWW--) zmu1Tjre8ie=k03u3HP#gNAGyX8N+GeVJT!bE1OC8D{5=%I>U7>KUIb WGK;!D`Q1fO8uxVdb6Mw<&;$UMO-b7T diff --git a/cmd/mist/assets/debugger/debugger.qml b/cmd/mist/assets/debugger/debugger.qml deleted file mode 100644 index 5566e8fca..000000000 --- a/cmd/mist/assets/debugger/debugger.qml +++ /dev/null @@ -1,436 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -ApplicationWindow { - id: win - visible: false - title: "IceCREAM" - minimumWidth: 1280 - minimumHeight: 700 - width: 1290 - height: 750 - - property alias codeText: codeEditor.text - property alias dataText: rawDataField.text - - onClosing: { - //dbg.Stop() - } - - menuBar: MenuBar { - Menu { - title: "Edit" - MenuItem { - text: "Focus code" - shortcut: "Ctrl+1" - onTriggered: { - codeEditor.focus = true - } - } - MenuItem { - text: "Focus data" - shortcut: "Ctrl+2" - onTriggered: { - rawDataField.focus = true - } - } - - MenuItem { - text: "Command" - shortcut: "Ctrl+l" - onTriggered: { - dbgCommand.focus = true - } - } - } - - Menu { - title: "Debugger" - MenuItem { - text: "Run" - shortcut: "Ctrl+r" - onTriggered: debugCurrent() - } - - MenuItem { - text: "Stop" - onTriggered: dbp.stop() - } - - MenuSeparator {} - - MenuItem { - text: "Next" - shortcut: "Ctrl+n" - onTriggered: dbg.next() - } - - MenuItem { - text: "Continue" - shortcut: "Ctrl+g" - onTriggered: dbg.continue() - } - } - } - - - SplitView { - anchors.fill: parent - property var asmModel: ListModel { - id: asmModel - } - - TableView { - id: asmTableView - width: 200 - headerVisible: false - TableViewColumn{ role: "value" ; title: "" ; width: asmTableView.width - 2 } - model: asmModel - /* - alternatingRowColors: false - itemDelegate: Item { - Rectangle { - anchors.fill: parent - color: "#DDD" - Text { - anchors { - left: parent.left - right: parent.right - leftMargin: 10 - verticalCenter: parent.verticalCenter - } - color: "#333" - elide: styleData.elideMode - text: styleData.value - font.pixelSize: 11 - MouseArea { - acceptedButtons: Qt.LeftButton - anchors.fill: parent - onClicked: { - mouse.accepted = true - } - } - } - } - } - */ - } - - Rectangle { - color: "#00000000" - anchors.left: asmTableView.right - anchors.right: parent.right - SplitView { - orientation: Qt.Vertical - anchors.fill: parent - - Rectangle { - color: "#00000000" - height: 330 - anchors.left: parent.left - anchors.right: parent.right - - TextArea { - id: codeEditor - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: settings.left - focus: true - - /* - Timer { - id: compileTimer - interval: 500 ; running: true ; repeat: true - onTriggered: { - dbg.autoComp(codeEditor.text) - } - } - */ - } - - Column { - id: settings - spacing: 5 - width: 300 - height: parent.height - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - - Label { - text: "Arbitrary data" - } - TextArea { - id: rawDataField - anchors.left: parent.left - anchors.right: parent.right - height: 150 - } - - Label { - text: "Amount" - } - TextField { - id: txValue - width: 200 - placeholderText: "Amount" - validator: RegExpValidator { regExp: /\d*/ } - } - Label { - text: "Amount of gas" - } - TextField { - id: txGas - width: 200 - validator: RegExpValidator { regExp: /\d*/ } - text: "10000" - placeholderText: "Gas" - } - Label { - text: "Gas price" - } - TextField { - id: txGasPrice - width: 200 - placeholderText: "Gas price" - text: "1000000000000" - validator: RegExpValidator { regExp: /\d*/ } - } - } - } - - SplitView { - orientation: Qt.Vertical - id: inspectorPane - height: 500 - - SplitView { - orientation: Qt.Horizontal - height: 150 - - TableView { - id: stackTableView - property var stackModel: ListModel { - id: stackModel - } - height: parent.height - width: 300 - TableViewColumn{ role: "value" ; title: "Local VM stack" ; width: stackTableView.width - 2 } - model: stackModel - } - - TableView { - id: memoryTableView - property var memModel: ListModel { - id: memModel - } - height: parent.height - width: parent.width - stackTableView.width - TableViewColumn{ id:mnumColmn ; role: "num" ; title: "#" ; width: 50 } - TableViewColumn{ role: "value" ; title: "Memory" ; width: 650 } - model: memModel - } - } - - Rectangle { - height: 100 - width: parent.width - TableView { - id: storageTableView - property var memModel: ListModel { - id: storageModel - } - height: parent.height - width: parent.width - TableViewColumn{ id: key ; role: "key" ; title: "#" ; width: storageTableView.width / 2 - 1} - TableViewColumn{ role: "value" ; title: "Storage" ; width: storageTableView.width / 2 - 1} - model: storageModel - } - } - - Rectangle { - height: 200 - width: parent.width * 0.66 - TableView { - id: logTableView - property var logModel: ListModel { - id: logModel - } - height: parent.height - width: parent.width - TableViewColumn{ id: message ; role: "message" ; title: "log" ; width: logTableView.width - 2 } - model: logModel - } - } - - } - } - } - } - - function exec() { - dbg.execCommand(dbgCommand.text); - dbgCommand.text = ""; - } - statusBar: StatusBar { - height: 30 - - - TextField { - id: dbgCommand - y: 1 - x: asmTableView.width - width: 500 - placeholderText: "Debugger (type 'help')" - Keys.onReturnPressed: { - exec() - } - } - - RowLayout { - anchors.left: dbgCommand.right - anchors.leftMargin: 10 - spacing: 5 - y: parent.height / 2 - this.height / 2 - - Text { - objectName: "stackFrame" - font.pixelSize: 10 - text: "stack ptr: 0" - } - - Text { - objectName: "stackSize" - font.pixelSize: 10 - text: "stack size: 0" - } - - Text { - objectName: "memSize" - font.pixelSize: 10 - text: "mem size: 0" - } - } - } - - toolBar: ToolBar { - height: 30 - RowLayout { - spacing: 10 - - Button { - property var enabled: true - id: debugStart - onClicked: { - debugCurrent() - } - text: "Debug" - } - - Button { - property var enabled: true - id: debugNextButton - onClicked: { - dbg.next() - } - text: "Next" - } - - Button { - id: debugContinueButton - onClicked: { - dbg.continue() - } - text: "Continue" - } - } - - - ComboBox { - visible: false - id: snippets - anchors.right: parent.right - model: ListModel { - ListElement { text: "Snippets" ; value: "" } - ListElement { text: "Call Contract" ; value: "var[2] in = { \"arg1\", 0xdeadbeef };\nvar ret;\n\nvar success = call(0x0c542ddea93dae0c2fcb2cf175f03ad80d6be9a0, 0, 7000, in, ret)\n\nreturn ret" } - } - onCurrentIndexChanged: { - if(currentIndex != 0) { - var code = snippets.model.get(currentIndex).value; - codeEditor.insert(codeEditor.cursorPosition, code) - } - } - } - - } - - function debugCurrent() { - dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text, rawDataField.text) - } - - function setAsm(asm) { - asmModel.append({asm: asm}) - } - - function clearAsm() { - asmModel.clear() - } - - function setInstruction(num) { - asmTableView.selection.clear() - asmTableView.selection.select(num) - asmTableView.positionViewAtRow(num, ListView.Center) - } - - function setMem(mem) { - memModel.append({num: mem.num, value: mem.value}) - } - function clearMem(){ - memModel.clear() - } - - function setStack(stack) { - stackModel.append({value: stack}) - } - function addDebugMessage(message){ - debuggerLog.append({value: message}) - } - - function clearStack() { - stackModel.clear() - } - - function clearStorage() { - storageModel.clear() - } - - function setStorage(storage) { - storageModel.append({key: storage.key, value: storage.value}) - } - - function setLog(msg) { - // Remove first item once we've reached max log items - if(logModel.count > 250) { - logModel.remove(0) - } - - if(msg.len != 0) { - if(logTableView.flickableItem.atYEnd) { - logModel.append({message: msg}) - logTableView.positionViewAtRow(logTableView.rowCount - 1, ListView.Contain) - } else { - logModel.append({message: msg}) - } - } - } - - function clearLog() { - logModel.clear() - } -} diff --git a/cmd/mist/assets/examples/abi.html b/cmd/mist/assets/examples/abi.html deleted file mode 100644 index 8170e88b0..000000000 --- a/cmd/mist/assets/examples/abi.html +++ /dev/null @@ -1,55 +0,0 @@ - - - -Hello world - - - - - -

Contract content

- -
-603880600c6000396000f3006001600060e060020a600035048063c6888fa1140
-05b6021600435602b565b8060005260206000f35b600081600702905091905056
- -
-
7 x = - - - - diff --git a/cmd/mist/assets/examples/balance.html b/cmd/mist/assets/examples/balance.html deleted file mode 100644 index bc483a879..000000000 --- a/cmd/mist/assets/examples/balance.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - -

coinbase balance

- -
-
-
-
- - - - diff --git a/cmd/mist/assets/examples/bomb.html b/cmd/mist/assets/examples/bomb.html deleted file mode 100644 index 62540f9bb..000000000 --- a/cmd/mist/assets/examples/bomb.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html deleted file mode 100644 index 4fe8e7fa2..000000000 --- a/cmd/mist/assets/examples/coin.html +++ /dev/null @@ -1,147 +0,0 @@ - - -JevCoin - - - - - - -

JevCoin

-
- Balance - -
- -
- Address: - - Amount: - - - -
- -
- - - - -
AddressBalance
- - - - - - - diff --git a/cmd/mist/assets/examples/coin.js b/cmd/mist/assets/examples/coin.js deleted file mode 100644 index 77daac846..000000000 --- a/cmd/mist/assets/examples/coin.js +++ /dev/null @@ -1,65 +0,0 @@ -var walletABI = [ - { - "name":"confirm", - "type":"function", - "constant":false, - "inputs":[ - {"name":"_h","type":"hash256"} - ], - "outputs":[] - },{ - "name":"execute", - "constant":false, - "type":"function", - "inputs":[ - {"name":"_to","type":"address"}, - {"name":"_value","type":"uint256"}, - {"name":"_data","type":"bytes"} - ], - "outputs":[ - {"name":"_r","type":"hash256"} - ] - },{ - "name":"kill", - "type":"function", - "constant":false, - "inputs":[ - {"name":"_to","type":"address"} - ], - "outputs":[] - },{ - "name":"changeOwner", - "type":"function", - "constant":false, - "inputs":[ - {"name":"_from","type":"address"}, - {"name":"_to","type":"address"} - ], - "outputs":[] - },{ - "name":"CashIn", - "type":"event", - "inputs":[ - {"indexed":false,"name":"value","type":"uint256"} - ] - },{ - "name":"SingleTransact", - "type":"event", - "inputs":[ - {"indexed":true,"name":"out","type":"string32"}, - {"indexed":false,"name":"owner","type":"address"}, - {"indexed":false,"name":"value","type":"uint256"}, - {"indexed":false,"name":"to","type":"address"} - ] - },{ - "name":"MultiTransact", - "type":"event", - "inputs":[ - {"indexed":true,"name":"out","type":"string32"}, - {"indexed":false,"name":"owner","type":"address"}, - {"indexed":false,"name":"operation","type":"hash256"}, - {"indexed":false,"name":"value","type":"uint256"}, - {"indexed":false,"name":"to","type":"address"} - ] - } -]; diff --git a/cmd/mist/assets/examples/info.html b/cmd/mist/assets/examples/info.html deleted file mode 100644 index 3b958a494..000000000 --- a/cmd/mist/assets/examples/info.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - -

Info

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Block number
Peer count
Default block
Accounts
Balance
Gas price
Mining
Listening
Coinbase
- - - - - - diff --git a/cmd/mist/assets/examples/whisper.html b/cmd/mist/assets/examples/whisper.html deleted file mode 100644 index ad568f783..000000000 --- a/cmd/mist/assets/examples/whisper.html +++ /dev/null @@ -1,70 +0,0 @@ - - -Whisper test - - - - - - -

Whisper test

- - - - - - - - - - - - - - - - - - - -
Count
ID
Has identity
- - - - - - - diff --git a/cmd/mist/assets/ext/.bowerrc b/cmd/mist/assets/ext/.bowerrc deleted file mode 100644 index c3a8813e8..000000000 --- a/cmd/mist/assets/ext/.bowerrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "directory": "example/js/", - "cwd": "./", - "analytics": false -} \ No newline at end of file diff --git a/cmd/mist/assets/ext/.editorconfig b/cmd/mist/assets/ext/.editorconfig deleted file mode 100644 index 60a2751d3..000000000 --- a/cmd/mist/assets/ext/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 4 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -trim_trailing_whitespace = false \ No newline at end of file diff --git a/cmd/mist/assets/ext/.gitignore b/cmd/mist/assets/ext/.gitignore deleted file mode 100644 index 399b6dc88..000000000 --- a/cmd/mist/assets/ext/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile ~/.gitignore_global - -*.swp -/tmp -*/**/*un~ -*un~ -.DS_Store -*/**/.DS_Store -ethereum/ethereum -ethereal/ethereal -example/js -node_modules -bower_components -npm-debug.log diff --git a/cmd/mist/assets/ext/.jshintrc b/cmd/mist/assets/ext/.jshintrc deleted file mode 100644 index c0ec5f89d..000000000 --- a/cmd/mist/assets/ext/.jshintrc +++ /dev/null @@ -1,50 +0,0 @@ -{ - "predef": [ - "console", - "require", - "equal", - "test", - "testBoth", - "testWithDefault", - "raises", - "deepEqual", - "start", - "stop", - "ok", - "strictEqual", - "module", - "expect", - "reject", - "impl" - ], - - "esnext": true, - "proto": true, - "node" : true, - "browser" : true, - "browserify" : true, - - "boss" : true, - "curly": false, - "debug": true, - "devel": true, - "eqeqeq": true, - "evil": true, - "forin": false, - "immed": false, - "laxbreak": false, - "newcap": true, - "noarg": true, - "noempty": false, - "nonew": false, - "nomen": false, - "onevar": false, - "plusplus": false, - "regexp": false, - "undef": true, - "sub": true, - "strict": false, - "white": false, - "shadow": true, - "eqnull": true -} \ No newline at end of file diff --git a/cmd/mist/assets/ext/.npmignore b/cmd/mist/assets/ext/.npmignore deleted file mode 100644 index 5bbffe4fd..000000000 --- a/cmd/mist/assets/ext/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -example/js -node_modules -test -.gitignore -.editorconfig -.travis.yml -.npmignore -component.json -testling.html \ No newline at end of file diff --git a/cmd/mist/assets/ext/.travis.yml b/cmd/mist/assets/ext/.travis.yml deleted file mode 100644 index 83b21d840..000000000 --- a/cmd/mist/assets/ext/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: node_js -node_js: - - "0.11" - - "0.10" -before_script: - - npm install - - npm install jshint -script: - - "jshint *.js lib" -after_script: - - npm run-script build - - npm test - diff --git a/cmd/mist/assets/ext/bignumber.min.js b/cmd/mist/assets/ext/bignumber.min.js deleted file mode 100644 index 7b63a8a02..000000000 --- a/cmd/mist/assets/ext/bignumber.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/* bignumber.js v2.0.3 https://github.com/MikeMcl/bignumber.js/LICENCE */ -/* modified by zelig to fix https://github.com/robertkrimen/otto#regular-expression-incompatibility */ -!function(e){"use strict";function n(e){function a(e,n){var t,r,i,o,u,s,f=this;if(!(f instanceof a))return j&&L(26,"constructor call without new",e),new a(e,n);if(null!=n&&H(n,2,64,M,"base")){if(n=0|n,s=e+"",10==n)return f=new a(e instanceof a?e:s),U(f,P+f.e+1,k);if((o="number"==typeof e)&&0*e!=0||!new RegExp("^-?"+(t="["+O.slice(0,n)+"]+")+"(?:\\."+t+")?$",37>n?"i":"").test(s))return g(f,s,o,n);o?(f.s=0>1/e?(s=s.slice(1),-1):1,j&&s.replace(/^0\.0*|\./,"").length>15&&L(M,b,e),o=!1):f.s=45===s.charCodeAt(0)?(s=s.slice(1),-1):1,s=D(s,10,n,f.s)}else{if(e instanceof a)return f.s=e.s,f.e=e.e,f.c=(e=e.c)?e.slice():e,void(M=0);if((o="number"==typeof e)&&0*e==0){if(f.s=0>1/e?(e=-e,-1):1,e===~~e){for(r=0,i=e;i>=10;i/=10,r++);return f.e=r,f.c=[e],void(M=0)}s=e+""}else{if(!p.test(s=e+""))return g(f,s,o);f.s=45===s.charCodeAt(0)?(s=s.slice(1),-1):1}}for((r=s.indexOf("."))>-1&&(s=s.replace(".","")),(i=s.search(/e/i))>0?(0>r&&(r=i),r+=+s.slice(i+1),s=s.substring(0,i)):0>r&&(r=s.length),i=0;48===s.charCodeAt(i);i++);for(u=s.length;48===s.charCodeAt(--u););if(s=s.slice(i,u+1))if(u=s.length,o&&j&&u>15&&L(M,b,f.s*e),r=r-i-1,r>z)f.c=f.e=null;else if(G>r)f.c=[f.e=0];else{if(f.e=r,f.c=[],i=(r+1)%y,0>r&&(i+=y),u>i){for(i&&f.c.push(+s.slice(0,i)),u-=y;u>i;)f.c.push(+s.slice(i,i+=y));s=s.slice(i),i=y-s.length}else i-=u;for(;i--;s+="0");f.c.push(+s)}else f.c=[f.e=0];M=0}function D(e,n,t,i){var o,u,f,c,h,g,p,d=e.indexOf("."),m=P,w=k;for(37>t&&(e=e.toLowerCase()),d>=0&&(f=J,J=0,e=e.replace(".",""),p=new a(t),h=p.pow(e.length-d),J=f,p.c=s(l(r(h.c),h.e),10,n),p.e=p.c.length),g=s(e,t,n),u=f=g.length;0==g[--f];g.pop());if(!g[0])return"0";if(0>d?--u:(h.c=g,h.e=u,h.s=i,h=C(h,p,m,w,n),g=h.c,c=h.r,u=h.e),o=u+m+1,d=g[o],f=n/2,c=c||0>o||null!=g[o+1],c=4>w?(null!=d||c)&&(0==w||w==(h.s<0?3:2)):d>f||d==f&&(4==w||c||6==w&&1&g[o-1]||w==(h.s<0?8:7)),1>o||!g[0])e=c?l("1",-m):"0";else{if(g.length=o,c)for(--n;++g[--o]>n;)g[o]=0,o||(++u,g.unshift(1));for(f=g.length;!g[--f];);for(d=0,e="";f>=d;e+=O.charAt(g[d++]));e=l(e,u)}return e}function _(e,n,t,i){var o,u,s,c,h;if(t=null!=t&&H(t,0,8,i,v)?0|t:k,!e.c)return e.toString();if(o=e.c[0],s=e.e,null==n)h=r(e.c),h=19==i||24==i&&B>=s?f(h,s):l(h,s);else if(e=U(new a(e),n,t),u=e.e,h=r(e.c),c=h.length,19==i||24==i&&(u>=n||B>=u)){for(;n>c;h+="0",c++);h=f(h,u)}else if(n-=s,h=l(h,u),u+1>c){if(--n>0)for(h+=".";n--;h+="0");}else if(n+=u-c,n>0)for(u+1==c&&(h+=".");n--;h+="0");return e.s<0&&o?"-"+h:h}function x(e,n){var t,r,i=0;for(u(e[0])&&(e=e[0]),t=new a(e[0]);++ie||e>t||e!=c(e))&&L(r,(i||"decimal places")+(n>e||e>t?" out of range":" not an integer"),e),!0}function I(e,n,t){for(var r=1,i=n.length;!n[--i];n.pop());for(i=n[0];i>=10;i/=10,r++);return(t=r+t*y-1)>z?e.c=e.e=null:G>t?e.c=[e.e=0]:(e.e=t,e.c=n),e}function L(e,n,t){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][e]+"() "+n+": "+t);throw r.name="BigNumber Error",M=0,r}function U(e,n,t,r){var i,o,u,s,f,l,c,a=e.c,h=R;if(a){e:{for(i=1,s=a[0];s>=10;s/=10,i++);if(o=n-i,0>o)o+=y,u=n,f=a[l=0],c=f/h[i-u-1]%10|0;else if(l=d((o+1)/y),l>=a.length){if(!r)break e;for(;a.length<=l;a.push(0));f=c=0,i=1,o%=y,u=o-y+1}else{for(f=s=a[l],i=1;s>=10;s/=10,i++);o%=y,u=o-y+i,c=0>u?0:f/h[i-u-1]%10|0}if(r=r||0>n||null!=a[l+1]||(0>u?f:f%h[i-u-1]),r=4>t?(c||r)&&(0==t||t==(e.s<0?3:2)):c>5||5==c&&(4==t||r||6==t&&(o>0?u>0?f/h[i-u]:0:a[l-1])%10&1||t==(e.s<0?8:7)),1>n||!a[0])return a.length=0,r?(n-=e.e+1,a[0]=h[n%y],e.e=-n||0):a[0]=e.e=0,e;if(0==o?(a.length=l,s=1,l--):(a.length=l+1,s=h[y-o],a[l]=u>0?m(f/h[i-u]%h[u])*s:0),r)for(;;){if(0==l){for(o=1,u=a[0];u>=10;u/=10,o++);for(u=a[0]+=s,s=1;u>=10;u/=10,s++);o!=s&&(e.e++,a[0]==N&&(a[0]=1));break}if(a[l]+=s,a[l]!=N)break;a[l--]=0,s=1}for(o=a.length;0===a[--o];a.pop());}e.e>z?e.c=e.e=null:e.et?null!=(e=i[t++]):void 0};return f(n="DECIMAL_PLACES")&&H(e,0,E,2,n)&&(P=0|e),r[n]=P,f(n="ROUNDING_MODE")&&H(e,0,8,2,n)&&(k=0|e),r[n]=k,f(n="EXPONENTIAL_AT")&&(u(e)?H(e[0],-E,0,2,n)&&H(e[1],0,E,2,n)&&(B=0|e[0],$=0|e[1]):H(e,-E,E,2,n)&&(B=-($=0|(0>e?-e:e)))),r[n]=[B,$],f(n="RANGE")&&(u(e)?H(e[0],-E,-1,2,n)&&H(e[1],1,E,2,n)&&(G=0|e[0],z=0|e[1]):H(e,-E,E,2,n)&&(0|e?G=-(z=0|(0>e?-e:e)):j&&L(2,n+" cannot be zero",e))),r[n]=[G,z],f(n="ERRORS")&&(e===!!e||1===e||0===e?(M=0,H=(j=!!e)?F:o):j&&L(2,n+w,e)),r[n]=j,f(n="CRYPTO")&&(e===!!e||1===e||0===e?(V=!(!e||!h||"object"!=typeof h),e&&!V&&j&&L(2,"crypto unavailable",h)):j&&L(2,n+w,e)),r[n]=V,f(n="MODULO_MODE")&&H(e,0,9,2,n)&&(W=0|e),r[n]=W,f(n="POW_PRECISION")&&H(e,0,E,2,n)&&(J=0|e),r[n]=J,f(n="FORMAT")&&("object"==typeof e?X=e:j&&L(2,n+" not an object",e)),r[n]=X,r},a.max=function(){return x(arguments,T.lt)},a.min=function(){return x(arguments,T.gt)},a.random=function(){var e=9007199254740992,n=Math.random()*e&2097151?function(){return m(Math.random()*e)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(e){var t,r,i,o,u,s=0,f=[],l=new a(q);if(e=null!=e&&H(e,0,E,14)?0|e:P,o=d(e/y),V)if(h&&h.getRandomValues){for(t=h.getRandomValues(new Uint32Array(o*=2));o>s;)u=131072*t[s]+(t[s+1]>>>11),u>=9e15?(r=h.getRandomValues(new Uint32Array(2)),t[s]=r[0],t[s+1]=r[1]):(f.push(u%1e14),s+=2);s=o/2}else if(h&&h.randomBytes){for(t=h.randomBytes(o*=7);o>s;)u=281474976710656*(31&t[s])+1099511627776*t[s+1]+4294967296*t[s+2]+16777216*t[s+3]+(t[s+4]<<16)+(t[s+5]<<8)+t[s+6],u>=9e15?h.randomBytes(7).copy(t,s):(f.push(u%1e14),s+=7);s=o/7}else j&&L(14,"crypto unavailable",h);if(!s)for(;o>s;)u=n(),9e15>u&&(f[s++]=u%1e14);for(o=f[--s],e%=y,o&&e&&(u=R[y-e],f[s]=m(o/u)*u);0===f[s];f.pop(),s--);if(0>s)f=[i=0];else{for(i=-1;0===f[0];f.shift(),i-=y);for(s=1,u=f[0];u>=10;u/=10,s++);y>s&&(i-=y-s)}return l.e=i,l.c=f,l}}(),C=function(){function e(e,n,t){var r,i,o,u,s=0,f=e.length,l=n%A,c=n/A|0;for(e=e.slice();f--;)o=e[f]%A,u=e[f]/A|0,r=c*o+u*l,i=l*o+r%A*A+s,s=(i/t|0)+(r/A|0)+c*u,e[f]=i%t;return s&&e.unshift(s),e}function n(e,n,t,r){var i,o;if(t!=r)o=t>r?1:-1;else for(i=o=0;t>i;i++)if(e[i]!=n[i]){o=e[i]>n[i]?1:-1;break}return o}function r(e,n,t,r){for(var i=0;t--;)e[t]-=i,i=e[t]1;e.shift());}return function(i,o,u,s,f){var l,c,h,g,p,d,w,v,b,O,S,R,A,E,D,_,x,F=i.s==o.s?1:-1,I=i.c,L=o.c;if(!(I&&I[0]&&L&&L[0]))return new a(i.s&&o.s&&(I?!L||I[0]!=L[0]:L)?I&&0==I[0]||!L?0*F:F/0:0/0);for(v=new a(F),b=v.c=[],c=i.e-o.e,F=u+c+1,f||(f=N,c=t(i.e/y)-t(o.e/y),F=F/y|0),h=0;L[h]==(I[h]||0);h++);if(L[h]>(I[h]||0)&&c--,0>F)b.push(1),g=!0;else{for(E=I.length,_=L.length,h=0,F+=2,p=m(f/(L[0]+1)),p>1&&(L=e(L,p,f),I=e(I,p,f),_=L.length,E=I.length),A=_,O=I.slice(0,_),S=O.length;_>S;O[S++]=0);x=L.slice(),x.unshift(0),D=L[0],L[1]>=f/2&&D++;do p=0,l=n(L,O,_,S),0>l?(R=O[0],_!=S&&(R=R*f+(O[1]||0)),p=m(R/D),p>1?(p>=f&&(p=f-1),d=e(L,p,f),w=d.length,S=O.length,l=n(d,O,w,S),1==l&&(p--,r(d,w>_?x:L,w,f))):(0==p&&(l=p=1),d=L.slice()),w=d.length,S>w&&d.unshift(0),r(O,d,S,f),-1==l&&(S=O.length,l=n(L,O,_,S),1>l&&(p++,r(O,S>_?x:L,S,f))),S=O.length):0===l&&(p++,O=[0]),b[h++]=p,l&&O[0]?O[S++]=I[A]||0:(O=[I[A]],S=1);while((A++=10;F/=10,h++);U(v,u+(v.e=h+c*y-1)+1,s,g)}else v.e=c,v.r=+g;return v}}(),g=function(){var e=/^(-?)0([xbo])(\w[\w.]*$)/i,n=/^([^.]+)\.$/,t=/^\.([^.]+)$/,r=/^-?(Infinity|NaN)$/,i=/^\s*\+([\w.])|^\s+|\s+$/g;return function(o,u,s,f){var l,c=s?u:u.replace(i,"$1");if(r.test(c))o.s=isNaN(c)?null:0>c?-1:1;else{if(!s&&(c=c.replace(e,function(e,n,t){return l="x"==(t=t.toLowerCase())?16:"b"==t?2:8,f&&f!=l?e:n}),f&&(l=f,c=c.replace(n,"$1").replace(t,"0.$1")),u!=c))return new a(c,l);j&&L(M,"not a"+(f?" base "+f:"")+" number",u),o.s=null}o.c=o.e=null,M=0}}(),T.absoluteValue=T.abs=function(){var e=new a(this);return e.s<0&&(e.s=1),e},T.ceil=function(){return U(new a(this),this.e+1,2)},T.comparedTo=T.cmp=function(e,n){return M=1,i(this,new a(e,n))},T.decimalPlaces=T.dp=function(){var e,n,r=this.c;if(!r)return null;if(e=((n=r.length-1)-t(this.e/y))*y,n=r[n])for(;n%10==0;n/=10,e--);return 0>e&&(e=0),e},T.dividedBy=T.div=function(e,n){return M=3,C(this,new a(e,n),P,k)},T.dividedToIntegerBy=T.divToInt=function(e,n){return M=4,C(this,new a(e,n),0,1)},T.equals=T.eq=function(e,n){return M=5,0===i(this,new a(e,n))},T.floor=function(){return U(new a(this),this.e+1,3)},T.greaterThan=T.gt=function(e,n){return M=6,i(this,new a(e,n))>0},T.greaterThanOrEqualTo=T.gte=function(e,n){return M=7,1===(n=i(this,new a(e,n)))||0===n},T.isFinite=function(){return!!this.c},T.isInteger=T.isInt=function(){return!!this.c&&t(this.e/y)>this.c.length-2},T.isNaN=function(){return!this.s},T.isNegative=T.isNeg=function(){return this.s<0},T.isZero=function(){return!!this.c&&0==this.c[0]},T.lessThan=T.lt=function(e,n){return M=8,i(this,new a(e,n))<0},T.lessThanOrEqualTo=T.lte=function(e,n){return M=9,-1===(n=i(this,new a(e,n)))||0===n},T.minus=T.sub=function(e,n){var r,i,o,u,s=this,f=s.s;if(M=10,e=new a(e,n),n=e.s,!f||!n)return new a(0/0);if(f!=n)return e.s=-n,s.plus(e);var l=s.e/y,c=e.e/y,h=s.c,g=e.c;if(!l||!c){if(!h||!g)return h?(e.s=-n,e):new a(g?s:0/0);if(!h[0]||!g[0])return g[0]?(e.s=-n,e):new a(h[0]?s:3==k?-0:0)}if(l=t(l),c=t(c),h=h.slice(),f=l-c){for((u=0>f)?(f=-f,o=h):(c=l,o=g),o.reverse(),n=f;n--;o.push(0));o.reverse()}else for(i=(u=(f=h.length)<(n=g.length))?f:n,f=n=0;i>n;n++)if(h[n]!=g[n]){u=h[n]0)for(;n--;h[r++]=0);for(n=N-1;i>f;){if(h[--i]0?(s=u,r=l):(o=-o,r=f),r.reverse();o--;r.push(0));r.reverse()}for(o=f.length,n=l.length,0>o-n&&(r=l,l=f,f=r,n=o),o=0;n;)o=(f[--n]=f[n]+l[n]+o)/N|0,f[n]%=N;return o&&(f.unshift(o),++s),I(e,f,s)},T.precision=T.sd=function(e){var n,t,r=this,i=r.c;if(null!=e&&e!==!!e&&1!==e&&0!==e&&(j&&L(13,"argument"+w,e),e!=!!e&&(e=null)),!i)return null;if(t=i.length-1,n=t*y+1,t=i[t]){for(;t%10==0;t/=10,n--);for(t=i[0];t>=10;t/=10,n++);}return e&&r.e+1>n&&(n=r.e+1),n},T.round=function(e,n){var t=new a(this);return(null==e||H(e,0,E,15))&&U(t,~~e+this.e+1,null!=n&&H(n,0,8,15,v)?0|n:k),t},T.shift=function(e){var n=this;return H(e,-S,S,16,"argument")?n.times("1e"+c(e)):new a(n.c&&n.c[0]&&(-S>e||e>S)?n.s*(0>e?0:1/0):n)},T.squareRoot=T.sqrt=function(){var e,n,i,o,u,s=this,f=s.c,l=s.s,c=s.e,h=P+4,g=new a("0.5");if(1!==l||!f||!f[0])return new a(!l||0>l&&(!f||f[0])?0/0:f?s:1/0);if(l=Math.sqrt(+s),0==l||l==1/0?(n=r(f),(n.length+c)%2==0&&(n+="0"),l=Math.sqrt(n),c=t((c+1)/2)-(0>c||c%2),l==1/0?n="1e"+c:(n=l.toExponential(),n=n.slice(0,n.indexOf("e")+1)+c),i=new a(n)):i=new a(l+""),i.c[0])for(c=i.e,l=c+h,3>l&&(l=0);;)if(u=i,i=g.times(u.plus(C(s,u,h,1))),r(u.c).slice(0,l)===(n=r(i.c)).slice(0,l)){if(i.el&&(m=O,O=S,S=m,o=l,l=g,g=o),o=l+g,m=[];o--;m.push(0));for(w=N,v=A,o=g;--o>=0;){for(r=0,p=S[o]%v,d=S[o]/v|0,s=l,u=o+s;u>o;)c=O[--s]%v,h=O[s]/v|0,f=d*c+h*p,c=p*c+f%v*v+m[u]+r,r=(c/w|0)+(f/v|0)+d*h,m[u--]=c%w;m[u]=r}return r?++i:m.shift(),I(e,m,i)},T.toDigits=function(e,n){var t=new a(this);return e=null!=e&&H(e,1,E,18,"precision")?0|e:null,n=null!=n&&H(n,0,8,18,v)?0|n:k,e?U(t,e,n):t},T.toExponential=function(e,n){return _(this,null!=e&&H(e,0,E,19)?~~e+1:null,n,19)},T.toFixed=function(e,n){return _(this,null!=e&&H(e,0,E,20)?~~e+this.e+1:null,n,20)},T.toFormat=function(e,n){var t=_(this,null!=e&&H(e,0,E,21)?~~e+this.e+1:null,n,21);if(this.c){var r,i=t.split("."),o=+X.groupSize,u=+X.secondaryGroupSize,s=X.groupSeparator,f=i[0],l=i[1],c=this.s<0,a=c?f.slice(1):f,h=a.length;if(u&&(r=o,o=u,u=r,h-=r),o>0&&h>0){for(r=h%o||o,f=a.substr(0,r);h>r;r+=o)f+=s+a.substr(r,o);u>0&&(f+=s+a.slice(r)),c&&(f="-"+f)}t=l?f+X.decimalSeparator+((u=+X.fractionGroupSize)?l.replace(new RegExp("\\d{"+u+"}\\B","g"),"$&"+X.fractionGroupSeparator):l):f}return t},T.toFraction=function(e){var n,t,i,o,u,s,f,l,c,h=j,g=this,p=g.c,d=new a(q),m=t=new a(q),w=f=new a(q);if(null!=e&&(j=!1,s=new a(e),j=h,(!(h=s.isInt())||s.lt(q))&&(j&&L(22,"max denominator "+(h?"out of range":"not an integer"),e),e=!h&&s.c&&U(s,s.e+1,1).gte(q)?s:null)),!p)return g.toString();for(c=r(p),o=d.e=c.length-g.e-1,d.c[0]=R[(u=o%y)<0?y+u:u],e=!e||s.cmp(d)>0?o>0?d:m:s,u=z,z=1/0,s=new a(c),f.c[0]=0;l=C(s,d,0,1),i=t.plus(l.times(w)),1!=i.cmp(e);)t=w,w=i,m=f.plus(l.times(i=m)),f=i,d=s.minus(l.times(i=d)),s=i;return i=C(e.minus(t),w,0,1),f=f.plus(i.times(m)),t=t.plus(i.times(w)),f.s=m.s=g.s,o*=2,n=C(m,w,o,k).minus(g).abs().cmp(C(f,t,o,k).minus(g).abs())<1?[m.toString(),w.toString()]:[f.toString(),t.toString()],z=u,n},T.toNumber=function(){var e=this;return+e||(e.s?0*e.s:0/0)},T.toPower=T.pow=function(e){var n,t,r=m(0>e?-e:+e),i=this;if(!H(e,-S,S,23,"exponent")&&(!isFinite(e)||r>S&&(e/=0)||parseFloat(e)!=e&&!(e=0/0)))return new a(Math.pow(+i,e));for(n=J?d(J/y+2):0,t=new a(q);;){if(r%2){if(t=t.times(i),!t.c)break;n&&t.c.length>n&&(t.c.length=n)}if(r=m(r/2),!r)break;i=i.times(i),n&&i.c&&i.c.length>n&&(i.c.length=n)}return 0>e&&(t=q.div(t)),n?U(t,J,k):t},T.toPrecision=function(e,n){return _(this,null!=e&&H(e,1,E,24,"precision")?0|e:null,n,24)},T.toString=function(e){var n,t=this,i=t.s,o=t.e;return null===o?i?(n="Infinity",0>i&&(n="-"+n)):n="NaN":(n=r(t.c),n=null!=e&&H(e,2,64,25,"base")?D(l(n,o),0|e,10,i):B>=o||o>=$?f(n,o):l(n,o),0>i&&t.c[0]&&(n="-"+n)),n},T.truncated=T.trunc=function(){return U(new a(this),this.e+1,1)},T.valueOf=T.toJSON=function(){return this.toString()},null!=e&&a.config(e),a}function t(e){var n=0|e;return e>0||e===n?n:n-1}function r(e){for(var n,t,r=1,i=e.length,o=e[0]+"";i>r;){for(n=e[r++]+"",t=y-n.length;t--;n="0"+n);o+=n}for(i=o.length;48===o.charCodeAt(--i););return o.slice(0,i+1||1)}function i(e,n){var t,r,i=e.c,o=n.c,u=e.s,s=n.s,f=e.e,l=n.e;if(!u||!s)return null;if(t=i&&!i[0],r=o&&!o[0],t||r)return t?r?0:-s:u;if(u!=s)return u;if(t=0>u,r=f==l,!i||!o)return r?0:!i^t?1:-1;if(!r)return f>l^t?1:-1;for(s=(f=i.length)<(l=o.length)?f:l,u=0;s>u;u++)if(i[u]!=o[u])return i[u]>o[u]^t?1:-1;return f==l?0:f>l^t?1:-1}function o(e,n,t){return(e=c(e))>=n&&t>=e}function u(e){return"[object Array]"==Object.prototype.toString.call(e)}function s(e,n,t){for(var r,i,o=[0],u=0,s=e.length;s>u;){for(i=o.length;i--;o[i]*=n);for(o[r=0]+=O.indexOf(e.charAt(u++));rt-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/t|0,o[r]%=t)}return o.reverse()}function f(e,n){return(e.length>1?e.charAt(0)+"."+e.slice(1):e)+(0>n?"e":"e+")+n}function l(e,n){var t,r;if(0>n){for(r="0.";++n;r+="0");e=r+e}else if(t=e.length,++n>t){for(r="0",n-=t;--n;r+="0");e+=r}else t>n&&(e=e.slice(0,n)+"."+e.slice(n));return e}function c(e){return e=parseFloat(e),0>e?d(e):m(e)}var a,h,g,p=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,d=Math.ceil,m=Math.floor,w=" not a boolean or binary digit",v="rounding mode",b="number type has more than 15 significant digits",O="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",N=1e14,y=14,S=9007199254740991,R=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],A=1e7,E=1e9;if(a=n(),"function"==typeof define&&define.amd)define(function(){return a});else if("undefined"!=typeof module&&module.exports){if(module.exports=a,!h)try{h=require("crypto")}catch(D){}}else e.BigNumber=a}(this); -//# sourceMappingURL=doc/bignumber.js.map \ No newline at end of file diff --git a/cmd/mist/assets/ext/ethereum.js b/cmd/mist/assets/ext/ethereum.js deleted file mode 160000 index 08f3aaea8..000000000 --- a/cmd/mist/assets/ext/ethereum.js +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 08f3aaea8cad2cf07276d6709e2ee384afe90d3c diff --git a/cmd/mist/assets/ext/filter.js b/cmd/mist/assets/ext/filter.js deleted file mode 100644 index f8529c54b..000000000 --- a/cmd/mist/assets/ext/filter.js +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301 USA - -var ethx = { - prototype: Object, - - watch: function(options) { - return new Filter(options); - }, - - note: function() { - var args = Array.prototype.slice.call(arguments, 0); - var o = [] - for(var i = 0; i < args.length; i++) { - o.push(args[i].toString()) - } - - eth.notef(o); - }, -}; - -var Filter = function(options) { - this.callbacks = []; - this.options = options; - - if(options === "chain") { - this.id = eth.newFilterString(options); - } else if(typeof options === "object") { - this.id = eth.newFilter(options); - } -}; - -Filter.prototype.changed = function(callback) { - this.callbacks.push(callback); - - var self = this; - messages.connect(function(messages, id) { - if(id == self.id) { - for(var i = 0; i < self.callbacks.length; i++) { - self.callbacks[i].call(self, messages); - } - } - }); -}; - -Filter.prototype.uninstall = function() { - eth.uninstallFilter(this.id) -} - -Filter.prototype.messages = function() { - return eth.messages(this.id) -} diff --git a/cmd/mist/assets/ext/http.js b/cmd/mist/assets/ext/http.js deleted file mode 100644 index 81908266f..000000000 --- a/cmd/mist/assets/ext/http.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301 USA - -// this function is included locally, but you can also include separately via a header definition -function request(url, callback) { - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = (function(req) { - return function() { - if(req.readyState === 4) { - callback(req); - } - } - })(xhr); - xhr.open('GET', url, true); - xhr.send(''); -} diff --git a/cmd/mist/assets/ext/mist.js b/cmd/mist/assets/ext/mist.js deleted file mode 100644 index 849e0804e..000000000 --- a/cmd/mist/assets/ext/mist.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2015, ETHDEV. All rights reserved. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301 USA - -// this function is included locally, but you can also include separately via a header definition - - -document.onkeydown = function(evt) { - // This functions keeps track of keyboard inputs in order to allow copy, paste and other features - - evt = evt || window.event; - if (evt.ctrlKey && evt.keyCode == 67) { - window.document.execCommand("copy"); - } else if (evt.ctrlKey && evt.keyCode == 88) { - window.document.execCommand("cut"); - } else if (evt.ctrlKey && evt.keyCode == 86) { - window.document.execCommand("paste"); - } else if (evt.ctrlKey && evt.keyCode == 90) { - window.document.execCommand("undo"); - } else if (evt.ctrlKey && evt.shiftKey && evt.keyCode == 90) { - window.document.execCommand("redo"); - } -}; \ No newline at end of file diff --git a/cmd/mist/assets/facet.png b/cmd/mist/assets/facet.png deleted file mode 100644 index 49a266e96a6c0322cfa927698b10efd35b97fa05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27302 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 R{2>4=4K-cW!fRGf{|D(@9S8sb diff --git a/cmd/mist/assets/heart.png b/cmd/mist/assets/heart.png deleted file mode 100644 index 3c874ab7f36da5f25e7295ee5572738941dfe2e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4277 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 - - -Ethereum - - - - - - -

Info

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Block number
Peer count
Accounts
Gas price
Mining
Listening
Coinbase
- - - - - - diff --git a/cmd/mist/assets/html/logo.png b/cmd/mist/assets/html/logo.png deleted file mode 100644 index 28dc9f509ed67bdedf60d48ed04e98dfbdd9c0a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12767 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 QZ(;)=BdH)!B?b!kKSFr8a{vGU diff --git a/cmd/mist/assets/icecream.png b/cmd/mist/assets/icecream.png deleted file mode 100644 index 2438ca845b9fcf9228fd36333b305ed3da85f5ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4643 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 diff --git a/cmd/mist/assets/mining-icon@2x.png b/cmd/mist/assets/mining-icon@2x.png deleted file mode 100644 index 16466d338c5829f10b8cc3971e7446e821e14075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2312 zcmV+j3HSDiP)Px-!bwCyRA>e58VhVw*Y(_IJ0TxJ2qB3bSjQShps*DPtfhlc%9@21!lZ6vkqSd% zlQwm$CUu!uHLcRRm2TZ8SS$Kr1vR6kz-U7tEP@cqCnJ!=d`hxF2!((hha^s7$FXDk z-JSCsM~3*>@7Zp;Nq&<3?mPF~bI&>V-t&78Ab!O)5Z6Fl191&Rt^pSL(C{N0z>v%V zrfWge0|*8jK|i`o0HVnQf*Bd;C;*eg2af%J%mq9H*;&aTlmHV-81Q8rSSJ8CGe$yj z{L#e>oRhFjk2pDqa}u~%;R5f$N1)5%!->s*%mi!%{X&5We?lP^qA*pW2o)m0!EmcX zt1JMl5dUzFvd@UDE{tY=)4jMt(c54g8umn%wRD>?u)b%F(HaXh!)ZG(bhj74c&-Vuogg@ zE*Q20XNx)au3P|}ccWoKZfq0eOl3@S3>ZJ>6-_^lWM|;^S9etbBu-`qE8{S~i+h%Q zUcwPqM4RTot)Ho7hT}B1I&M{B(-|=`!)c>nco&C8wE8Ni^rJJJb0==u0opx&V9f6q z1j7y#@Bk7XPvQJ>Fch!>1%1a4P;ytiMaiI`rCij-z0V?H^xxxtaSQhr(zz#IVmdpy z0=>ipwG{3i`Jmj0VFj+raxR$z}{FC;sJNkHuAk=d&fe; zo~4lprP9lJUbv`aEO{SfFMuXLGyj`uE0@2ZosyB#f4FArmCx#rd=Fq)ZcHdR`AH39 zZ5Z*ajymGGz;bKQ>23%$VW_?a$ewp&^@g22yFTo6_w;hF!@>LZR`#^7-B_-4n+2m! zJQ-Q;@nC(5VH7x{)$Awtpm@*-B5L_d*H%2U#q!$rHrLJD{Qk>z>kha4VOwkKqiZ(T zL+%vy^vPxA_ML^SY_(%Y@r_{Egsx%FC_q7jn7z7a)z3|3FB=_~TkeVO{XvvC!rji`RGjxa<@A>2t%P$8(P` zp&mT;L2ljiaZh{658pcvhFN1N2Zs=E#AEQ@Fi<+k6gkj64C-ii%j{)WZ71s7q8Ck4 z1ef#bb>2L4$w;X^ghyF7p#?S#6H$vA%bA#;r?DM9<-Pmbo8s`TJF<-3-yu4N zp#Q*Ov3q;DJK-x2D7LJ`8zs~jbxgmXrvF)1Kn`B?SN;s#j~@D-ykOpt{^hd7wAJ4d z`t~1&{)%c4hlXSa;Ua_MoDsU;*abprs-WMpS(jS)s9knI&<<|)l|+Je$_K6-1iiq( ztR^UPUTW@hHeZDabG`}*4?Y0)+B)cdeHWyzTnfqa=ib8st?u;6S1F^;q4!Q-oJlfweCN(ulHX^e;agJ;fz{p48yr;~xe5;Op*%4Ula3r+A3)cU~Y*-P8(r|RA0-#i00ZrxYOyZ-t% zA8NfW*;MbKgS+qcNNv|=9sKU=J9+Q!1KeZnlVF6`GV?Lz)(K_w`9edfoVcS@+)~(9v?V#%CeNW4+u7*nDSIRQh$F_NjIvltR7ppydM zwxV@^>)!Fc*?+EvO`W{^t#aP8^F!(U(K+n<=m@v``7Q3a)GVDn>Add#XIJ}E&+br@ zFGdxr5#Nyn+b^MQyqr0A`OWn|tG3miaZ*ew1=aOU-16!hlF=DBdXjrxE(vb0YjEG% z_>0;r(+Y}fL+q#kJ&rb`4z{C7m(D^)T5CbkbLJOcz3gne;ae%2oey_*No^@z`u*0{ z|2*>4uj(KzW0Y%!4az(yl_MS%4hfDHZNl3KQ}b}^z1>^Bzsu7*;d_Y}wLwTos{hYr!;pdnc2cnwv*(M|kew0;AI~<;O+3WB@aq=>w*{5% z&*O90v+Exd!#l&dKT=z|S2aHw3v~XrFX-jVyC~pkwS_6wD^Z27u=LDOgPQ50_Y_57 z8C0bumB_R$vzX=tGMaDVrp#3UE;S@%gKaq?G=Z0!9>+|&H;ZZOKF{|RM4RToxh`6{ zX|h`3OwsE23dmlp&{6rrU;RRXu_QuO14^vJt#TmEcss6v ixCY`Hh-+XxHSk|nY+^_(vZJ#A0000

-
-
- > -
-
-
-
-
- - - diff --git a/cmd/mist/assets/muted/eclipse.css b/cmd/mist/assets/muted/eclipse.css deleted file mode 100644 index 317218e3d..000000000 --- a/cmd/mist/assets/muted/eclipse.css +++ /dev/null @@ -1,23 +0,0 @@ -.cm-s-eclipse span.cm-meta {color: #FF1717;} -.cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; } -.cm-s-eclipse span.cm-atom {color: #219;} -.cm-s-eclipse span.cm-number {color: #164;} -.cm-s-eclipse span.cm-def {color: #00f;} -.cm-s-eclipse span.cm-variable {color: black;} -.cm-s-eclipse span.cm-variable-2 {color: #0000C0;} -.cm-s-eclipse span.cm-variable-3 {color: #0000C0;} -.cm-s-eclipse span.cm-property {color: black;} -.cm-s-eclipse span.cm-operator {color: black;} -.cm-s-eclipse span.cm-comment {color: #3F7F5F;} -.cm-s-eclipse span.cm-string {color: #2A00FF;} -.cm-s-eclipse span.cm-string-2 {color: #f50;} -.cm-s-eclipse span.cm-qualifier {color: #555;} -.cm-s-eclipse span.cm-builtin {color: #30a;} -.cm-s-eclipse span.cm-bracket {color: #cc7;} -.cm-s-eclipse span.cm-tag {color: #170;} -.cm-s-eclipse span.cm-attribute {color: #00c;} -.cm-s-eclipse span.cm-link {color: #219;} -.cm-s-eclipse span.cm-error {color: #f00;} - -.cm-s-eclipse .CodeMirror-activeline-background {background: #e8f2ff !important;} -.cm-s-eclipse .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;} diff --git a/cmd/mist/assets/muted/index.html b/cmd/mist/assets/muted/index.html deleted file mode 100644 index 14949b5ac..000000000 --- a/cmd/mist/assets/muted/index.html +++ /dev/null @@ -1,80 +0,0 @@ - - - -Mutan Editor - - - - - - - - - - - - - -
-
-
- > -
-
-
-
-
- - - - diff --git a/cmd/mist/assets/muted/lib/codemirror.js b/cmd/mist/assets/muted/lib/codemirror.js deleted file mode 100644 index 0ab217711..000000000 --- a/cmd/mist/assets/muted/lib/codemirror.js +++ /dev/null @@ -1,7526 +0,0 @@ -// This is CodeMirror (http://codemirror.net), a code editor -// implemented in JavaScript on top of the browser's DOM. -// -// You can find some technical background for some of the code below -// at http://marijnhaverbeke.nl/blog/#cm-internals . - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - module.exports = mod(); - else if (typeof define == "function" && define.amd) // AMD - return define([], mod); - else // Plain browser env - this.CodeMirror = mod(); -})(function() { - "use strict"; - - // BROWSER SNIFFING - - // Kludges for bugs and behavior differences that can't be feature - // detected are enabled based on userAgent etc sniffing. - - var gecko = /gecko\/\d/i.test(navigator.userAgent); - // ie_uptoN means Internet Explorer version N or lower - var ie_upto10 = /MSIE \d/.test(navigator.userAgent); - var ie_upto7 = ie_upto10 && (document.documentMode == null || document.documentMode < 8); - var ie_upto8 = ie_upto10 && (document.documentMode == null || document.documentMode < 9); - var ie_upto9 = ie_upto10 && (document.documentMode == null || document.documentMode < 10); - var ie_11up = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent); - var ie = ie_upto10 || ie_11up; - var webkit = /WebKit\//.test(navigator.userAgent); - var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); - var chrome = /Chrome\//.test(navigator.userAgent); - var presto = /Opera\//.test(navigator.userAgent); - var safari = /Apple Computer/.test(navigator.vendor); - var khtml = /KHTML\//.test(navigator.userAgent); - var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); - var phantom = /PhantomJS/.test(navigator.userAgent); - - var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); - // This is woefully incomplete. Suggestions for alternative methods welcome. - var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); - var mac = ios || /Mac/.test(navigator.platform); - var windows = /win/i.test(navigator.platform); - - var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/); - if (presto_version) presto_version = Number(presto_version[1]); - if (presto_version && presto_version >= 15) { presto = false; webkit = true; } - // Some browsers use the wrong event properties to signal cmd/ctrl on OS X - var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); - var captureRightClick = gecko || (ie && !ie_upto8); - - // Optimize some code when these features are not used. - var sawReadOnlySpans = false, sawCollapsedSpans = false; - - // EDITOR CONSTRUCTOR - - // A CodeMirror instance represents an editor. This is the object - // that user code is usually dealing with. - - function CodeMirror(place, options) { - if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); - - this.options = options = options || {}; - // Determine effective options based on given values and defaults. - copyObj(defaults, options, false); - setGuttersForLineNumbers(options); - - var doc = options.value; - if (typeof doc == "string") doc = new Doc(doc, options.mode); - this.doc = doc; - - var display = this.display = new Display(place, doc); - display.wrapper.CodeMirror = this; - updateGutters(this); - themeChanged(this); - if (options.lineWrapping) - this.display.wrapper.className += " CodeMirror-wrap"; - if (options.autofocus && !mobile) focusInput(this); - - this.state = { - keyMaps: [], // stores maps added by addKeyMap - overlays: [], // highlighting overlays, as added by addOverlay - modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info - overwrite: false, focused: false, - suppressEdits: false, // used to disable editing during key handlers when in readOnly mode - pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput - draggingText: false, - highlight: new Delayed() // stores highlight worker timeout - }; - - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie_upto10) setTimeout(bind(resetInput, this, true), 20); - - registerEventHandlers(this); - - var cm = this; - runInOp(this, function() { - cm.curOp.forceUpdate = true; - attachDoc(cm, doc); - - if ((options.autofocus && !mobile) || activeElt() == display.input) - setTimeout(bind(onFocus, cm), 20); - else - onBlur(cm); - - for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) - optionHandlers[opt](cm, options[opt], Init); - for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm); - }); - } - - // DISPLAY CONSTRUCTOR - - // The display handles the DOM integration, both for input reading - // and content drawing. It holds references to DOM nodes and - // display-related state. - - function Display(place, doc) { - var d = this; - - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); - // The textarea is kept positioned near the cursor to prevent the - // fact that it'll be scrolled into view on input from scrolling - // our fake cursor out of view. On webkit, when wrap=off, paste is - // very slow. So make the area wide instead. - if (webkit) input.style.width = "1000px"; - else input.setAttribute("wrap", "off"); - // If border: 0; -- iOS fails to open keyboard (issue #1287) - if (ios) input.style.border = "1px solid black"; - input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false"); - - // Wraps and hides input textarea - d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); - // The fake scrollbar elements. - d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); - d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); - // Covers bottom-right square when both scrollbars are present. - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); - // Covers bottom of gutter when coverGutterNextToScrollbar is on - // and h scrollbar is present. - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); - // Will contain the actual code, positioned to cover the viewport. - d.lineDiv = elt("div", null, "CodeMirror-code"); - // Elements are added to these to represent selection and cursors. - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); - d.cursorDiv = elt("div", null, "CodeMirror-cursors"); - // A visibility: hidden element used to find the size of things. - d.measure = elt("div", null, "CodeMirror-measure"); - // When lines outside of the viewport are measured, they are drawn in this. - d.lineMeasure = elt("div", null, "CodeMirror-measure"); - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], - null, "position: relative; outline: none"); - // Moved around its parent to cover visible view. - d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); - // Set to the height of the document, allowing scrolling. - d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); - // Behavior of elts with overflow: auto and padding is - // inconsistent across browsers. This is used to ensure the - // scrollable area is big enough. - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;"); - // Will contain the gutters, if any. - d.gutters = elt("div", null, "CodeMirror-gutters"); - d.lineGutter = null; - // Actual scrollable element. - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); - d.scroller.setAttribute("tabIndex", "-1"); - // The element in which the editor lives. - d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV, - d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); - - // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) - if (ie_upto7) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } - // Needed to hide big blue blinking cursor on Mobile Safari - if (ios) input.style.width = "0px"; - if (!webkit) d.scroller.draggable = true; - // Needed to handle Tab key in KHTML - if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; } - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - if (ie_upto7) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px"; - - if (place.appendChild) place.appendChild(d.wrapper); - else place(d.wrapper); - - // Current rendered range (may be bigger than the view window). - d.viewFrom = d.viewTo = doc.first; - // Information about the rendered lines. - d.view = []; - // Holds info about a single rendered line when it was rendered - // for measurement, while not in view. - d.externalMeasured = null; - // Empty space (in pixels) above the view - d.viewOffset = 0; - d.lastSizeC = 0; - d.updateLineNumbers = null; - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; - // See readInput and resetInput - d.prevInput = ""; - // Set to true when a non-horizontal-scrolling line widget is - // added. As an optimization, line widget aligning is skipped when - // this is false. - d.alignWidgets = false; - // Flag that indicates whether we expect input to appear real soon - // now (after some event like 'keypress' or 'input') and are - // polling intensively. - d.pollingFast = false; - // Self-resetting timeout for the poller - d.poll = new Delayed(); - - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - - // Tracks when resetInput has punted to just putting a short - // string into the textarea instead of the full selection. - d.inaccurateSelection = false; - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null; - d.maxLineLength = 0; - d.maxLineChanged = false; - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - - // True when shift is held down. - d.shift = false; - } - - // STATE UPDATES - - // Used to get the editor into a consistent state again when options change. - - function loadMode(cm) { - cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); - resetModeState(cm); - } - - function resetModeState(cm) { - cm.doc.iter(function(line) { - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - }); - cm.doc.frontier = cm.doc.first; - startWorker(cm, 100); - cm.state.modeGen++; - if (cm.curOp) regChange(cm); - } - - function wrappingChanged(cm) { - if (cm.options.lineWrapping) { - addClass(cm.display.wrapper, "CodeMirror-wrap"); - cm.display.sizer.style.minWidth = ""; - } else { - rmClass(cm.display.wrapper, "CodeMirror-wrap"); - findMaxLine(cm); - } - estimateLineHeights(cm); - regChange(cm); - clearCaches(cm); - setTimeout(function(){updateScrollbars(cm);}, 100); - } - - // Returns a function that estimates the height of a line, to use as - // first approximation until the line becomes visible (and is thus - // properly measurable). - function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); - return function(line) { - if (lineIsHidden(cm.doc, line)) return 0; - - var widgetsHeight = 0; - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { - if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; - } - - if (wrapping) - return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; - else - return widgetsHeight + th; - }; - } - - function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm); - doc.iter(function(line) { - var estHeight = est(line); - if (estHeight != line.height) updateLineHeight(line, estHeight); - }); - } - - function keyMapChanged(cm) { - var map = keyMap[cm.options.keyMap], style = map.style; - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") + - (style ? " cm-keymap-" + style : ""); - } - - function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); - clearCaches(cm); - } - - function guttersChanged(cm) { - updateGutters(cm); - regChange(cm); - setTimeout(function(){alignHorizontally(cm);}, 20); - } - - // Rebuild the gutter elements, ensure the margin to the left of the - // code matches their width. - function updateGutters(cm) { - var gutters = cm.display.gutters, specs = cm.options.gutters; - removeChildren(gutters); - for (var i = 0; i < specs.length; ++i) { - var gutterClass = specs[i]; - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); - if (gutterClass == "CodeMirror-linenumbers") { - cm.display.lineGutter = gElt; - gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; - } - } - gutters.style.display = i ? "" : "none"; - updateGutterSpace(cm); - } - - function updateGutterSpace(cm) { - var width = cm.display.gutters.offsetWidth; - cm.display.sizer.style.marginLeft = width + "px"; - cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0; - } - - // Compute the character length of a line, taking into account - // collapsed ranges (see markText) that might hide parts, and join - // other lines onto it. - function lineLength(line) { - if (line.height == 0) return 0; - var len = line.text.length, merged, cur = line; - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(0, true); - cur = found.from.line; - len += found.from.ch - found.to.ch; - } - cur = line; - while (merged = collapsedSpanAtEnd(cur)) { - var found = merged.find(0, true); - len -= cur.text.length - found.from.ch; - cur = found.to.line; - len += cur.text.length - found.to.ch; - } - return len; - } - - // Find the longest line in the document. - function findMaxLine(cm) { - var d = cm.display, doc = cm.doc; - d.maxLine = getLine(doc, doc.first); - d.maxLineLength = lineLength(d.maxLine); - d.maxLineChanged = true; - doc.iter(function(line) { - var len = lineLength(line); - if (len > d.maxLineLength) { - d.maxLineLength = len; - d.maxLine = line; - } - }); - } - - // Make sure the gutters options contains the element - // "CodeMirror-linenumbers" when the lineNumbers option is true. - function setGuttersForLineNumbers(options) { - var found = indexOf(options.gutters, "CodeMirror-linenumbers"); - if (found == -1 && options.lineNumbers) { - options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); - } else if (found > -1 && !options.lineNumbers) { - options.gutters = options.gutters.slice(0); - options.gutters.splice(found, 1); - } - } - - // SCROLLBARS - - // Prepare DOM reads needed to update the scrollbars. Done in one - // shot to minimize update/measure roundtrips. - function measureForScrollbars(cm) { - var scroll = cm.display.scroller; - return { - clientHeight: scroll.clientHeight, - barHeight: cm.display.scrollbarV.clientHeight, - scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth, - barWidth: cm.display.scrollbarH.clientWidth, - docHeight: Math.round(cm.doc.height + paddingVert(cm.display)) - }; - } - - // Re-synchronize the fake scrollbars with the actual size of the - // content. - function updateScrollbars(cm, measure) { - if (!measure) measure = measureForScrollbars(cm); - var d = cm.display; - var scrollHeight = measure.docHeight + scrollerCutOff; - var needsH = measure.scrollWidth > measure.clientWidth; - var needsV = scrollHeight > measure.clientHeight; - if (needsV) { - d.scrollbarV.style.display = "block"; - d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0"; - // A bug in IE8 can cause this value to be negative, so guard it. - d.scrollbarV.firstChild.style.height = - Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px"; - } else { - d.scrollbarV.style.display = ""; - d.scrollbarV.firstChild.style.height = "0"; - } - if (needsH) { - d.scrollbarH.style.display = "block"; - d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0"; - d.scrollbarH.firstChild.style.width = - (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px"; - } else { - d.scrollbarH.style.display = ""; - d.scrollbarH.firstChild.style.width = "0"; - } - if (needsH && needsV) { - d.scrollbarFiller.style.display = "block"; - d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px"; - } else d.scrollbarFiller.style.display = ""; - if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block"; - d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px"; - d.gutterFiller.style.width = d.gutters.offsetWidth + "px"; - } else d.gutterFiller.style.display = ""; - - if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) { - if (scrollbarWidth(d.measure) === 0) { - var w = mac && !mac_geMountainLion ? "12px" : "18px"; - d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w; - var barMouseDown = function(e) { - if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH) - operation(cm, onMouseDown)(e); - }; - on(d.scrollbarV, "mousedown", barMouseDown); - on(d.scrollbarH, "mousedown", barMouseDown); - } - cm.state.checkedOverlayScrollbar = true; - } - } - - // Compute the lines that are visible in a given viewport (defaults - // the the current scroll position). viewPort may contain top, - // height, and ensure (see op.scrollToPos) properties. - function visibleLines(display, doc, viewPort) { - var top = viewPort && viewPort.top != null ? viewPort.top : display.scroller.scrollTop; - top = Math.floor(top - paddingTop(display)); - var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight; - - var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); - // Ensure is a {from: {line, ch}, to: {line, ch}} object, and - // forces those lines into the viewport (if possible). - if (viewPort && viewPort.ensure) { - var ensureFrom = viewPort.ensure.from.line, ensureTo = viewPort.ensure.to.line; - if (ensureFrom < from) - return {from: ensureFrom, - to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)}; - if (Math.min(ensureTo, doc.lastLine()) >= to) - return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight), - to: ensureTo}; - } - return {from: from, to: to}; - } - - // LINE NUMBERS - - // Re-align line numbers and gutter marks to compensate for - // horizontal scrolling. - function alignHorizontally(cm) { - var display = cm.display, view = display.view; - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; - var gutterW = display.gutters.offsetWidth, left = comp + "px"; - for (var i = 0; i < view.length; i++) if (!view[i].hidden) { - if (cm.options.fixedGutter && view[i].gutter) - view[i].gutter.style.left = left; - var align = view[i].alignable; - if (align) for (var j = 0; j < align.length; j++) - align[j].style.left = left; - } - if (cm.options.fixedGutter) - display.gutters.style.left = (comp + gutterW) + "px"; - } - - // Used to ensure that the line number gutter is still the right - // size for the current document size. Returns true when an update - // is needed. - function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) return false; - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")); - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; - display.lineGutter.style.width = ""; - display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding); - display.lineNumWidth = display.lineNumInnerWidth + padding; - display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; - display.lineGutter.style.width = display.lineNumWidth + "px"; - updateGutterSpace(cm); - return true; - } - return false; - } - - function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)); - } - - // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, - // but using getBoundingClientRect to get a sub-pixel-accurate - // result. - function compensateForHScroll(display) { - return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; - } - - // DISPLAY DRAWING - - // Updates the display, selection, and scrollbars, using the - // information in display.view to find out which nodes are no longer - // up-to-date. Tries to bail out early when no changes are needed, - // unless forced is true. - // Returns true if an actual update happened, false otherwise. - function updateDisplay(cm, viewPort, forced) { - var oldFrom = cm.display.viewFrom, oldTo = cm.display.viewTo, updated; - var visible = visibleLines(cm.display, cm.doc, viewPort); - for (var first = true;; first = false) { - var oldWidth = cm.display.scroller.clientWidth; - if (!updateDisplayInner(cm, visible, forced)) break; - updated = true; - - // If the max line changed since it was last measured, measure it, - // and ensure the document's width matches it. - if (cm.display.maxLineChanged && !cm.options.lineWrapping) - adjustContentWidth(cm); - - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - setDocumentHeight(cm, barMeasure); - updateScrollbars(cm, barMeasure); - if (webkit && cm.options.lineWrapping) - checkForWebkitWidthBug(cm, barMeasure); // (Issue #2420) - if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { - forced = true; - continue; - } - forced = false; - - // Clip forced viewport to actual scrollable area. - if (viewPort && viewPort.top != null) - viewPort = {top: Math.min(barMeasure.docHeight - scrollerCutOff - barMeasure.clientHeight, viewPort.top)}; - // Updated line heights might result in the drawn area not - // actually covering the viewport. Keep looping until it does. - visible = visibleLines(cm.display, cm.doc, viewPort); - if (visible.from >= cm.display.viewFrom && visible.to <= cm.display.viewTo) - break; - } - - cm.display.updateLineNumbers = null; - if (updated) { - signalLater(cm, "update", cm); - if (cm.display.viewFrom != oldFrom || cm.display.viewTo != oldTo) - signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); - } - return updated; - } - - // Does the actual updating of the line display. Bails out - // (returning false) when there is nothing to be done and forced is - // false. - function updateDisplayInner(cm, visible, forced) { - var display = cm.display, doc = cm.doc; - if (!display.wrapper.offsetWidth) { - resetView(cm); - return; - } - - // Bail out if the visible area is already rendered and nothing changed. - if (!forced && visible.from >= display.viewFrom && visible.to <= display.viewTo && - countDirtyView(cm) == 0) - return; - - if (maybeUpdateLineNumberWidth(cm)) - resetView(cm); - var dims = getDimensions(cm); - - // Compute a suitable new viewport (from & to) - var end = doc.first + doc.size; - var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); - var to = Math.min(end, visible.to + cm.options.viewportMargin); - if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); - if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); - if (sawCollapsedSpans) { - from = visualLineNo(cm.doc, from); - to = visualLineEndNo(cm.doc, to); - } - - var different = from != display.viewFrom || to != display.viewTo || - display.lastSizeC != display.wrapper.clientHeight; - adjustView(cm, from, to); - - display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); - // Position the mover div to align with the current scroll position - cm.display.mover.style.top = display.viewOffset + "px"; - - var toUpdate = countDirtyView(cm); - if (!different && toUpdate == 0 && !forced) return; - - // For big changes, we hide the enclosing element during the - // update, since that speeds up the operations on most browsers. - var focused = activeElt(); - if (toUpdate > 4) display.lineDiv.style.display = "none"; - patchDisplay(cm, display.updateLineNumbers, dims); - if (toUpdate > 4) display.lineDiv.style.display = ""; - // There might have been a widget with a focused element that got - // hidden or updated, if so re-focus it. - if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); - - // Prevent selection and cursors from interfering with the scroll - // width. - removeChildren(display.cursorDiv); - removeChildren(display.selectionDiv); - - if (different) { - display.lastSizeC = display.wrapper.clientHeight; - startWorker(cm, 400); - } - - updateHeightsInViewport(cm); - - return true; - } - - function adjustContentWidth(cm) { - var display = cm.display; - var width = measureChar(cm, display.maxLine, display.maxLine.text.length).left; - display.maxLineChanged = false; - var minWidth = Math.max(0, width + 3); - var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + minWidth + scrollerCutOff - display.scroller.clientWidth); - display.sizer.style.minWidth = minWidth + "px"; - if (maxScrollLeft < cm.doc.scrollLeft) - setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true); - } - - function setDocumentHeight(cm, measure) { - cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px"; - cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px"; - } - - - function checkForWebkitWidthBug(cm, measure) { - // Work around Webkit bug where it sometimes reserves space for a - // non-existing phantom scrollbar in the scroller (Issue #2420) - if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) { - cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px"; - cm.display.gutters.style.height = measure.docHeight + "px"; - } - } - - // Read the actual heights of the rendered lines, and update their - // stored heights to match. - function updateHeightsInViewport(cm) { - var display = cm.display; - var prevBottom = display.lineDiv.offsetTop; - for (var i = 0; i < display.view.length; i++) { - var cur = display.view[i], height; - if (cur.hidden) continue; - if (ie_upto7) { - var bot = cur.node.offsetTop + cur.node.offsetHeight; - height = bot - prevBottom; - prevBottom = bot; - } else { - var box = cur.node.getBoundingClientRect(); - height = box.bottom - box.top; - } - var diff = cur.line.height - height; - if (height < 2) height = textHeight(display); - if (diff > .001 || diff < -.001) { - updateLineHeight(cur.line, height); - updateWidgetHeight(cur.line); - if (cur.rest) for (var j = 0; j < cur.rest.length; j++) - updateWidgetHeight(cur.rest[j]); - } - } - } - - // Read and store the height of line widgets associated with the - // given line. - function updateWidgetHeight(line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) - line.widgets[i].height = line.widgets[i].node.offsetHeight; - } - - // Do a bulk-read of the DOM positions and sizes needed to draw the - // view, so that we don't interleave reading and writing to the DOM. - function getDimensions(cm) { - var d = cm.display, left = {}, width = {}; - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - left[cm.options.gutters[i]] = n.offsetLeft; - width[cm.options.gutters[i]] = n.offsetWidth; - } - return {fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth}; - } - - // Sync the actual display DOM structure with display.view, removing - // nodes for lines that are no longer in view, and creating the ones - // that are not there yet, and updating the ones that are out of - // date. - function patchDisplay(cm, updateNumbersFrom, dims) { - var display = cm.display, lineNumbers = cm.options.lineNumbers; - var container = display.lineDiv, cur = container.firstChild; - - function rm(node) { - var next = node.nextSibling; - // Works around a throw-scroll bug in OS X Webkit - if (webkit && mac && cm.display.currentWheelTarget == node) - node.style.display = "none"; - else - node.parentNode.removeChild(node); - return next; - } - - var view = display.view, lineN = display.viewFrom; - // Loop over the elements in the view, syncing cur (the DOM nodes - // in display.lineDiv) with the view as we go. - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (lineView.hidden) { - } else if (!lineView.node) { // Not drawn yet - var node = buildLineElement(cm, lineView, lineN, dims); - container.insertBefore(node, cur); - } else { // Already drawn - while (cur != lineView.node) cur = rm(cur); - var updateNumber = lineNumbers && updateNumbersFrom != null && - updateNumbersFrom <= lineN && lineView.lineNumber; - if (lineView.changes) { - if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; - updateLineForChanges(cm, lineView, lineN, dims); - } - if (updateNumber) { - removeChildren(lineView.lineNumber); - lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); - } - cur = lineView.node.nextSibling; - } - lineN += lineView.size; - } - while (cur) cur = rm(cur); - } - - // When an aspect of a line changes, a string is added to - // lineView.changes. This updates the relevant part of the line's - // DOM structure. - function updateLineForChanges(cm, lineView, lineN, dims) { - for (var j = 0; j < lineView.changes.length; j++) { - var type = lineView.changes[j]; - if (type == "text") updateLineText(cm, lineView); - else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); - else if (type == "class") updateLineClasses(lineView); - else if (type == "widget") updateLineWidgets(lineView, dims); - } - lineView.changes = null; - } - - // Lines with gutter elements, widgets or a background class need to - // be wrapped, and have the extra elements added to the wrapper div - function ensureLineWrapped(lineView) { - if (lineView.node == lineView.text) { - lineView.node = elt("div", null, null, "position: relative"); - if (lineView.text.parentNode) - lineView.text.parentNode.replaceChild(lineView.node, lineView.text); - lineView.node.appendChild(lineView.text); - if (ie_upto7) lineView.node.style.zIndex = 2; - } - return lineView.node; - } - - function updateLineBackground(lineView) { - var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; - if (cls) cls += " CodeMirror-linebackground"; - if (lineView.background) { - if (cls) lineView.background.className = cls; - else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } - } else if (cls) { - var wrap = ensureLineWrapped(lineView); - lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); - } - } - - // Wrapper around buildLineContent which will reuse the structure - // in display.externalMeasured when possible. - function getLineContent(cm, lineView) { - var ext = cm.display.externalMeasured; - if (ext && ext.line == lineView.line) { - cm.display.externalMeasured = null; - lineView.measure = ext.measure; - return ext.built; - } - return buildLineContent(cm, lineView); - } - - // Redraw the line's text. Interacts with the background and text - // classes because the mode may output tokens that influence these - // classes. - function updateLineText(cm, lineView) { - var cls = lineView.text.className; - var built = getLineContent(cm, lineView); - if (lineView.text == lineView.node) lineView.node = built.pre; - lineView.text.parentNode.replaceChild(built.pre, lineView.text); - lineView.text = built.pre; - if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { - lineView.bgClass = built.bgClass; - lineView.textClass = built.textClass; - updateLineClasses(lineView); - } else if (cls) { - lineView.text.className = cls; - } - } - - function updateLineClasses(lineView) { - updateLineBackground(lineView); - if (lineView.line.wrapClass) - ensureLineWrapped(lineView).className = lineView.line.wrapClass; - else if (lineView.node != lineView.text) - lineView.node.className = ""; - var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; - lineView.text.className = textClass || ""; - } - - function updateLineGutter(cm, lineView, lineN, dims) { - if (lineView.gutter) { - lineView.node.removeChild(lineView.gutter); - lineView.gutter = null; - } - var markers = lineView.line.gutterMarkers; - if (cm.options.lineNumbers || markers) { - var wrap = ensureLineWrapped(lineView); - var gutterWrap = lineView.gutter = - wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " + - (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"), - lineView.text); - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) - lineView.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineN), - "CodeMirror-linenumber CodeMirror-gutter-elt", - "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " - + cm.display.lineNumInnerWidth + "px")); - if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { - var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; - if (found) - gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + - dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); - } - } - } - - function updateLineWidgets(lineView, dims) { - if (lineView.alignable) lineView.alignable = null; - for (var node = lineView.node.firstChild, next; node; node = next) { - var next = node.nextSibling; - if (node.className == "CodeMirror-linewidget") - lineView.node.removeChild(node); - } - insertLineWidgets(lineView, dims); - } - - // Build a line's DOM representation from scratch - function buildLineElement(cm, lineView, lineN, dims) { - var built = getLineContent(cm, lineView); - lineView.text = lineView.node = built.pre; - if (built.bgClass) lineView.bgClass = built.bgClass; - if (built.textClass) lineView.textClass = built.textClass; - - updateLineClasses(lineView); - updateLineGutter(cm, lineView, lineN, dims); - insertLineWidgets(lineView, dims); - return lineView.node; - } - - // A lineView may contain multiple logical lines (when merged by - // collapsed spans). The widgets for all of them need to be drawn. - function insertLineWidgets(lineView, dims) { - insertLineWidgetsFor(lineView.line, lineView, dims, true); - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - insertLineWidgetsFor(lineView.rest[i], lineView, dims, false); - } - - function insertLineWidgetsFor(line, lineView, dims, allowAbove) { - if (!line.widgets) return; - var wrap = ensureLineWrapped(lineView); - for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); - if (!widget.handleMouseEvents) node.ignoreEvents = true; - positionLineWidget(widget, node, lineView, dims); - if (allowAbove && widget.above) - wrap.insertBefore(node, lineView.gutter || lineView.text); - else - wrap.appendChild(node); - signalLater(widget, "redraw"); - } - } - - function positionLineWidget(widget, node, lineView, dims) { - if (widget.noHScroll) { - (lineView.alignable || (lineView.alignable = [])).push(node); - var width = dims.wrapperWidth; - node.style.left = dims.fixedPos + "px"; - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth; - node.style.paddingLeft = dims.gutterTotalWidth + "px"; - } - node.style.width = width + "px"; - } - if (widget.coverGutter) { - node.style.zIndex = 5; - node.style.position = "relative"; - if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; - } - } - - // POSITION OBJECT - - // A Pos instance represents a position within the text. - var Pos = CodeMirror.Pos = function(line, ch) { - if (!(this instanceof Pos)) return new Pos(line, ch); - this.line = line; this.ch = ch; - }; - - // Compare two positions, return 0 if they are the same, a negative - // number when a is less, and a positive number otherwise. - var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; - - function copyPos(x) {return Pos(x.line, x.ch);} - function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } - function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } - - // SELECTION / CURSOR - - // Selection objects are immutable. A new one is created every time - // the selection changes. A selection is one or more non-overlapping - // (and non-touching) ranges, sorted, and an integer that indicates - // which one is the primary selection (the one that's scrolled into - // view, that getCursor returns, etc). - function Selection(ranges, primIndex) { - this.ranges = ranges; - this.primIndex = primIndex; - } - - Selection.prototype = { - primary: function() { return this.ranges[this.primIndex]; }, - equals: function(other) { - if (other == this) return true; - if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; - for (var i = 0; i < this.ranges.length; i++) { - var here = this.ranges[i], there = other.ranges[i]; - if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; - } - return true; - }, - deepCopy: function() { - for (var out = [], i = 0; i < this.ranges.length; i++) - out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); - return new Selection(out, this.primIndex); - }, - somethingSelected: function() { - for (var i = 0; i < this.ranges.length; i++) - if (!this.ranges[i].empty()) return true; - return false; - }, - contains: function(pos, end) { - if (!end) end = pos; - for (var i = 0; i < this.ranges.length; i++) { - var range = this.ranges[i]; - if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) - return i; - } - return -1; - } - }; - - function Range(anchor, head) { - this.anchor = anchor; this.head = head; - } - - Range.prototype = { - from: function() { return minPos(this.anchor, this.head); }, - to: function() { return maxPos(this.anchor, this.head); }, - empty: function() { - return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; - } - }; - - // Take an unsorted, potentially overlapping set of ranges, and - // build a selection out of it. 'Consumes' ranges array (modifying - // it). - function normalizeSelection(ranges, primIndex) { - var prim = ranges[primIndex]; - ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); - primIndex = indexOf(ranges, prim); - for (var i = 1; i < ranges.length; i++) { - var cur = ranges[i], prev = ranges[i - 1]; - if (cmp(prev.to(), cur.from()) >= 0) { - var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); - var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; - if (i <= primIndex) --primIndex; - ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); - } - } - return new Selection(ranges, primIndex); - } - - function simpleSelection(anchor, head) { - return new Selection([new Range(anchor, head || anchor)], 0); - } - - // Most of the external API clips given positions to make sure they - // actually exist within the document. - function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} - function clipPos(doc, pos) { - if (pos.line < doc.first) return Pos(doc.first, 0); - var last = doc.first + doc.size - 1; - if (pos.line > last) return Pos(last, getLine(doc, last).text.length); - return clipToLen(pos, getLine(doc, pos.line).text.length); - } - function clipToLen(pos, linelen) { - var ch = pos.ch; - if (ch == null || ch > linelen) return Pos(pos.line, linelen); - else if (ch < 0) return Pos(pos.line, 0); - else return pos; - } - function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} - function clipPosArray(doc, array) { - for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); - return out; - } - - // SELECTION UPDATES - - // The 'scroll' parameter given to many of these indicated whether - // the new cursor position should be scrolled into view after - // modifying the selection. - - // If shift is held or the extend flag is set, extends a range to - // include a given position (and optionally a second position). - // Otherwise, simply returns the range between the given positions. - // Used for cursor motion and such. - function extendRange(doc, range, head, other) { - if (doc.cm && doc.cm.display.shift || doc.extend) { - var anchor = range.anchor; - if (other) { - var posBefore = cmp(head, anchor) < 0; - if (posBefore != (cmp(other, anchor) < 0)) { - anchor = head; - head = other; - } else if (posBefore != (cmp(head, other) < 0)) { - head = other; - } - } - return new Range(anchor, head); - } else { - return new Range(other || head, head); - } - } - - // Extend the primary selection range, discard the rest. - function extendSelection(doc, head, other, options) { - setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); - } - - // Extend all selections (pos is an array of selections with length - // equal the number of selections) - function extendSelections(doc, heads, options) { - for (var out = [], i = 0; i < doc.sel.ranges.length; i++) - out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); - var newSel = normalizeSelection(out, doc.sel.primIndex); - setSelection(doc, newSel, options); - } - - // Updates a single range in the selection. - function replaceOneSelection(doc, i, range, options) { - var ranges = doc.sel.ranges.slice(0); - ranges[i] = range; - setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); - } - - // Reset the selection to a single range. - function setSimpleSelection(doc, anchor, head, options) { - setSelection(doc, simpleSelection(anchor, head), options); - } - - // Give beforeSelectionChange handlers a change to influence a - // selection update. - function filterSelectionChange(doc, sel) { - var obj = { - ranges: sel.ranges, - update: function(ranges) { - this.ranges = []; - for (var i = 0; i < ranges.length; i++) - this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), - clipPos(doc, ranges[i].head)); - } - }; - signal(doc, "beforeSelectionChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); - if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); - else return sel; - } - - function setSelectionReplaceHistory(doc, sel, options) { - var done = doc.history.done, last = lst(done); - if (last && last.ranges) { - done[done.length - 1] = sel; - setSelectionNoUndo(doc, sel, options); - } else { - setSelection(doc, sel, options); - } - } - - // Set a new selection. - function setSelection(doc, sel, options) { - setSelectionNoUndo(doc, sel, options); - addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); - } - - function setSelectionNoUndo(doc, sel, options) { - if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) - sel = filterSelectionChange(doc, sel); - - var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1; - setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); - - if (!(options && options.scroll === false) && doc.cm) - ensureCursorVisible(doc.cm); - } - - function setSelectionInner(doc, sel) { - if (sel.equals(doc.sel)) return; - - doc.sel = sel; - - if (doc.cm) { - doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; - signalCursorActivity(doc.cm); - } - signalLater(doc, "cursorActivity", doc); - } - - // Verify that the selection does not partially select any atomic - // marked ranges. - function reCheckSelection(doc) { - setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); - } - - // Return a selection that does not partially select any atomic - // ranges. - function skipAtomicInSelection(doc, sel, bias, mayClear) { - var out; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear); - var newHead = skipAtomic(doc, range.head, bias, mayClear); - if (out || newAnchor != range.anchor || newHead != range.head) { - if (!out) out = sel.ranges.slice(0, i); - out[i] = new Range(newAnchor, newHead); - } - } - return out ? normalizeSelection(out, sel.primIndex) : sel; - } - - // Ensure a given position is not inside an atomic range. - function skipAtomic(doc, pos, bias, mayClear) { - var flipped = false, curPos = pos; - var dir = bias || 1; - doc.cantEdit = false; - search: for (;;) { - var line = getLine(doc, curPos.line); - if (line.markedSpans) { - for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker; - if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && - (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter"); - if (m.explicitlyCleared) { - if (!line.markedSpans) break; - else {--i; continue;} - } - } - if (!m.atomic) continue; - var newPos = m.find(dir < 0 ? -1 : 1); - if (cmp(newPos, curPos) == 0) { - newPos.ch += dir; - if (newPos.ch < 0) { - if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); - else newPos = null; - } else if (newPos.ch > line.text.length) { - if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); - else newPos = null; - } - if (!newPos) { - if (flipped) { - // Driven in a corner -- no valid cursor position found at all - // -- try again *with* clearing, if we didn't already - if (!mayClear) return skipAtomic(doc, pos, bias, true); - // Otherwise, turn off editing until further notice, and return the start of the doc - doc.cantEdit = true; - return Pos(doc.first, 0); - } - flipped = true; newPos = pos; dir = -dir; - } - } - curPos = newPos; - continue search; - } - } - } - return curPos; - } - } - - // SELECTION DRAWING - - // Redraw the selection and/or cursor - function updateSelection(cm) { - var display = cm.display, doc = cm.doc; - var curFragment = document.createDocumentFragment(); - var selFragment = document.createDocumentFragment(); - - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - var collapsed = range.empty(); - if (collapsed || cm.options.showCursorWhenSelecting) - drawSelectionCursor(cm, range, curFragment); - if (!collapsed) - drawSelectionRange(cm, range, selFragment); - } - - // Move the hidden textarea near the cursor to prevent scrolling artifacts - if (cm.options.moveInputWithCursor) { - var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); - var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); - var top = Math.max(0, Math.min(display.wrapper.clientHeight - 10, - headPos.top + lineOff.top - wrapOff.top)); - var left = Math.max(0, Math.min(display.wrapper.clientWidth - 10, - headPos.left + lineOff.left - wrapOff.left)); - display.inputDiv.style.top = top + "px"; - display.inputDiv.style.left = left + "px"; - } - - removeChildrenAndAdd(display.cursorDiv, curFragment); - removeChildrenAndAdd(display.selectionDiv, selFragment); - } - - // Draws a cursor for the given range - function drawSelectionCursor(cm, range, output) { - var pos = cursorCoords(cm, range.head, "div"); - - var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); - cursor.style.left = pos.left + "px"; - cursor.style.top = pos.top + "px"; - cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; - - if (pos.other) { - // Secondary cursor, shown when on a 'jump' in bi-directional text - var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); - otherCursor.style.display = ""; - otherCursor.style.left = pos.other.left + "px"; - otherCursor.style.top = pos.other.top + "px"; - otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; - } - } - - // Draws the given range as a highlighted selection - function drawSelectionRange(cm, range, output) { - var display = cm.display, doc = cm.doc; - var fragment = document.createDocumentFragment(); - var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right; - - function add(left, top, width, bottom) { - if (top < 0) top = 0; - top = Math.round(top); - bottom = Math.round(bottom); - fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + - "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + - "px; height: " + (bottom - top) + "px")); - } - - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line); - var lineLen = lineObj.text.length; - var start, end; - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias); - } - - iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { - var leftPos = coords(from, "left"), rightPos, left, right; - if (from == to) { - rightPos = leftPos; - left = right = leftPos.left; - } else { - rightPos = coords(to - 1, "right"); - if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } - left = leftPos.left; - right = rightPos.right; - } - if (fromArg == null && from == 0) left = leftSide; - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom); - left = leftSide; - if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); - } - if (toArg == null && to == lineLen) right = rightSide; - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - start = leftPos; - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - end = rightPos; - if (left < leftSide + 1) left = leftSide; - add(left, rightPos.top, right - left, rightPos.bottom); - }); - return {start: start, end: end}; - } - - var sFrom = range.from(), sTo = range.to(); - if (sFrom.line == sTo.line) { - drawForLine(sFrom.line, sFrom.ch, sTo.ch); - } else { - var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); - var singleVLine = visualLine(fromLine) == visualLine(toLine); - var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; - var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); - add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); - } - } - if (leftEnd.bottom < rightStart.top) - add(leftSide, leftEnd.bottom, null, rightStart.top); - } - - output.appendChild(fragment); - } - - // Cursor-blinking - function restartBlink(cm) { - if (!cm.state.focused) return; - var display = cm.display; - clearInterval(display.blinker); - var on = true; - display.cursorDiv.style.visibility = ""; - if (cm.options.cursorBlinkRate > 0) - display.blinker = setInterval(function() { - display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; - }, cm.options.cursorBlinkRate); - } - - // HIGHLIGHT WORKER - - function startWorker(cm, time) { - if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) - cm.state.highlight.set(time, bind(highlightWorker, cm)); - } - - function highlightWorker(cm) { - var doc = cm.doc; - if (doc.frontier < doc.first) doc.frontier = doc.first; - if (doc.frontier >= cm.display.viewTo) return; - var end = +new Date + cm.options.workTime; - var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); - - runInOp(cm, function() { - doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { - if (doc.frontier >= cm.display.viewFrom) { // Visible - var oldStyles = line.styles; - var highlighted = highlightLine(cm, line, state, true); - line.styles = highlighted.styles; - if (highlighted.classes) line.styleClasses = highlighted.classes; - else if (line.styleClasses) line.styleClasses = null; - var ischange = !oldStyles || oldStyles.length != line.styles.length; - for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; - if (ischange) regLineChange(cm, doc.frontier, "text"); - line.stateAfter = copyState(doc.mode, state); - } else { - processLine(cm, line.text, state); - line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; - } - ++doc.frontier; - if (+new Date > end) { - startWorker(cm, cm.options.workDelay); - return true; - } - }); - }); - } - - // Finds the line to start with when starting a parse. Tries to - // find a line with a stateAfter, so that it can start with a - // valid state. If that fails, it returns the line with the - // smallest indentation, which tends to need the least context to - // parse correctly. - function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc; - var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); - for (var search = n; search > lim; --search) { - if (search <= doc.first) return doc.first; - var line = getLine(doc, search - 1); - if (line.stateAfter && (!precise || search <= doc.frontier)) return search; - var indented = countColumn(line.text, null, cm.options.tabSize); - if (minline == null || minindent > indented) { - minline = search - 1; - minindent = indented; - } - } - return minline; - } - - function getStateBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display; - if (!doc.mode.startState) return true; - var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; - if (!state) state = startState(doc.mode); - else state = copyState(doc.mode, state); - doc.iter(pos, n, function(line) { - processLine(cm, line.text, state); - var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; - line.stateAfter = save ? copyState(doc.mode, state) : null; - ++pos; - }); - if (precise) doc.frontier = pos; - return state; - } - - // POSITION MEASUREMENT - - function paddingTop(display) {return display.lineSpace.offsetTop;} - function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} - function paddingH(display) { - if (display.cachedPaddingH) return display.cachedPaddingH; - var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); - var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; - var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; - if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; - return data; - } - - // Ensure the lineView.wrapping.heights array is populated. This is - // an array of bottom offsets for the lines that make up a drawn - // line. When lineWrapping is on, there might be more than one - // height. - function ensureLineHeights(cm, lineView, rect) { - var wrapping = cm.options.lineWrapping; - var curWidth = wrapping && cm.display.scroller.clientWidth; - if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { - var heights = lineView.measure.heights = []; - if (wrapping) { - lineView.measure.width = curWidth; - var rects = lineView.text.firstChild.getClientRects(); - for (var i = 0; i < rects.length - 1; i++) { - var cur = rects[i], next = rects[i + 1]; - if (Math.abs(cur.bottom - next.bottom) > 2) - heights.push((cur.bottom + next.top) / 2 - rect.top); - } - } - heights.push(rect.bottom - rect.top); - } - } - - // Find a line map (mapping character offsets to text nodes) and a - // measurement cache for the given line number. (A line view might - // contain multiple lines when collapsed ranges are present.) - function mapFromLineView(lineView, line, lineN) { - if (lineView.line == line) - return {map: lineView.measure.map, cache: lineView.measure.cache}; - for (var i = 0; i < lineView.rest.length; i++) - if (lineView.rest[i] == line) - return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; - for (var i = 0; i < lineView.rest.length; i++) - if (lineNo(lineView.rest[i]) > lineN) - return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; - } - - // Render a line into the hidden node display.externalMeasured. Used - // when measurement is needed for a line that's not in the viewport. - function updateExternalMeasurement(cm, line) { - line = visualLine(line); - var lineN = lineNo(line); - var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); - view.lineN = lineN; - var built = view.built = buildLineContent(cm, view); - view.text = built.pre; - removeChildrenAndAdd(cm.display.lineMeasure, built.pre); - return view; - } - - // Get a {top, bottom, left, right} box (in line-local coordinates) - // for a given character. - function measureChar(cm, line, ch, bias) { - return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); - } - - // Find a line view that corresponds to the given line number. - function findViewForLine(cm, lineN) { - if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) - return cm.display.view[findViewIndex(cm, lineN)]; - var ext = cm.display.externalMeasured; - if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) - return ext; - } - - // Measurement can be split in two steps, the set-up work that - // applies to the whole line, and the measurement of the actual - // character. Functions like coordsChar, that need to do a lot of - // measurements in a row, can thus ensure that the set-up work is - // only done once. - function prepareMeasureForLine(cm, line) { - var lineN = lineNo(line); - var view = findViewForLine(cm, lineN); - if (view && !view.text) - view = null; - else if (view && view.changes) - updateLineForChanges(cm, view, lineN, getDimensions(cm)); - if (!view) - view = updateExternalMeasurement(cm, line); - - var info = mapFromLineView(view, line, lineN); - return { - line: line, view: view, rect: null, - map: info.map, cache: info.cache, before: info.before, - hasHeights: false - }; - } - - // Given a prepared measurement object, measures the position of an - // actual character (or fetches it from the cache). - function measureCharPrepared(cm, prepared, ch, bias) { - if (prepared.before) ch = -1; - var key = ch + (bias || ""), found; - if (prepared.cache.hasOwnProperty(key)) { - found = prepared.cache[key]; - } else { - if (!prepared.rect) - prepared.rect = prepared.view.text.getBoundingClientRect(); - if (!prepared.hasHeights) { - ensureLineHeights(cm, prepared.view, prepared.rect); - prepared.hasHeights = true; - } - found = measureCharInner(cm, prepared, ch, bias); - if (!found.bogus) prepared.cache[key] = found; - } - return {left: found.left, right: found.right, top: found.top, bottom: found.bottom}; - } - - var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; - - function measureCharInner(cm, prepared, ch, bias) { - var map = prepared.map; - - var node, start, end, collapse; - // First, search the line map for the text node corresponding to, - // or closest to, the target character. - for (var i = 0; i < map.length; i += 3) { - var mStart = map[i], mEnd = map[i + 1]; - if (ch < mStart) { - start = 0; end = 1; - collapse = "left"; - } else if (ch < mEnd) { - start = ch - mStart; - end = start + 1; - } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { - end = mEnd - mStart; - start = end - 1; - if (ch >= mEnd) collapse = "right"; - } - if (start != null) { - node = map[i + 2]; - if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) - collapse = bias; - if (bias == "left" && start == 0) - while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { - node = map[(i -= 3) + 2]; - collapse = "left"; - } - if (bias == "right" && start == mEnd - mStart) - while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { - node = map[(i += 3) + 2]; - collapse = "right"; - } - break; - } - } - - var rect; - if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start; - while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end; - if (ie_upto8 && start == 0 && end == mEnd - mStart) { - rect = node.parentNode.getBoundingClientRect(); - } else if (ie && cm.options.lineWrapping) { - var rects = range(node, start, end).getClientRects(); - if (rects.length) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = nullRect; - } else { - rect = range(node, start, end).getBoundingClientRect(); - } - } else { // If it is a widget, simply get the box for the whole widget. - if (start > 0) collapse = bias = "right"; - var rects; - if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = node.getBoundingClientRect(); - } - if (ie_upto8 && !start && (!rect || !rect.left && !rect.right)) { - var rSpan = node.parentNode.getClientRects()[0]; - if (rSpan) - rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; - else - rect = nullRect; - } - - var top, bot = (rect.bottom + rect.top) / 2 - prepared.rect.top; - var heights = prepared.view.measure.heights; - for (var i = 0; i < heights.length - 1; i++) - if (bot < heights[i]) break; - top = i ? heights[i - 1] : 0; bot = heights[i]; - var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, - right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, - top: top, bottom: bot}; - if (!rect.left && !rect.right) result.bogus = true; - return result; - } - - function clearLineMeasurementCacheFor(lineView) { - if (lineView.measure) { - lineView.measure.cache = {}; - lineView.measure.heights = null; - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - lineView.measure.caches[i] = {}; - } - } - - function clearLineMeasurementCache(cm) { - cm.display.externalMeasure = null; - removeChildren(cm.display.lineMeasure); - for (var i = 0; i < cm.display.view.length; i++) - clearLineMeasurementCacheFor(cm.display.view[i]); - } - - function clearCaches(cm) { - clearLineMeasurementCache(cm); - cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; - if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; - cm.display.lineNumChars = null; - } - - function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } - function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } - - // Converts a {top, bottom, left, right} box from line-local - // coordinates into another coordinate system. Context may be one of - // "line", "div" (display.lineDiv), "local"/null (editor), or "page". - function intoCoordSystem(cm, lineObj, rect, context) { - if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { - var size = widgetHeight(lineObj.widgets[i]); - rect.top += size; rect.bottom += size; - } - if (context == "line") return rect; - if (!context) context = "local"; - var yOff = heightAtLine(lineObj); - if (context == "local") yOff += paddingTop(cm.display); - else yOff -= cm.display.viewOffset; - if (context == "page" || context == "window") { - var lOff = cm.display.lineSpace.getBoundingClientRect(); - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); - rect.left += xOff; rect.right += xOff; - } - rect.top += yOff; rect.bottom += yOff; - return rect; - } - - // Coverts a box from "div" coords to another coordinate system. - // Context may be "window", "page", "div", or "local"/null. - function fromCoordSystem(cm, coords, context) { - if (context == "div") return coords; - var left = coords.left, top = coords.top; - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX(); - top -= pageScrollY(); - } else if (context == "local" || !context) { - var localBox = cm.display.sizer.getBoundingClientRect(); - left += localBox.left; - top += localBox.top; - } - - var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); - return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; - } - - function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) lineObj = getLine(cm.doc, pos.line); - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); - } - - // Returns a box for a given cursor position, which may have an - // 'other' property containing the position of the secondary cursor - // on a bidi boundary. - function cursorCoords(cm, pos, context, lineObj, preparedMeasure) { - lineObj = lineObj || getLine(cm.doc, pos.line); - if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); - function get(ch, right) { - var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left"); - if (right) m.left = m.right; else m.right = m.left; - return intoCoordSystem(cm, lineObj, m, context); - } - function getBidi(ch, partPos) { - var part = order[partPos], right = part.level % 2; - if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { - part = order[--partPos]; - ch = bidiRight(part) - (part.level % 2 ? 0 : 1); - right = true; - } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { - part = order[++partPos]; - ch = bidiLeft(part) - part.level % 2; - right = false; - } - if (right && ch == part.to && ch > part.from) return get(ch - 1); - return get(ch, right); - } - var order = getOrder(lineObj), ch = pos.ch; - if (!order) return get(ch); - var partPos = getBidiPartAt(order, ch); - var val = getBidi(ch, partPos); - if (bidiOther != null) val.other = getBidi(ch, bidiOther); - return val; - } - - // Used to cheaply estimate the coordinates for a position. Used for - // intermediate scroll updates. - function estimateCoords(cm, pos) { - var left = 0, pos = clipPos(cm.doc, pos); - if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; - var lineObj = getLine(cm.doc, pos.line); - var top = heightAtLine(lineObj) + paddingTop(cm.display); - return {left: left, right: left, top: top, bottom: top + lineObj.height}; - } - - // Positions returned by coordsChar contain some extra information. - // xRel is the relative x position of the input coordinates compared - // to the found position (so xRel > 0 means the coordinates are to - // the right of the character position, for example). When outside - // is true, that means the coordinates lie outside the line's - // vertical range. - function PosWithInfo(line, ch, outside, xRel) { - var pos = Pos(line, ch); - pos.xRel = xRel; - if (outside) pos.outside = true; - return pos; - } - - // Compute the character position closest to the given coordinates. - // Input must be lineSpace-local ("div" coordinate system). - function coordsChar(cm, x, y) { - var doc = cm.doc; - y += cm.display.viewOffset; - if (y < 0) return PosWithInfo(doc.first, 0, true, -1); - var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; - if (lineN > last) - return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); - if (x < 0) x = 0; - - var lineObj = getLine(doc, lineN); - for (;;) { - var found = coordsCharInner(cm, lineObj, lineN, x, y); - var merged = collapsedSpanAtEnd(lineObj); - var mergedPos = merged && merged.find(0, true); - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - lineN = lineNo(lineObj = mergedPos.to.line); - else - return found; - } - } - - function coordsCharInner(cm, lineObj, lineNo, x, y) { - var innerOff = y - heightAtLine(lineObj); - var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; - var preparedMeasure = prepareMeasureForLine(cm, lineObj); - - function getX(ch) { - var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); - wrongLine = true; - if (innerOff > sp.bottom) return sp.left - adjust; - else if (innerOff < sp.top) return sp.left + adjust; - else wrongLine = false; - return sp.left; - } - - var bidi = getOrder(lineObj), dist = lineObj.text.length; - var from = lineLeft(lineObj), to = lineRight(lineObj); - var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; - - if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); - // Do a binary search between these bounds. - for (;;) { - if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { - var ch = x < fromX || x - fromX <= toX - x ? from : to; - var xDiff = x - (ch == from ? fromX : toX); - while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; - var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, - xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); - return pos; - } - var step = Math.ceil(dist / 2), middle = from + step; - if (bidi) { - middle = from; - for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); - } - var middleX = getX(middle); - if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} - else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} - } - } - - var measureText; - // Compute the default text height. - function textHeight(display) { - if (display.cachedTextHeight != null) return display.cachedTextHeight; - if (measureText == null) { - measureText = elt("pre"); - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")); - measureText.appendChild(elt("br")); - } - measureText.appendChild(document.createTextNode("x")); - } - removeChildrenAndAdd(display.measure, measureText); - var height = measureText.offsetHeight / 50; - if (height > 3) display.cachedTextHeight = height; - removeChildren(display.measure); - return height || 1; - } - - // Compute the default character width. - function charWidth(display) { - if (display.cachedCharWidth != null) return display.cachedCharWidth; - var anchor = elt("span", "xxxxxxxxxx"); - var pre = elt("pre", [anchor]); - removeChildrenAndAdd(display.measure, pre); - var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; - if (width > 2) display.cachedCharWidth = width; - return width || 10; - } - - // OPERATIONS - - // Operations are used to wrap a series of changes to the editor - // state in such a way that each change won't have to update the - // cursor and display (which would be awkward, slow, and - // error-prone). Instead, display updates are batched and then all - // combined and executed at once. - - var nextOpId = 0; - // Start a new operation. - function startOperation(cm) { - cm.curOp = { - viewChanged: false, // Flag that indicates that lines might need to be redrawn - startHeight: cm.doc.height, // Used to detect need to update scrollbar - forceUpdate: false, // Used to force a redraw - updateInput: null, // Whether to reset the input textarea - typing: false, // Whether this reset should be careful to leave existing text (for compositing) - changeObjs: null, // Accumulated changes, for firing change events - cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on - selectionChanged: false, // Whether the selection needs to be redrawn - updateMaxLine: false, // Set when the widest line needs to be determined anew - scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet - scrollToPos: null, // Used to scroll to a specific position - id: ++nextOpId // Unique ID - }; - if (!delayedCallbackDepth++) delayedCallbacks = []; - } - - // Finish an operation, updating the display and signalling delayed events - function endOperation(cm) { - var op = cm.curOp, doc = cm.doc, display = cm.display; - cm.curOp = null; - - if (op.updateMaxLine) findMaxLine(cm); - - // If it looks like an update might be needed, call updateDisplay - if (op.viewChanged || op.forceUpdate || op.scrollTop != null || - op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || - op.scrollToPos.to.line >= display.viewTo) || - display.maxLineChanged && cm.options.lineWrapping) { - var updated = updateDisplay(cm, {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); - if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop; - } - // If no update was run, but the selection changed, redraw that. - if (!updated && op.selectionChanged) updateSelection(cm); - if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm); - - // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) { - var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); - display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top; - } - if (op.scrollLeft != null && display.scroller.scrollLeft != op.scrollLeft) { - var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); - display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left; - alignHorizontally(cm); - } - // If we need to scroll a specific position into view, do so. - if (op.scrollToPos) { - var coords = scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from), - clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin); - if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); - } - - if (op.selectionChanged) restartBlink(cm); - - if (cm.state.focused && op.updateInput) - resetInput(cm, op.typing); - - // Fire events for markers that are hidden/unidden by editing or - // undoing - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; - if (hidden) for (var i = 0; i < hidden.length; ++i) - if (!hidden[i].lines.length) signal(hidden[i], "hide"); - if (unhidden) for (var i = 0; i < unhidden.length; ++i) - if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); - - var delayed; - if (!--delayedCallbackDepth) { - delayed = delayedCallbacks; - delayedCallbacks = null; - } - // Fire change events, and delayed event handlers - if (op.changeObjs) - signal(cm, "changes", cm, op.changeObjs); - if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i](); - if (op.cursorActivityHandlers) - for (var i = 0; i < op.cursorActivityHandlers.length; i++) - op.cursorActivityHandlers[i](cm); - } - - // Run the given function in an operation - function runInOp(cm, f) { - if (cm.curOp) return f(); - startOperation(cm); - try { return f(); } - finally { endOperation(cm); } - } - // Wraps a function in an operation. Returns the wrapped function. - function operation(cm, f) { - return function() { - if (cm.curOp) return f.apply(cm, arguments); - startOperation(cm); - try { return f.apply(cm, arguments); } - finally { endOperation(cm); } - }; - } - // Used to add methods to editor and doc instances, wrapping them in - // operations. - function methodOp(f) { - return function() { - if (this.curOp) return f.apply(this, arguments); - startOperation(this); - try { return f.apply(this, arguments); } - finally { endOperation(this); } - }; - } - function docMethodOp(f) { - return function() { - var cm = this.cm; - if (!cm || cm.curOp) return f.apply(this, arguments); - startOperation(cm); - try { return f.apply(this, arguments); } - finally { endOperation(cm); } - }; - } - - // VIEW TRACKING - - // These objects are used to represent the visible (currently drawn) - // part of the document. A LineView may correspond to multiple - // logical lines, if those are connected by collapsed ranges. - function LineView(doc, line, lineN) { - // The starting line - this.line = line; - // Continuing lines, if any - this.rest = visualLineContinued(line); - // Number of logical lines in this visual line - this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; - this.node = this.text = null; - this.hidden = lineIsHidden(doc, line); - } - - // Create a range of LineView objects for the given lines. - function buildViewArray(cm, from, to) { - var array = [], nextPos; - for (var pos = from; pos < to; pos = nextPos) { - var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); - nextPos = pos + view.size; - array.push(view); - } - return array; - } - - // Updates the display.view data structure for a given change to the - // document. From and to are in pre-change coordinates. Lendiff is - // the amount of lines added or subtracted by the change. This is - // used for changes that span multiple lines, or change the way - // lines are divided into visual lines. regLineChange (below) - // registers single-line changes. - function regChange(cm, from, to, lendiff) { - if (from == null) from = cm.doc.first; - if (to == null) to = cm.doc.first + cm.doc.size; - if (!lendiff) lendiff = 0; - - var display = cm.display; - if (lendiff && to < display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers > from)) - display.updateLineNumbers = from; - - cm.curOp.viewChanged = true; - - if (from >= display.viewTo) { // Change after - if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) - resetView(cm); - } else if (to <= display.viewFrom) { // Change before - if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { - resetView(cm); - } else { - display.viewFrom += lendiff; - display.viewTo += lendiff; - } - } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap - resetView(cm); - } else if (from <= display.viewFrom) { // Top overlap - var cut = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cut) { - display.view = display.view.slice(cut.index); - display.viewFrom = cut.lineN; - display.viewTo += lendiff; - } else { - resetView(cm); - } - } else if (to >= display.viewTo) { // Bottom overlap - var cut = viewCuttingPoint(cm, from, from, -1); - if (cut) { - display.view = display.view.slice(0, cut.index); - display.viewTo = cut.lineN; - } else { - resetView(cm); - } - } else { // Gap in the middle - var cutTop = viewCuttingPoint(cm, from, from, -1); - var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cutTop && cutBot) { - display.view = display.view.slice(0, cutTop.index) - .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) - .concat(display.view.slice(cutBot.index)); - display.viewTo += lendiff; - } else { - resetView(cm); - } - } - - var ext = display.externalMeasured; - if (ext) { - if (to < ext.lineN) - ext.lineN += lendiff; - else if (from < ext.lineN + ext.size) - display.externalMeasured = null; - } - } - - // Register a change to a single line. Type must be one of "text", - // "gutter", "class", "widget" - function regLineChange(cm, line, type) { - cm.curOp.viewChanged = true; - var display = cm.display, ext = cm.display.externalMeasured; - if (ext && line >= ext.lineN && line < ext.lineN + ext.size) - display.externalMeasured = null; - - if (line < display.viewFrom || line >= display.viewTo) return; - var lineView = display.view[findViewIndex(cm, line)]; - if (lineView.node == null) return; - var arr = lineView.changes || (lineView.changes = []); - if (indexOf(arr, type) == -1) arr.push(type); - } - - // Clear the view. - function resetView(cm) { - cm.display.viewFrom = cm.display.viewTo = cm.doc.first; - cm.display.view = []; - cm.display.viewOffset = 0; - } - - // Find the view element corresponding to a given line. Return null - // when the line isn't visible. - function findViewIndex(cm, n) { - if (n >= cm.display.viewTo) return null; - n -= cm.display.viewFrom; - if (n < 0) return null; - var view = cm.display.view; - for (var i = 0; i < view.length; i++) { - n -= view[i].size; - if (n < 0) return i; - } - } - - function viewCuttingPoint(cm, oldN, newN, dir) { - var index = findViewIndex(cm, oldN), diff, view = cm.display.view; - if (!sawCollapsedSpans) return {index: index, lineN: newN}; - for (var i = 0, n = cm.display.viewFrom; i < index; i++) - n += view[i].size; - if (n != oldN) { - if (dir > 0) { - if (index == view.length - 1) return null; - diff = (n + view[index].size) - oldN; - index++; - } else { - diff = n - oldN; - } - oldN += diff; newN += diff; - } - while (visualLineNo(cm.doc, newN) != newN) { - if (index == (dir < 0 ? 0 : view.length - 1)) return null; - newN += dir * view[index - (dir < 0 ? 1 : 0)].size; - index += dir; - } - return {index: index, lineN: newN}; - } - - // Force the view to cover a given range, adding empty view element - // or clipping off existing ones as needed. - function adjustView(cm, from, to) { - var display = cm.display, view = display.view; - if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { - display.view = buildViewArray(cm, from, to); - display.viewFrom = from; - } else { - if (display.viewFrom > from) - display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); - else if (display.viewFrom < from) - display.view = display.view.slice(findViewIndex(cm, from)); - display.viewFrom = from; - if (display.viewTo < to) - display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); - else if (display.viewTo > to) - display.view = display.view.slice(0, findViewIndex(cm, to)); - } - display.viewTo = to; - } - - // Count the number of lines in the view whose DOM representation is - // out of date (or nonexistent). - function countDirtyView(cm) { - var view = cm.display.view, dirty = 0; - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; - } - return dirty; - } - - // INPUT HANDLING - - // Poll for input changes, using the normal rate of polling. This - // runs as long as the editor is focused. - function slowPoll(cm) { - if (cm.display.pollingFast) return; - cm.display.poll.set(cm.options.pollInterval, function() { - readInput(cm); - if (cm.state.focused) slowPoll(cm); - }); - } - - // When an event has just come in that is likely to add or change - // something in the input textarea, we poll faster, to ensure that - // the change appears on the screen quickly. - function fastPoll(cm) { - var missed = false; - cm.display.pollingFast = true; - function p() { - var changed = readInput(cm); - if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);} - else {cm.display.pollingFast = false; slowPoll(cm);} - } - cm.display.poll.set(20, p); - } - - // Read input from the textarea, and update the document to match. - // When something is selected, it is present in the textarea, and - // selected (unless it is huge, in which case a placeholder is - // used). When nothing is selected, the cursor sits after previously - // seen text (can be empty), which is stored in prevInput (we must - // not reset the textarea when typing, because that breaks IME). - function readInput(cm) { - var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc; - // Since this is called a *lot*, try to bail out as cheaply as - // possible when it is clear that nothing happened. hasSelection - // will be the case when there is a lot of text in the textarea, - // in which case reading its value would be expensive. - if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput) - return false; - // See paste handler for more on the fakedLastChar kludge - if (cm.state.pasteIncoming && cm.state.fakedLastChar) { - input.value = input.value.substring(0, input.value.length - 1); - cm.state.fakedLastChar = false; - } - var text = input.value; - // If nothing changed, bail. - if (text == prevInput && !cm.somethingSelected()) return false; - // Work around nonsensical selection resetting in IE9/10 - if (ie && !ie_upto8 && cm.display.inputHasSelection === text) { - resetInput(cm); - return false; - } - - var withOp = !cm.curOp; - if (withOp) startOperation(cm); - cm.display.shift = false; - - // Find the part of the input that is actually new - var same = 0, l = Math.min(prevInput.length, text.length); - while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; - var inserted = text.slice(same), textLines = splitLines(inserted); - - // When pasing N lines into N selections, insert one line per selection - var multiPaste = cm.state.pasteIncoming && textLines.length > 1 && doc.sel.ranges.length == textLines.length; - - // Normal behavior is to insert the new text into every selection - for (var i = doc.sel.ranges.length - 1; i >= 0; i--) { - var range = doc.sel.ranges[i]; - var from = range.from(), to = range.to(); - // Handle deletion - if (same < prevInput.length) - from = Pos(from.line, from.ch - (prevInput.length - same)); - // Handle overwrite - else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming) - to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); - var updateInput = cm.curOp.updateInput; - var changeEvent = {from: from, to: to, text: multiPaste ? [textLines[i]] : textLines, - origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"}; - makeChange(cm.doc, changeEvent); - signalLater(cm, "inputRead", cm, changeEvent); - // When an 'electric' character is inserted, immediately trigger a reindent - if (inserted && !cm.state.pasteIncoming && cm.options.electricChars && - cm.options.smartIndent && range.head.ch < 100 && - (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) { - var mode = cm.getModeAt(range.head); - if (mode.electricChars) { - for (var j = 0; j < mode.electricChars.length; j++) - if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { - indentLine(cm, range.head.line, "smart"); - break; - } - } else if (mode.electricInput) { - var end = changeEnd(changeEvent); - if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch))) - indentLine(cm, range.head.line, "smart"); - } - } - } - ensureCursorVisible(cm); - cm.curOp.updateInput = updateInput; - cm.curOp.typing = true; - - // Don't leave long text in the textarea, since it makes further polling slow - if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = ""; - else cm.display.prevInput = text; - if (withOp) endOperation(cm); - cm.state.pasteIncoming = cm.state.cutIncoming = false; - return true; - } - - // Reset the input to correspond to the selection (or to be empty, - // when not typing and nothing is selected) - function resetInput(cm, typing) { - var minimal, selected, doc = cm.doc; - if (cm.somethingSelected()) { - cm.display.prevInput = ""; - var range = doc.sel.primary(); - minimal = hasCopyEvent && - (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); - var content = minimal ? "-" : selected || cm.getSelection(); - cm.display.input.value = content; - if (cm.state.focused) selectInput(cm.display.input); - if (ie && !ie_upto8) cm.display.inputHasSelection = content; - } else if (!typing) { - cm.display.prevInput = cm.display.input.value = ""; - if (ie && !ie_upto8) cm.display.inputHasSelection = null; - } - cm.display.inaccurateSelection = minimal; - } - - function focusInput(cm) { - if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input)) - cm.display.input.focus(); - } - - function ensureFocus(cm) { - if (!cm.state.focused) { focusInput(cm); onFocus(cm); } - } - - function isReadOnly(cm) { - return cm.options.readOnly || cm.doc.cantEdit; - } - - // EVENT HANDLERS - - // Attach the necessary event handlers when initializing the editor - function registerEventHandlers(cm) { - var d = cm.display; - on(d.scroller, "mousedown", operation(cm, onMouseDown)); - // Older IE's will not fire a second mousedown for a double click - if (ie_upto10) - on(d.scroller, "dblclick", operation(cm, function(e) { - if (signalDOMEvent(cm, e)) return; - var pos = posFromMouse(cm, e); - if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; - e_preventDefault(e); - var word = findWordAt(cm.doc, pos); - extendSelection(cm.doc, word.anchor, word.head); - })); - else - on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); - // Prevent normal selection in the editor (we handle our own) - on(d.lineSpace, "selectstart", function(e) { - if (!eventInWidget(d, e)) e_preventDefault(e); - }); - // Some browsers fire contextmenu *after* opening the menu, at - // which point we can't mess with it anymore. Context menu is - // handled in onMouseDown for these browsers. - if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); - - // Sync scrolling between fake scrollbars and real scrollable - // area, ensure viewport is updated when scrolling. - on(d.scroller, "scroll", function() { - if (d.scroller.clientHeight) { - setScrollTop(cm, d.scroller.scrollTop); - setScrollLeft(cm, d.scroller.scrollLeft, true); - signal(cm, "scroll", cm); - } - }); - on(d.scrollbarV, "scroll", function() { - if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop); - }); - on(d.scrollbarH, "scroll", function() { - if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft); - }); - - // Listen to wheel events in order to try and update the viewport on time. - on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); - on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); - - // Prevent clicks in the scrollbars from killing focus - function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); } - on(d.scrollbarH, "mousedown", reFocus); - on(d.scrollbarV, "mousedown", reFocus); - // Prevent wrapper from ever scrolling - on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); - - // When the window resizes, we need to refresh active editors. - var resizeTimer; - function onResize() { - if (resizeTimer == null) resizeTimer = setTimeout(function() { - resizeTimer = null; - // Might be a text scaling operation, clear size caches. - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null; - cm.setSize(); - }, 100); - } - on(window, "resize", onResize); - // The above handler holds on to the editor and its data - // structures. Here we poll to unregister it when the editor is no - // longer in the document, so that it can be garbage-collected. - function unregister() { - if (contains(document.body, d.wrapper)) setTimeout(unregister, 5000); - else off(window, "resize", onResize); - } - setTimeout(unregister, 5000); - - on(d.input, "keyup", operation(cm, onKeyUp)); - on(d.input, "input", function() { - if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; - fastPoll(cm); - }); - on(d.input, "keydown", operation(cm, onKeyDown)); - on(d.input, "keypress", operation(cm, onKeyPress)); - on(d.input, "focus", bind(onFocus, cm)); - on(d.input, "blur", bind(onBlur, cm)); - - function drag_(e) { - if (!signalDOMEvent(cm, e)) e_stop(e); - } - if (cm.options.dragDrop) { - on(d.scroller, "dragstart", function(e){onDragStart(cm, e);}); - on(d.scroller, "dragenter", drag_); - on(d.scroller, "dragover", drag_); - on(d.scroller, "drop", operation(cm, onDrop)); - } - on(d.scroller, "paste", function(e) { - if (eventInWidget(d, e)) return; - cm.state.pasteIncoming = true; - focusInput(cm); - fastPoll(cm); - }); - on(d.input, "paste", function() { - // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206 - // Add a char to the end of textarea before paste occur so that - // selection doesn't span to the end of textarea. - if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) { - var start = d.input.selectionStart, end = d.input.selectionEnd; - d.input.value += "$"; - d.input.selectionStart = start; - d.input.selectionEnd = end; - cm.state.fakedLastChar = true; - } - cm.state.pasteIncoming = true; - fastPoll(cm); - }); - - function prepareCopyCut(e) { - if (cm.somethingSelected()) { - if (d.inaccurateSelection) { - d.prevInput = ""; - d.inaccurateSelection = false; - d.input.value = cm.getSelection(); - selectInput(d.input); - } - } else { - var text = "", ranges = []; - for (var i = 0; i < cm.doc.sel.ranges.length; i++) { - var line = cm.doc.sel.ranges[i].head.line; - var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; - ranges.push(lineRange); - text += cm.getRange(lineRange.anchor, lineRange.head); - } - if (e.type == "cut") { - cm.setSelections(ranges, null, sel_dontScroll); - } else { - d.prevInput = ""; - d.input.value = text; - selectInput(d.input); - } - } - if (e.type == "cut") cm.state.cutIncoming = true; - } - on(d.input, "cut", prepareCopyCut); - on(d.input, "copy", prepareCopyCut); - - // Needed to handle Tab key in KHTML - if (khtml) on(d.sizer, "mouseup", function() { - if (activeElt() == d.input) d.input.blur(); - focusInput(cm); - }); - } - - // MOUSE EVENTS - - // Return true when the given mouse event happened in a widget - function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true; - } - } - - // Given a mouse event, find the corresponding position. If liberal - // is false, it checks whether a gutter or scrollbar was clicked, - // and returns null if it was. forRect is used by rectangular - // selections, and tries to estimate a character position even for - // coordinates beyond the right of the text. - function posFromMouse(cm, e, liberal, forRect) { - var display = cm.display; - if (!liberal) { - var target = e_target(e); - if (target == display.scrollbarH || target == display.scrollbarV || - target == display.scrollbarFiller || target == display.gutterFiller) return null; - } - var x, y, space = display.lineSpace.getBoundingClientRect(); - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX - space.left; y = e.clientY - space.top; } - catch (e) { return null; } - var coords = coordsChar(cm, x, y), line; - if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { - var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; - coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); - } - return coords; - } - - // A mouse down can be a single click, double click, triple click, - // start of selection drag, start of text drag, new cursor - // (ctrl-click), rectangle drag (alt-drag), or xwin - // middle-click-paste. Or it might be a click on something we should - // not interfere with, such as a scrollbar or widget. - function onMouseDown(e) { - if (signalDOMEvent(this, e)) return; - var cm = this, display = cm.display; - display.shift = e.shiftKey; - - if (eventInWidget(display, e)) { - if (!webkit) { - // Briefly turn off draggability, to allow widgets to do - // normal dragging things. - display.scroller.draggable = false; - setTimeout(function(){display.scroller.draggable = true;}, 100); - } - return; - } - if (clickInGutter(cm, e)) return; - var start = posFromMouse(cm, e); - window.focus(); - - switch (e_button(e)) { - case 1: - if (start) - leftButtonDown(cm, e, start); - else if (e_target(e) == display.scroller) - e_preventDefault(e); - break; - case 2: - if (webkit) cm.state.lastMiddleDown = +new Date; - if (start) extendSelection(cm.doc, start); - setTimeout(bind(focusInput, cm), 20); - e_preventDefault(e); - break; - case 3: - if (captureRightClick) onContextMenu(cm, e); - break; - } - } - - var lastClick, lastDoubleClick; - function leftButtonDown(cm, e, start) { - setTimeout(bind(ensureFocus, cm), 0); - - var now = +new Date, type; - if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { - type = "triple"; - } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { - type = "double"; - lastDoubleClick = {time: now, pos: start}; - } else { - type = "single"; - lastClick = {time: now, pos: start}; - } - - var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey; - if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) && - type == "single" && sel.contains(start) > -1 && sel.somethingSelected()) - leftButtonStartDrag(cm, e, start); - else - leftButtonSelect(cm, e, start, type, addNew); - } - - // Start a text drag. When it ends, see if any dragging actually - // happen, and treat as a click if it didn't. - function leftButtonStartDrag(cm, e, start) { - var display = cm.display; - var dragEnd = operation(cm, function(e2) { - if (webkit) display.scroller.draggable = false; - cm.state.draggingText = false; - off(document, "mouseup", dragEnd); - off(display.scroller, "drop", dragEnd); - if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { - e_preventDefault(e2); - extendSelection(cm.doc, start); - focusInput(cm); - // Work around unexplainable focus problem in IE9 (#2127) - if (ie_upto10 && !ie_upto8) - setTimeout(function() {document.body.focus(); focusInput(cm);}, 20); - } - }); - // Let the drag handler handle this. - if (webkit) display.scroller.draggable = true; - cm.state.draggingText = dragEnd; - // IE's approach to draggable - if (display.scroller.dragDrop) display.scroller.dragDrop(); - on(document, "mouseup", dragEnd); - on(display.scroller, "drop", dragEnd); - } - - // Normal selection, as opposed to text dragging. - function leftButtonSelect(cm, e, start, type, addNew) { - var display = cm.display, doc = cm.doc; - e_preventDefault(e); - - var ourRange, ourIndex, startSel = doc.sel; - if (addNew && !e.shiftKey) { - ourIndex = doc.sel.contains(start); - if (ourIndex > -1) - ourRange = doc.sel.ranges[ourIndex]; - else - ourRange = new Range(start, start); - } else { - ourRange = doc.sel.primary(); - } - - if (e.altKey) { - type = "rect"; - if (!addNew) ourRange = new Range(start, start); - start = posFromMouse(cm, e, true, true); - ourIndex = -1; - } else if (type == "double") { - var word = findWordAt(doc, start); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, word.anchor, word.head); - else - ourRange = word; - } else if (type == "triple") { - var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, line.anchor, line.head); - else - ourRange = line; - } else { - ourRange = extendRange(doc, ourRange, start); - } - - if (!addNew) { - ourIndex = 0; - setSelection(doc, new Selection([ourRange], 0), sel_mouse); - startSel = doc.sel; - } else if (ourIndex > -1) { - replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); - } else { - ourIndex = doc.sel.ranges.length; - setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex), - {scroll: false, origin: "*mouse"}); - } - - var lastPos = start; - function extendTo(pos) { - if (cmp(lastPos, pos) == 0) return; - lastPos = pos; - - if (type == "rect") { - var ranges = [], tabSize = cm.options.tabSize; - var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); - var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); - var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); - for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); - line <= end; line++) { - var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); - if (left == right) - ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); - else if (text.length > leftPos) - ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); - } - if (!ranges.length) ranges.push(new Range(start, start)); - setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), sel_mouse); - } else { - var oldRange = ourRange; - var anchor = oldRange.anchor, head = pos; - if (type != "single") { - if (type == "double") - var range = findWordAt(doc, pos); - else - var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); - if (cmp(range.anchor, anchor) > 0) { - head = range.head; - anchor = minPos(oldRange.from(), range.anchor); - } else { - head = range.anchor; - anchor = maxPos(oldRange.to(), range.head); - } - } - var ranges = startSel.ranges.slice(0); - ranges[ourIndex] = new Range(clipPos(doc, anchor), head); - setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); - } - } - - var editorSize = display.wrapper.getBoundingClientRect(); - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0; - - function extend(e) { - var curCount = ++counter; - var cur = posFromMouse(cm, e, true, type == "rect"); - if (!cur) return; - if (cmp(cur, lastPos) != 0) { - ensureFocus(cm); - extendTo(cur); - var visible = visibleLines(display, doc); - if (cur.line >= visible.to || cur.line < visible.from) - setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; - if (outside) setTimeout(operation(cm, function() { - if (counter != curCount) return; - display.scroller.scrollTop += outside; - extend(e); - }), 50); - } - } - - function done(e) { - counter = Infinity; - e_preventDefault(e); - focusInput(cm); - off(document, "mousemove", move); - off(document, "mouseup", up); - doc.history.lastSelOrigin = null; - } - - var move = operation(cm, function(e) { - if ((ie && !ie_upto9) ? !e.buttons : !e_button(e)) done(e); - else extend(e); - }); - var up = operation(cm, done); - on(document, "mousemove", move); - on(document, "mouseup", up); - } - - // Determines whether an event happened in the gutter, and fires the - // handlers for the corresponding event. - function gutterEvent(cm, e, type, prevent, signalfn) { - try { var mX = e.clientX, mY = e.clientY; } - catch(e) { return false; } - if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; - if (prevent) e_preventDefault(e); - - var display = cm.display; - var lineBox = display.lineDiv.getBoundingClientRect(); - - if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); - mY -= lineBox.top - display.viewOffset; - - for (var i = 0; i < cm.options.gutters.length; ++i) { - var g = display.gutters.childNodes[i]; - if (g && g.getBoundingClientRect().right >= mX) { - var line = lineAtHeight(cm.doc, mY); - var gutter = cm.options.gutters[i]; - signalfn(cm, type, cm, line, gutter, e); - return e_defaultPrevented(e); - } - } - } - - function clickInGutter(cm, e) { - return gutterEvent(cm, e, "gutterClick", true, signalLater); - } - - // Kludge to work around strange IE behavior where it'll sometimes - // re-fire a series of drag-related events right after the drop (#1551) - var lastDrop = 0; - - function onDrop(e) { - var cm = this; - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) - return; - e_preventDefault(e); - if (ie) lastDrop = +new Date; - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; - if (!pos || isReadOnly(cm)) return; - // Might be a file drop, in which case we simply extract the text - // and insert it. - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0; - var loadFile = function(file, i) { - var reader = new FileReader; - reader.onload = operation(cm, function() { - text[i] = reader.result; - if (++read == n) { - pos = clipPos(cm.doc, pos); - var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}; - makeChange(cm.doc, change); - setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); - } - }); - reader.readAsText(file); - }; - for (var i = 0; i < n; ++i) loadFile(files[i], i); - } else { // Normal drop - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { - cm.state.draggingText(e); - // Ensure the editor is re-focused - setTimeout(bind(focusInput, cm), 20); - return; - } - try { - var text = e.dataTransfer.getData("Text"); - if (text) { - var selected = cm.state.draggingText && cm.listSelections(); - setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); - if (selected) for (var i = 0; i < selected.length; ++i) - replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); - cm.replaceSelection(text, "around", "paste"); - focusInput(cm); - } - } - catch(e){} - } - } - - function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; - - e.dataTransfer.setData("Text", cm.getSelection()); - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (presto) { - img.width = img.height = 1; - cm.display.wrapper.appendChild(img); - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop; - } - e.dataTransfer.setDragImage(img, 0, 0); - if (presto) img.parentNode.removeChild(img); - } - } - - // SCROLL EVENTS - - // Sync the scrollable area and scrollbars, ensure the viewport - // covers the visible area. - function setScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) return; - cm.doc.scrollTop = val; - if (!gecko) updateDisplay(cm, {top: val}); - if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; - if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val; - if (gecko) updateDisplay(cm); - startWorker(cm, 100); - } - // Sync scroller and scrollbar, ensure the gutter elements are - // aligned. - function setScrollLeft(cm, val, isScroller) { - if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; - val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); - cm.doc.scrollLeft = val; - alignHorizontally(cm); - if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; - if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val; - } - - // Since the delta values reported on mouse wheel events are - // unstandardized between browsers and even browser versions, and - // generally horribly unpredictable, this code starts by measuring - // the scroll effect that the first few mouse wheel events have, - // and, from that, detects the way it can convert deltas to pixel - // offsets afterwards. - // - // The reason we want to know the amount a wheel event will scroll - // is that it gives us a chance to update the display before the - // actual scrolling happens, reducing flickering. - - var wheelSamples = 0, wheelPixelsPerUnit = null; - // Fill in a browser-detected starting value on browsers where we - // know one. These don't have to be accurate -- the result of them - // being wrong would just be a slight flicker on the first wheel - // scroll (if it is large enough). - if (ie) wheelPixelsPerUnit = -.53; - else if (gecko) wheelPixelsPerUnit = 15; - else if (chrome) wheelPixelsPerUnit = -.7; - else if (safari) wheelPixelsPerUnit = -1/3; - - function onScrollWheel(cm, e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY; - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; - else if (dy == null) dy = e.wheelDelta; - - var display = cm.display, scroll = display.scroller; - // Quit if there's nothing to scroll here - if (!(dx && scroll.scrollWidth > scroll.clientWidth || - dy && scroll.scrollHeight > scroll.clientHeight)) return; - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { - for (var i = 0; i < view.length; i++) { - if (view[i].node == cur) { - cm.display.currentWheelTarget = cur; - break outer; - } - } - } - } - - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { - if (dy) - setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); - setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); - e_preventDefault(e); - display.wheelStartX = null; // Abort measurement, if in progress - return; - } - - // 'Project' the visible viewport to cover the area that is being - // scrolled into view (if we know enough to estimate it). - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit; - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; - if (pixels < 0) top = Math.max(0, top + pixels - 50); - else bot = Math.min(cm.doc.height, bot + pixels + 50); - updateDisplay(cm, {top: top, bottom: bot}); - } - - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; - display.wheelDX = dx; display.wheelDY = dy; - setTimeout(function() { - if (display.wheelStartX == null) return; - var movedX = scroll.scrollLeft - display.wheelStartX; - var movedY = scroll.scrollTop - display.wheelStartY; - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX); - display.wheelStartX = display.wheelStartY = null; - if (!sample) return; - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); - ++wheelSamples; - }, 200); - } else { - display.wheelDX += dx; display.wheelDY += dy; - } - } - } - - // KEY EVENTS - - // Run a handler that was bound to a key. - function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound]; - if (!bound) return false; - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false; - var prevShift = cm.display.shift, done = false; - try { - if (isReadOnly(cm)) cm.state.suppressEdits = true; - if (dropShift) cm.display.shift = false; - done = bound(cm) != Pass; - } finally { - cm.display.shift = prevShift; - cm.state.suppressEdits = false; - } - return done; - } - - // Collect the currently active keymaps. - function allKeyMaps(cm) { - var maps = cm.state.keyMaps.slice(0); - if (cm.options.extraKeys) maps.push(cm.options.extraKeys); - maps.push(cm.options.keyMap); - return maps; - } - - var maybeTransition; - // Handle a key from the keydown event. - function handleKeyBinding(cm, e) { - // Handle automatic keymap transitions - var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto; - clearTimeout(maybeTransition); - if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() { - if (getKeyMap(cm.options.keyMap) == startMap) { - cm.options.keyMap = (next.call ? next.call(null, cm) : next); - keyMapChanged(cm); - } - }, 50); - - var name = keyName(e, true), handled = false; - if (!name) return false; - var keymaps = allKeyMaps(cm); - - if (e.shiftKey) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);}) - || lookupKey(name, keymaps, function(b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) - return doHandleBinding(cm, b); - }); - } else { - handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); }); - } - - if (handled) { - e_preventDefault(e); - restartBlink(cm); - signalLater(cm, "keyHandled", cm, name, e); - } - return handled; - } - - // Handle a key from the keypress event - function handleCharBinding(cm, e, ch) { - var handled = lookupKey("'" + ch + "'", allKeyMaps(cm), - function(b) { return doHandleBinding(cm, b, true); }); - if (handled) { - e_preventDefault(e); - restartBlink(cm); - signalLater(cm, "keyHandled", cm, "'" + ch + "'", e); - } - return handled; - } - - var lastStoppedKey = null; - function onKeyDown(e) { - var cm = this; - ensureFocus(cm); - if (signalDOMEvent(cm, e)) return; - // IE does strange things with escape. - if (ie_upto10 && e.keyCode == 27) e.returnValue = false; - var code = e.keyCode; - cm.display.shift = code == 16 || e.shiftKey; - var handled = handleKeyBinding(cm, e); - if (presto) { - lastStoppedKey = handled ? code : null; - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) - cm.replaceSelection("", null, "cut"); - } - - // Turn mouse into crosshair when Alt is held on Mac. - if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) - showCrossHair(cm); - } - - function showCrossHair(cm) { - var lineDiv = cm.display.lineDiv; - addClass(lineDiv, "CodeMirror-crosshair"); - - function up(e) { - if (e.keyCode == 18 || !e.altKey) { - rmClass(lineDiv, "CodeMirror-crosshair"); - off(document, "keyup", up); - off(document, "mouseover", up); - } - } - on(document, "keyup", up); - on(document, "mouseover", up); - } - - function onKeyUp(e) { - if (signalDOMEvent(this, e)) return; - if (e.keyCode == 16) this.doc.sel.shift = false; - } - - function onKeyPress(e) { - var cm = this; - if (signalDOMEvent(cm, e)) return; - var keyCode = e.keyCode, charCode = e.charCode; - if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} - if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return; - var ch = String.fromCharCode(charCode == null ? keyCode : charCode); - if (handleCharBinding(cm, e, ch)) return; - if (ie && !ie_upto8) cm.display.inputHasSelection = null; - fastPoll(cm); - } - - // FOCUS/BLUR EVENTS - - function onFocus(cm) { - if (cm.options.readOnly == "nocursor") return; - if (!cm.state.focused) { - signal(cm, "focus", cm); - cm.state.focused = true; - addClass(cm.display.wrapper, "CodeMirror-focused"); - // The prevInput test prevents this from firing when a context - // menu is closed (since the resetInput would kill the - // select-all detection hack) - if (!cm.curOp && cm.display.selForContextMenu == cm.doc.sel) { - resetInput(cm); - if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730 - } - } - slowPoll(cm); - restartBlink(cm); - } - function onBlur(cm) { - if (cm.state.focused) { - signal(cm, "blur", cm); - cm.state.focused = false; - rmClass(cm.display.wrapper, "CodeMirror-focused"); - } - clearInterval(cm.display.blinker); - setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); - } - - // CONTEXT MENU HANDLING - - var detectingSelectAll; - // To make the context menu work, we need to briefly unhide the - // textarea (making it as unobtrusive as possible) to let the - // right-click take effect on it. - function onContextMenu(cm, e) { - if (signalDOMEvent(cm, e, "contextmenu")) return; - var display = cm.display; - if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return; - - var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; - if (!pos || presto) return; // Opera is difficult. - - // Reset the current text selection only if the click is done outside of the selection - // and 'resetSelectionOnContextMenu' option is true. - var reset = cm.options.resetSelectionOnContextMenu; - if (reset && cm.doc.sel.contains(pos) == -1) - operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); - - var oldCSS = display.input.style.cssText; - display.inputDiv.style.position = "absolute"; - display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + - "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " + - (ie ? "rgba(255, 255, 255, .05)" : "transparent") + - "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; - focusInput(cm); - resetInput(cm); - // Adds "Select all" to context menu in FF - if (!cm.somethingSelected()) display.input.value = display.prevInput = " "; - display.selForContextMenu = cm.doc.sel; - - // Select-all will be greyed out if there's nothing to select, so - // this adds a zero-width space so that we can later check whether - // it got selected. - function prepareSelectAllHack() { - if (display.input.selectionStart != null) { - var selected = cm.somethingSelected(); - var extval = display.input.value = "\u200b" + (selected ? display.input.value : ""); - display.prevInput = selected ? "" : "\u200b"; - display.input.selectionStart = 1; display.input.selectionEnd = extval.length; - } - } - function rehide() { - display.inputDiv.style.position = "relative"; - display.input.style.cssText = oldCSS; - if (ie_upto8) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos; - slowPoll(cm); - - // Try to detect the user choosing select-all - if (display.input.selectionStart != null) { - if (!ie || ie_upto8) prepareSelectAllHack(); - clearTimeout(detectingSelectAll); - var i = 0, poll = function() { - if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0) - operation(cm, commands.selectAll)(cm); - else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500); - else resetInput(cm); - }; - detectingSelectAll = setTimeout(poll, 200); - } - } - - if (ie && !ie_upto8) prepareSelectAllHack(); - if (captureRightClick) { - e_stop(e); - var mouseup = function() { - off(window, "mouseup", mouseup); - setTimeout(rehide, 20); - }; - on(window, "mouseup", mouseup); - } else { - setTimeout(rehide, 50); - } - } - - function contextMenuInGutter(cm, e) { - if (!hasHandler(cm, "gutterContextMenu")) return false; - return gutterEvent(cm, e, "gutterContextMenu", false, signal); - } - - // UPDATING - - // Compute the position of the end of a change (its 'to' property - // refers to the pre-change end). - var changeEnd = CodeMirror.changeEnd = function(change) { - if (!change.text) return change.to; - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); - }; - - // Adjust a position to refer to the post-change position of the - // same text, or the end of the change if the change covers it. - function adjustForChange(pos, change) { - if (cmp(pos, change.from) < 0) return pos; - if (cmp(pos, change.to) <= 0) return changeEnd(change); - - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; - if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; - return Pos(line, ch); - } - - function computeSelAfterChange(doc, change) { - var out = []; - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - out.push(new Range(adjustForChange(range.anchor, change), - adjustForChange(range.head, change))); - } - return normalizeSelection(out, doc.sel.primIndex); - } - - function offsetPos(pos, old, nw) { - if (pos.line == old.line) - return Pos(nw.line, pos.ch - old.ch + nw.ch); - else - return Pos(nw.line + (pos.line - old.line), pos.ch); - } - - // Used by replaceSelections to allow moving the selection to the - // start or around the replaced test. Hint may be "start" or "around". - function computeReplacedSel(doc, changes, hint) { - var out = []; - var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - var from = offsetPos(change.from, oldPrev, newPrev); - var to = offsetPos(changeEnd(change), oldPrev, newPrev); - oldPrev = change.to; - newPrev = to; - if (hint == "around") { - var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; - out[i] = new Range(inv ? to : from, inv ? from : to); - } else { - out[i] = new Range(from, from); - } - } - return new Selection(out, doc.sel.primIndex); - } - - // Allow "beforeChange" event handlers to influence a change - function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function() { this.canceled = true; } - }; - if (update) obj.update = function(from, to, text, origin) { - if (from) this.from = clipPos(doc, from); - if (to) this.to = clipPos(doc, to); - if (text) this.text = text; - if (origin !== undefined) this.origin = origin; - }; - signal(doc, "beforeChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); - - if (obj.canceled) return null; - return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; - } - - // Apply a change to a document, and add it to the document's - // history, and propagating it to all linked documents. - function makeChange(doc, change, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); - if (doc.cm.state.suppressEdits) return; - } - - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true); - if (!change) return; - } - - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); - if (split) { - for (var i = split.length - 1; i >= 0; --i) - makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); - } else { - makeChangeInner(doc, change); - } - } - - function makeChangeInner(doc, change) { - if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; - var selAfter = computeSelAfterChange(doc, change); - addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); - - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); - var rebased = []; - - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); - }); - } - - // Revert a change stored in a document's history. - function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits) return; - - var hist = doc.history, event, selAfter = doc.sel; - var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; - - // Verify that there is a useable event (so that ctrl-z won't - // needlessly clear selection events) - for (var i = 0; i < source.length; i++) { - event = source[i]; - if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) - break; - } - if (i == source.length) return; - hist.lastOrigin = hist.lastSelOrigin = null; - - for (;;) { - event = source.pop(); - if (event.ranges) { - pushSelectionToHistory(event, dest); - if (allowSelectionOnly && !event.equals(doc.sel)) { - setSelection(doc, event, {clearRedo: false}); - return; - } - selAfter = event; - } - else break; - } - - // Build up a reverse change object to add to the opposite history - // stack (redo when undoing, and vice versa). - var antiChanges = []; - pushSelectionToHistory(selAfter, dest); - dest.push({changes: antiChanges, generation: hist.generation}); - hist.generation = event.generation || ++hist.maxGeneration; - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); - - for (var i = event.changes.length - 1; i >= 0; --i) { - var change = event.changes[i]; - change.origin = type; - if (filter && !filterChange(doc, change, false)) { - source.length = 0; - return; - } - - antiChanges.push(historyChangeFromChange(doc, change)); - - var after = i ? computeSelAfterChange(doc, change, null) : lst(source); - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); - if (doc.cm) ensureCursorVisible(doc.cm); - var rebased = []; - - // Propagate to the linked documents - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); - }); - } - } - - // Sub-views need their line numbers shifted when text is added - // above or below them in the parent document. - function shiftDoc(doc, distance) { - doc.first += distance; - doc.sel = new Selection(map(doc.sel.ranges, function(range) { - return new Range(Pos(range.anchor.line + distance, range.anchor.ch), - Pos(range.head.line + distance, range.head.ch)); - }), doc.sel.primIndex); - if (doc.cm) regChange(doc.cm, doc.first, doc.first - distance, distance); - } - - // More lower-level change function, handling only a single document - // (not linked ones). - function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) - return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); - - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); - return; - } - if (change.from.line > doc.lastLine()) return; - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line); - shiftDoc(doc, shift); - change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin}; - } - var last = doc.lastLine(); - if (change.to.line > last) { - change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin}; - } - - change.removed = getBetween(doc, change.from, change.to); - - if (!selAfter) selAfter = computeSelAfterChange(doc, change, null); - if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); - else updateDoc(doc, change, spans); - setSelectionNoUndo(doc, selAfter, sel_dontScroll); - } - - // Handle the interaction of a change to a document with the editor - // that this document is part of. - function makeChangeSingleDocInEditor(cm, change, spans) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to; - - var recomputeMaxLength = false, checkWidthStart = from.line; - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); - doc.iter(checkWidthStart, to.line + 1, function(line) { - if (line == display.maxLine) { - recomputeMaxLength = true; - return true; - } - }); - } - - if (doc.sel.contains(change.from, change.to) > -1) - signalCursorActivity(cm); - - updateDoc(doc, change, spans, estimateHeight(cm)); - - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function(line) { - var len = lineLength(line); - if (len > display.maxLineLength) { - display.maxLine = line; - display.maxLineLength = len; - display.maxLineChanged = true; - recomputeMaxLength = false; - } - }); - if (recomputeMaxLength) cm.curOp.updateMaxLine = true; - } - - // Adjust frontier, schedule worker - doc.frontier = Math.min(doc.frontier, from.line); - startWorker(cm, 400); - - var lendiff = change.text.length - (to.line - from.line) - 1; - // Remember that these lines changed, for updating the display - if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) - regLineChange(cm, from.line, "text"); - else - regChange(cm, from.line, to.line + 1, lendiff); - - var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); - if (changeHandler || changesHandler) { - var obj = { - from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin - }; - if (changeHandler) signalLater(cm, "change", cm, obj); - if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); - } - } - - function replaceRange(doc, code, from, to, origin) { - if (!to) to = from; - if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } - if (typeof code == "string") code = splitLines(code); - makeChange(doc, {from: from, to: to, text: code, origin: origin}); - } - - // SCROLLING THINGS INTO VIEW - - // If an editor sits on the top or bottom of the window, partially - // scrolled out of view, this ensures that the cursor is visible. - function maybeScrollWindow(cm, coords) { - var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; - if (coords.top + box.top < 0) doScroll = true; - else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; - if (doScroll != null && !phantom) { - var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + - (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + - (coords.bottom - coords.top + scrollerCutOff) + "px; left: " + - coords.left + "px; width: 2px;"); - cm.display.lineSpace.appendChild(scrollNode); - scrollNode.scrollIntoView(doScroll); - cm.display.lineSpace.removeChild(scrollNode); - } - } - - // Scroll a given position into view (immediately), verifying that - // it actually became visible (as line heights are accurately - // measured, the position of something may 'drift' during drawing). - function scrollPosIntoView(cm, pos, end, margin) { - if (margin == null) margin = 0; - for (;;) { - var changed = false, coords = cursorCoords(cm, pos); - var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); - var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), - Math.min(coords.top, endCoords.top) - margin, - Math.max(coords.left, endCoords.left), - Math.max(coords.bottom, endCoords.bottom) + margin); - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; - if (scrollPos.scrollTop != null) { - setScrollTop(cm, scrollPos.scrollTop); - if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft); - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; - } - if (!changed) return coords; - } - } - - // Scroll a given set of coordinates into view (immediately). - function scrollIntoView(cm, x1, y1, x2, y2) { - var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); - if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); - if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); - } - - // Calculate a new scroll position needed to scroll the given - // rectangle into view. Returns an object with scrollTop and - // scrollLeft properties. When these are undefined, the - // vertical/horizontal position does not need to be adjusted. - function calculateScrollPos(cm, x1, y1, x2, y2) { - var display = cm.display, snapMargin = textHeight(cm.display); - if (y1 < 0) y1 = 0; - var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; - var screen = display.scroller.clientHeight - scrollerCutOff, result = {}; - var docBottom = cm.doc.height + paddingVert(display); - var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; - if (y1 < screentop) { - result.scrollTop = atTop ? 0 : y1; - } else if (y2 > screentop + screen) { - var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); - if (newTop != screentop) result.scrollTop = newTop; - } - - var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; - var screenw = display.scroller.clientWidth - scrollerCutOff; - x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth; - var gutterw = display.gutters.offsetWidth; - var atLeft = x1 < gutterw + 10; - if (x1 < screenleft + gutterw || atLeft) { - if (atLeft) x1 = 0; - result.scrollLeft = Math.max(0, x1 - 10 - gutterw); - } else if (x2 > screenw + screenleft - 3) { - result.scrollLeft = x2 + 10 - screenw; - } - return result; - } - - // Store a relative adjustment to the scroll position in the current - // operation (to be applied when the operation finishes). - function addToScrollPos(cm, left, top) { - if (left != null || top != null) resolveScrollToPos(cm); - if (left != null) - cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; - if (top != null) - cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; - } - - // Make sure that at the end of the operation the current cursor is - // shown. - function ensureCursorVisible(cm) { - resolveScrollToPos(cm); - var cur = cm.getCursor(), from = cur, to = cur; - if (!cm.options.lineWrapping) { - from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; - to = Pos(cur.line, cur.ch + 1); - } - cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; - } - - // When an operation has its scrollToPos property set, and another - // scroll action is applied before the end of the operation, this - // 'simulates' scrolling that position into view in a cheap way, so - // that the effect of intermediate scroll commands is not ignored. - function resolveScrollToPos(cm) { - var range = cm.curOp.scrollToPos; - if (range) { - cm.curOp.scrollToPos = null; - var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); - var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), - Math.min(from.top, to.top) - range.margin, - Math.max(from.right, to.right), - Math.max(from.bottom, to.bottom) + range.margin); - cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - } - - // API UTILITIES - - // Indent the given line. The how parameter can be "smart", - // "add"/null, "subtract", or "prev". When aggressive is false - // (typically set to true for forced single-line indents), empty - // lines are not indented, and places where the mode returns Pass - // are left alone. - function indentLine(cm, n, how, aggressive) { - var doc = cm.doc, state; - if (how == null) how = "add"; - if (how == "smart") { - // Fall back to "prev" when the mode doesn't have an indentation - // method. - if (!cm.doc.mode.indent) how = "prev"; - else state = getStateBefore(cm, n); - } - - var tabSize = cm.options.tabSize; - var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); - if (line.stateAfter) line.stateAfter = null; - var curSpaceString = line.text.match(/^\s*/)[0], indentation; - if (!aggressive && !/\S/.test(line.text)) { - indentation = 0; - how = "not"; - } else if (how == "smart") { - indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); - if (indentation == Pass) { - if (!aggressive) return; - how = "prev"; - } - } - if (how == "prev") { - if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); - else indentation = 0; - } else if (how == "add") { - indentation = curSpace + cm.options.indentUnit; - } else if (how == "subtract") { - indentation = curSpace - cm.options.indentUnit; - } else if (typeof how == "number") { - indentation = curSpace + how; - } - indentation = Math.max(0, indentation); - - var indentString = "", pos = 0; - if (cm.options.indentWithTabs) - for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} - if (pos < indentation) indentString += spaceStr(indentation - pos); - - if (indentString != curSpaceString) { - replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); - } else { - // Ensure that, if the cursor was in the whitespace at the start - // of the line, it is moved to the end of that space. - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - if (range.head.line == n && range.head.ch < curSpaceString.length) { - var pos = Pos(n, curSpaceString.length); - replaceOneSelection(doc, i, new Range(pos, pos)); - break; - } - } - } - line.stateAfter = null; - } - - // Utility for applying a change to a line by handle or number, - // returning the number and optionally registering the line as - // changed. - function changeLine(cm, handle, changeType, op) { - var no = handle, line = handle, doc = cm.doc; - if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); - else no = lineNo(handle); - if (no == null) return null; - if (op(line, no)) regLineChange(cm, no, changeType); - return line; - } - - // Helper for deleting text near the selection(s), used to implement - // backspace, delete, and similar functionality. - function deleteNearSelection(cm, compute) { - var ranges = cm.doc.sel.ranges, kill = []; - // Build up a set of ranges to kill first, merging overlapping - // ranges. - for (var i = 0; i < ranges.length; i++) { - var toKill = compute(ranges[i]); - while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { - var replaced = kill.pop(); - if (cmp(replaced.from, toKill.from) < 0) { - toKill.from = replaced.from; - break; - } - } - kill.push(toKill); - } - // Next, remove those actual ranges. - runInOp(cm, function() { - for (var i = kill.length - 1; i >= 0; i--) - replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); - ensureCursorVisible(cm); - }); - } - - // Used for horizontal relative motion. Dir is -1 or 1 (left or - // right), unit can be "char", "column" (like char, but doesn't - // cross line boundaries), "word" (across next word), or "group" (to - // the start of next group of word or non-word-non-whitespace - // chars). The visually param controls whether, in right-to-left - // text, direction 1 means to move towards the next index in the - // string, or towards the character to the right of the current - // position. The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosH(doc, pos, dir, unit, visually) { - var line = pos.line, ch = pos.ch, origDir = dir; - var lineObj = getLine(doc, line); - var possible = true; - function findNextLine() { - var l = line + dir; - if (l < doc.first || l >= doc.first + doc.size) return (possible = false); - line = l; - return lineObj = getLine(doc, l); - } - function moveOnce(boundToLine) { - var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); - if (next == null) { - if (!boundToLine && findNextLine()) { - if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); - else ch = dir < 0 ? lineObj.text.length : 0; - } else return (possible = false); - } else ch = next; - return true; - } - - if (unit == "char") moveOnce(); - else if (unit == "column") moveOnce(true); - else if (unit == "word" || unit == "group") { - var sawType = null, group = unit == "group"; - for (var first = true;; first = false) { - if (dir < 0 && !moveOnce(!first)) break; - var cur = lineObj.text.charAt(ch) || "\n"; - var type = isWordChar(cur) ? "w" - : group && cur == "\n" ? "n" - : !group || /\s/.test(cur) ? null - : "p"; - if (group && !first && !type) type = "s"; - if (sawType && sawType != type) { - if (dir < 0) {dir = 1; moveOnce();} - break; - } - - if (type) sawType = type; - if (dir > 0 && !moveOnce(!first)) break; - } - } - var result = skipAtomic(doc, Pos(line, ch), origDir, true); - if (!possible) result.hitSide = true; - return result; - } - - // For relative vertical movement. Dir may be -1 or 1. Unit can be - // "page" or "line". The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosV(cm, pos, dir, unit) { - var doc = cm.doc, x = pos.left, y; - if (unit == "page") { - var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); - y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); - } else if (unit == "line") { - y = dir > 0 ? pos.bottom + 3 : pos.top - 3; - } - for (;;) { - var target = coordsChar(cm, x, y); - if (!target.outside) break; - if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } - y += dir * 5; - } - return target; - } - - // Find the word at the given position (as returned by coordsChar). - function findWordAt(doc, pos) { - var line = getLine(doc, pos.line).text; - var start = pos.ch, end = pos.ch; - if (line) { - if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; - var startChar = line.charAt(start); - var check = isWordChar(startChar) ? isWordChar - : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} - : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; - while (start > 0 && check(line.charAt(start - 1))) --start; - while (end < line.length && check(line.charAt(end))) ++end; - } - return new Range(Pos(pos.line, start), Pos(pos.line, end)); - } - - // EDITOR METHODS - - // The publicly visible API. Note that methodOp(f) means - // 'wrap f in an operation, performed on its `this` parameter'. - - // This is not the complete set of editor methods. Most of the - // methods defined on the Doc type are also injected into - // CodeMirror.prototype, for backwards compatibility and - // convenience. - - CodeMirror.prototype = { - constructor: CodeMirror, - focus: function(){window.focus(); focusInput(this); fastPoll(this);}, - - setOption: function(option, value) { - var options = this.options, old = options[option]; - if (options[option] == value && option != "mode") return; - options[option] = value; - if (optionHandlers.hasOwnProperty(option)) - operation(this, optionHandlers[option])(this, value, old); - }, - - getOption: function(option) {return this.options[option];}, - getDoc: function() {return this.doc;}, - - addKeyMap: function(map, bottom) { - this.state.keyMaps[bottom ? "push" : "unshift"](map); - }, - removeKeyMap: function(map) { - var maps = this.state.keyMaps; - for (var i = 0; i < maps.length; ++i) - if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) { - maps.splice(i, 1); - return true; - } - }, - - addOverlay: methodOp(function(spec, options) { - var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); - if (mode.startState) throw new Error("Overlays may not be stateful."); - this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); - this.state.modeGen++; - regChange(this); - }), - removeOverlay: methodOp(function(spec) { - var overlays = this.state.overlays; - for (var i = 0; i < overlays.length; ++i) { - var cur = overlays[i].modeSpec; - if (cur == spec || typeof spec == "string" && cur.name == spec) { - overlays.splice(i, 1); - this.state.modeGen++; - regChange(this); - return; - } - } - }), - - indentLine: methodOp(function(n, dir, aggressive) { - if (typeof dir != "string" && typeof dir != "number") { - if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; - else dir = dir ? "add" : "subtract"; - } - if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); - }), - indentSelection: methodOp(function(how) { - var ranges = this.doc.sel.ranges, end = -1; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - if (!range.empty()) { - var start = Math.max(end, range.from().line); - var to = range.to(); - end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; - for (var j = start; j < end; ++j) - indentLine(this, j, how); - } else if (range.head.line > end) { - indentLine(this, range.head.line, how, true); - end = range.head.line; - if (i == this.doc.sel.primIndex) ensureCursorVisible(this); - } - } - }), - - // Fetch the parser token for a given character. Useful for hacks - // that want to inspect the mode state (say, for completion). - getTokenAt: function(pos, precise) { - var doc = this.doc; - pos = clipPos(doc, pos); - var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode; - var line = getLine(doc, pos.line); - var stream = new StringStream(line.text, this.options.tabSize); - while (stream.pos < pos.ch && !stream.eol()) { - stream.start = stream.pos; - var style = readToken(mode, stream, state); - } - return {start: stream.start, - end: stream.pos, - string: stream.current(), - type: style || null, - state: state}; - }, - - getTokenTypeAt: function(pos) { - pos = clipPos(this.doc, pos); - var styles = getLineStyles(this, getLine(this.doc, pos.line)); - var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; - var type; - if (ch == 0) type = styles[2]; - else for (;;) { - var mid = (before + after) >> 1; - if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; - else if (styles[mid * 2 + 1] < ch) before = mid + 1; - else { type = styles[mid * 2 + 2]; break; } - } - var cut = type ? type.indexOf("cm-overlay ") : -1; - return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); - }, - - getModeAt: function(pos) { - var mode = this.doc.mode; - if (!mode.innerMode) return mode; - return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; - }, - - getHelper: function(pos, type) { - return this.getHelpers(pos, type)[0]; - }, - - getHelpers: function(pos, type) { - var found = []; - if (!helpers.hasOwnProperty(type)) return helpers; - var help = helpers[type], mode = this.getModeAt(pos); - if (typeof mode[type] == "string") { - if (help[mode[type]]) found.push(help[mode[type]]); - } else if (mode[type]) { - for (var i = 0; i < mode[type].length; i++) { - var val = help[mode[type][i]]; - if (val) found.push(val); - } - } else if (mode.helperType && help[mode.helperType]) { - found.push(help[mode.helperType]); - } else if (help[mode.name]) { - found.push(help[mode.name]); - } - for (var i = 0; i < help._global.length; i++) { - var cur = help._global[i]; - if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) - found.push(cur.val); - } - return found; - }, - - getStateAfter: function(line, precise) { - var doc = this.doc; - line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); - return getStateBefore(this, line + 1, precise); - }, - - cursorCoords: function(start, mode) { - var pos, range = this.doc.sel.primary(); - if (start == null) pos = range.head; - else if (typeof start == "object") pos = clipPos(this.doc, start); - else pos = start ? range.from() : range.to(); - return cursorCoords(this, pos, mode || "page"); - }, - - charCoords: function(pos, mode) { - return charCoords(this, clipPos(this.doc, pos), mode || "page"); - }, - - coordsChar: function(coords, mode) { - coords = fromCoordSystem(this, coords, mode || "page"); - return coordsChar(this, coords.left, coords.top); - }, - - lineAtHeight: function(height, mode) { - height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; - return lineAtHeight(this.doc, height + this.display.viewOffset); - }, - heightAtLine: function(line, mode) { - var end = false, last = this.doc.first + this.doc.size - 1; - if (line < this.doc.first) line = this.doc.first; - else if (line > last) { line = last; end = true; } - var lineObj = getLine(this.doc, line); - return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + - (end ? this.doc.height - heightAtLine(lineObj) : 0); - }, - - defaultTextHeight: function() { return textHeight(this.display); }, - defaultCharWidth: function() { return charWidth(this.display); }, - - setGutterMarker: methodOp(function(line, gutterID, value) { - return changeLine(this, line, "gutter", function(line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}); - markers[gutterID] = value; - if (!value && isEmpty(markers)) line.gutterMarkers = null; - return true; - }); - }), - - clearGutter: methodOp(function(gutterID) { - var cm = this, doc = cm.doc, i = doc.first; - doc.iter(function(line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - line.gutterMarkers[gutterID] = null; - regLineChange(cm, i, "gutter"); - if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; - } - ++i; - }); - }), - - addLineClass: methodOp(function(handle, where, cls) { - return changeLine(this, handle, "class", function(line) { - var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; - if (!line[prop]) line[prop] = cls; - else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false; - else line[prop] += " " + cls; - return true; - }); - }), - - removeLineClass: methodOp(function(handle, where, cls) { - return changeLine(this, handle, "class", function(line) { - var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; - var cur = line[prop]; - if (!cur) return false; - else if (cls == null) line[prop] = null; - else { - var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)")); - if (!found) return false; - var end = found.index + found[0].length; - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; - } - return true; - }); - }), - - addLineWidget: methodOp(function(handle, node, options) { - return addLineWidget(this, handle, node, options); - }), - - removeLineWidget: function(widget) { widget.clear(); }, - - lineInfo: function(line) { - if (typeof line == "number") { - if (!isLine(this.doc, line)) return null; - var n = line; - line = getLine(this.doc, line); - if (!line) return null; - } else { - var n = lineNo(line); - if (n == null) return null; - } - return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets}; - }, - - getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, - - addWidget: function(pos, node, scroll, vert, horiz) { - var display = this.display; - pos = cursorCoords(this, clipPos(this.doc, pos)); - var top = pos.bottom, left = pos.left; - node.style.position = "absolute"; - display.sizer.appendChild(node); - if (vert == "over") { - top = pos.top; - } else if (vert == "above" || vert == "near") { - var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), - hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); - // Default to positioning above (if specified and possible); otherwise default to positioning below - if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) - top = pos.top - node.offsetHeight; - else if (pos.bottom + node.offsetHeight <= vspace) - top = pos.bottom; - if (left + node.offsetWidth > hspace) - left = hspace - node.offsetWidth; - } - node.style.top = top + "px"; - node.style.left = node.style.right = ""; - if (horiz == "right") { - left = display.sizer.clientWidth - node.offsetWidth; - node.style.right = "0px"; - } else { - if (horiz == "left") left = 0; - else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; - node.style.left = left + "px"; - } - if (scroll) - scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); - }, - - triggerOnKeyDown: methodOp(onKeyDown), - triggerOnKeyPress: methodOp(onKeyPress), - triggerOnKeyUp: methodOp(onKeyUp), - - execCommand: function(cmd) { - if (commands.hasOwnProperty(cmd)) - return commands[cmd](this); - }, - - findPosH: function(from, amount, unit, visually) { - var dir = 1; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - cur = findPosH(this.doc, cur, dir, unit, visually); - if (cur.hitSide) break; - } - return cur; - }, - - moveH: methodOp(function(dir, unit) { - var cm = this; - cm.extendSelectionsBy(function(range) { - if (cm.display.shift || cm.doc.extend || range.empty()) - return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); - else - return dir < 0 ? range.from() : range.to(); - }, sel_move); - }), - - deleteH: methodOp(function(dir, unit) { - var sel = this.doc.sel, doc = this.doc; - if (sel.somethingSelected()) - doc.replaceSelection("", null, "+delete"); - else - deleteNearSelection(this, function(range) { - var other = findPosH(doc, range.head, dir, unit, false); - return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; - }); - }), - - findPosV: function(from, amount, unit, goalColumn) { - var dir = 1, x = goalColumn; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - var coords = cursorCoords(this, cur, "div"); - if (x == null) x = coords.left; - else coords.left = x; - cur = findPosV(this, coords, dir, unit); - if (cur.hitSide) break; - } - return cur; - }, - - moveV: methodOp(function(dir, unit) { - var cm = this, doc = this.doc, goals = []; - var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); - doc.extendSelectionsBy(function(range) { - if (collapse) - return dir < 0 ? range.from() : range.to(); - var headPos = cursorCoords(cm, range.head, "div"); - if (range.goalColumn != null) headPos.left = range.goalColumn; - goals.push(headPos.left); - var pos = findPosV(cm, headPos, dir, unit); - if (unit == "page" && range == doc.sel.primary()) - addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); - return pos; - }, sel_move); - if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) - doc.sel.ranges[i].goalColumn = goals[i]; - }), - - toggleOverwrite: function(value) { - if (value != null && value == this.state.overwrite) return; - if (this.state.overwrite = !this.state.overwrite) - addClass(this.display.cursorDiv, "CodeMirror-overwrite"); - else - rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); - - signal(this, "overwriteToggle", this, this.state.overwrite); - }, - hasFocus: function() { return activeElt() == this.display.input; }, - - scrollTo: methodOp(function(x, y) { - if (x != null || y != null) resolveScrollToPos(this); - if (x != null) this.curOp.scrollLeft = x; - if (y != null) this.curOp.scrollTop = y; - }), - getScrollInfo: function() { - var scroller = this.display.scroller, co = scrollerCutOff; - return {left: scroller.scrollLeft, top: scroller.scrollTop, - height: scroller.scrollHeight - co, width: scroller.scrollWidth - co, - clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co}; - }, - - scrollIntoView: methodOp(function(range, margin) { - if (range == null) { - range = {from: this.doc.sel.primary().head, to: null}; - if (margin == null) margin = this.options.cursorScrollMargin; - } else if (typeof range == "number") { - range = {from: Pos(range, 0), to: null}; - } else if (range.from == null) { - range = {from: range, to: null}; - } - if (!range.to) range.to = range.from; - range.margin = margin || 0; - - if (range.from.line != null) { - resolveScrollToPos(this); - this.curOp.scrollToPos = range; - } else { - var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), - Math.min(range.from.top, range.to.top) - range.margin, - Math.max(range.from.right, range.to.right), - Math.max(range.from.bottom, range.to.bottom) + range.margin); - this.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - }), - - setSize: methodOp(function(width, height) { - function interpret(val) { - return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; - } - if (width != null) this.display.wrapper.style.width = interpret(width); - if (height != null) this.display.wrapper.style.height = interpret(height); - if (this.options.lineWrapping) clearLineMeasurementCache(this); - this.curOp.forceUpdate = true; - signal(this, "refresh", this); - }), - - operation: function(f){return runInOp(this, f);}, - - refresh: methodOp(function() { - var oldHeight = this.display.cachedTextHeight; - regChange(this); - this.curOp.forceUpdate = true; - clearCaches(this); - this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); - updateGutterSpace(this); - if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) - estimateLineHeights(this); - signal(this, "refresh", this); - }), - - swapDoc: methodOp(function(doc) { - var old = this.doc; - old.cm = null; - attachDoc(this, doc); - clearCaches(this); - resetInput(this); - this.scrollTo(doc.scrollLeft, doc.scrollTop); - signalLater(this, "swapDoc", this, old); - return old; - }), - - getInputField: function(){return this.display.input;}, - getWrapperElement: function(){return this.display.wrapper;}, - getScrollerElement: function(){return this.display.scroller;}, - getGutterElement: function(){return this.display.gutters;} - }; - eventMixin(CodeMirror); - - // OPTION DEFAULTS - - // The default configuration options. - var defaults = CodeMirror.defaults = {}; - // Functions to run when options are changed. - var optionHandlers = CodeMirror.optionHandlers = {}; - - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt; - if (handle) optionHandlers[name] = - notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; - } - - // Passed to option handlers when there is no old value. - var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function(cm, val) { - cm.setValue(val); - }, true); - option("mode", null, function(cm, val) { - cm.doc.modeOption = val; - loadMode(cm); - }, true); - - option("indentUnit", 2, loadMode, true); - option("indentWithTabs", false); - option("smartIndent", true); - option("tabSize", 4, function(cm) { - resetModeState(cm); - clearCaches(cm); - regChange(cm); - }, true); - option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) { - cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); - cm.refresh(); - }, true); - option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); - option("electricChars", true); - option("rtlMoveVisually", !windows); - option("wholeLineUpdateBefore", true); - - option("theme", "default", function(cm) { - themeChanged(cm); - guttersChanged(cm); - }, true); - option("keyMap", "default", keyMapChanged); - option("extraKeys", null); - - option("lineWrapping", false, wrappingChanged, true); - option("gutters", [], function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("fixedGutter", true, function(cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; - cm.refresh(); - }, true); - option("coverGutterNextToScrollbar", false, updateScrollbars, true); - option("lineNumbers", false, function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("firstLineNumber", 1, guttersChanged, true); - option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); - option("showCursorWhenSelecting", false, updateSelection, true); - - option("resetSelectionOnContextMenu", true); - - option("readOnly", false, function(cm, val) { - if (val == "nocursor") { - onBlur(cm); - cm.display.input.blur(); - cm.display.disabled = true; - } else { - cm.display.disabled = false; - if (!val) resetInput(cm); - } - }); - option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true); - option("dragDrop", true); - - option("cursorBlinkRate", 530); - option("cursorScrollMargin", 0); - option("cursorHeight", 1); - option("workTime", 100); - option("workDelay", 100); - option("flattenSpans", true, resetModeState, true); - option("addModeClass", false, resetModeState, true); - option("pollInterval", 100); - option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); - option("historyEventDelay", 1250); - option("viewportMargin", 10, function(cm){cm.refresh();}, true); - option("maxHighlightLength", 10000, resetModeState, true); - option("moveInputWithCursor", true, function(cm, val) { - if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0; - }); - - option("tabindex", null, function(cm, val) { - cm.display.input.tabIndex = val || ""; - }); - option("autofocus", null); - - // MODE DEFINITION AND QUERYING - - // Known modes, by name and by MIME - var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; - - // Extra arguments are stored as the mode's dependencies, which is - // used by (legacy) mechanisms like loadmode.js to automatically - // load a mode. (Preferred mechanism is the require/define calls.) - CodeMirror.defineMode = function(name, mode) { - if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; - if (arguments.length > 2) { - mode.dependencies = []; - for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); - } - modes[name] = mode; - }; - - CodeMirror.defineMIME = function(mime, spec) { - mimeModes[mime] = spec; - }; - - // Given a MIME type, a {name, ...options} config object, or a name - // string, return a mode config object. - CodeMirror.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name]; - if (typeof found == "string") found = {name: found}; - spec = createObj(found, spec); - spec.name = found.name; - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return CodeMirror.resolveMode("application/xml"); - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; - }; - - // Given a mode spec (anything that resolveMode accepts), find and - // initialize an actual mode object. - CodeMirror.getMode = function(options, spec) { - var spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) return CodeMirror.getMode(options, "text/plain"); - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) continue; - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - if (spec.helperType) modeObj.helperType = spec.helperType; - if (spec.modeProps) for (var prop in spec.modeProps) - modeObj[prop] = spec.modeProps[prop]; - - return modeObj; - }; - - // Minimal default mode. - CodeMirror.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; - }); - CodeMirror.defineMIME("text/plain", "null"); - - // This can be used to attach properties to mode objects from - // outside the actual mode definition. - var modeExtensions = CodeMirror.modeExtensions = {}; - CodeMirror.extendMode = function(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); - }; - - // EXTENSIONS - - CodeMirror.defineExtension = function(name, func) { - CodeMirror.prototype[name] = func; - }; - CodeMirror.defineDocExtension = function(name, func) { - Doc.prototype[name] = func; - }; - CodeMirror.defineOption = option; - - var initHooks = []; - CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; - - var helpers = CodeMirror.helpers = {}; - CodeMirror.registerHelper = function(type, name, value) { - if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; - helpers[type][name] = value; - }; - CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { - CodeMirror.registerHelper(type, name, value); - helpers[type]._global.push({pred: predicate, val: value}); - }; - - // MODE STATE HANDLING - - // Utility functions for working with state. Exported because nested - // modes need to do this for their inner modes. - - var copyState = CodeMirror.copyState = function(mode, state) { - if (state === true) return state; - if (mode.copyState) return mode.copyState(state); - var nstate = {}; - for (var n in state) { - var val = state[n]; - if (val instanceof Array) val = val.concat([]); - nstate[n] = val; - } - return nstate; - }; - - var startState = CodeMirror.startState = function(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; - }; - - // Given a mode and a state (for that mode), find the inner mode and - // state at the position that the state refers to. - CodeMirror.innerMode = function(mode, state) { - while (mode.innerMode) { - var info = mode.innerMode(state); - if (!info || info.mode == mode) break; - state = info.state; - mode = info.mode; - } - return info || {mode: mode, state: state}; - }; - - // STANDARD COMMANDS - - // Commands are parameter-less actions that can be performed on an - // editor, mostly used for keybindings. - var commands = CodeMirror.commands = { - selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, - singleSelection: function(cm) { - cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); - }, - killLine: function(cm) { - deleteNearSelection(cm, function(range) { - if (range.empty()) { - var len = getLine(cm.doc, range.head.line).text.length; - if (range.head.ch == len && range.head.line < cm.lastLine()) - return {from: range.head, to: Pos(range.head.line + 1, 0)}; - else - return {from: range.head, to: Pos(range.head.line, len)}; - } else { - return {from: range.from(), to: range.to()}; - } - }); - }, - deleteLine: function(cm) { - deleteNearSelection(cm, function(range) { - return {from: Pos(range.from().line, 0), - to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; - }); - }, - delLineLeft: function(cm) { - deleteNearSelection(cm, function(range) { - return {from: Pos(range.from().line, 0), to: range.from()}; - }); - }, - undo: function(cm) {cm.undo();}, - redo: function(cm) {cm.redo();}, - undoSelection: function(cm) {cm.undoSelection();}, - redoSelection: function(cm) {cm.redoSelection();}, - goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, - goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, - goLineStart: function(cm) { - cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, sel_move); - }, - goLineStartSmart: function(cm) { - cm.extendSelectionsBy(function(range) { - var start = lineStart(cm, range.head.line); - var line = cm.getLineHandle(start.line); - var order = getOrder(line); - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(0, line.text.search(/\S/)); - var inWS = range.head.line == start.line && range.head.ch <= firstNonWS && range.head.ch; - return Pos(start.line, inWS ? 0 : firstNonWS); - } - return start; - }, sel_move); - }, - goLineEnd: function(cm) { - cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, sel_move); - }, - goLineRight: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); - }, sel_move); - }, - goLineLeft: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({left: 0, top: top}, "div"); - }, sel_move); - }, - goLineUp: function(cm) {cm.moveV(-1, "line");}, - goLineDown: function(cm) {cm.moveV(1, "line");}, - goPageUp: function(cm) {cm.moveV(-1, "page");}, - goPageDown: function(cm) {cm.moveV(1, "page");}, - goCharLeft: function(cm) {cm.moveH(-1, "char");}, - goCharRight: function(cm) {cm.moveH(1, "char");}, - goColumnLeft: function(cm) {cm.moveH(-1, "column");}, - goColumnRight: function(cm) {cm.moveH(1, "column");}, - goWordLeft: function(cm) {cm.moveH(-1, "word");}, - goGroupRight: function(cm) {cm.moveH(1, "group");}, - goGroupLeft: function(cm) {cm.moveH(-1, "group");}, - goWordRight: function(cm) {cm.moveH(1, "word");}, - delCharBefore: function(cm) {cm.deleteH(-1, "char");}, - delCharAfter: function(cm) {cm.deleteH(1, "char");}, - delWordBefore: function(cm) {cm.deleteH(-1, "word");}, - delWordAfter: function(cm) {cm.deleteH(1, "word");}, - delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, - delGroupAfter: function(cm) {cm.deleteH(1, "group");}, - indentAuto: function(cm) {cm.indentSelection("smart");}, - indentMore: function(cm) {cm.indentSelection("add");}, - indentLess: function(cm) {cm.indentSelection("subtract");}, - insertTab: function(cm) {cm.replaceSelection("\t");}, - insertSoftTab: function(cm) { - var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].from(); - var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); - spaces.push(new Array(tabSize - col % tabSize + 1).join(" ")); - } - cm.replaceSelections(spaces); - }, - defaultTab: function(cm) { - if (cm.somethingSelected()) cm.indentSelection("add"); - else cm.execCommand("insertTab"); - }, - transposeChars: function(cm) { - runInOp(cm, function() { - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; - if (cur.ch > 0 && cur.ch < line.length - 1) - cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1), - Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); - } - }); - }, - newlineAndIndent: function(cm) { - runInOp(cm, function() { - var len = cm.listSelections().length; - for (var i = 0; i < len; i++) { - var range = cm.listSelections()[i]; - cm.replaceRange("\n", range.anchor, range.head, "+input"); - cm.indentLine(range.from().line + 1, null, true); - ensureCursorVisible(cm); - } - }); - }, - toggleOverwrite: function(cm) {cm.toggleOverwrite();} - }; - - // STANDARD KEYMAPS - - var keyMap = CodeMirror.keyMap = {}; - keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", - "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", - "Esc": "singleSelection" - }; - // Note that the save and find-related commands aren't defined by - // default. User code or addons can define them. Unknown commands - // are simply ignored. - keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" - }; - keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft", - "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", - fallthrough: ["basic", "emacsy"] - }; - // Very basic readline/emacs-style bindings, which are standard on Mac. - keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" - }; - keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; - - // KEYMAP DISPATCH - - function getKeyMap(val) { - if (typeof val == "string") return keyMap[val]; - else return val; - } - - // Given an array of keymaps and a key name, call handle on any - // bindings found, until that returns a truthy value, at which point - // we consider the key handled. Implements things like binding a key - // to false stopping further handling and keymap fallthrough. - var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) { - function lookup(map) { - map = getKeyMap(map); - var found = map[name]; - if (found === false) return "stop"; - if (found != null && handle(found)) return true; - if (map.nofallthrough) return "stop"; - - var fallthrough = map.fallthrough; - if (fallthrough == null) return false; - if (Object.prototype.toString.call(fallthrough) != "[object Array]") - return lookup(fallthrough); - for (var i = 0; i < fallthrough.length; ++i) { - var done = lookup(fallthrough[i]); - if (done) return done; - } - return false; - } - - for (var i = 0; i < maps.length; ++i) { - var done = lookup(maps[i]); - if (done) return done != "stop"; - } - }; - - // Modifier key presses don't count as 'real' key presses for the - // purpose of keymap fallthrough. - var isModifierKey = CodeMirror.isModifierKey = function(event) { - var name = keyNames[event.keyCode]; - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; - }; - - // Look up the name of a key as indicated by an event object. - var keyName = CodeMirror.keyName = function(event, noShift) { - if (presto && event.keyCode == 34 && event["char"]) return false; - var name = keyNames[event.keyCode]; - if (name == null || event.altGraphKey) return false; - if (event.altKey) name = "Alt-" + name; - if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name; - if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name; - if (!noShift && event.shiftKey) name = "Shift-" + name; - return name; - }; - - // FROMTEXTAREA - - CodeMirror.fromTextArea = function(textarea, options) { - if (!options) options = {}; - options.value = textarea.value; - if (!options.tabindex && textarea.tabindex) - options.tabindex = textarea.tabindex; - if (!options.placeholder && textarea.placeholder) - options.placeholder = textarea.placeholder; - // Set autofocus to true if this textarea is focused, or if it has - // autofocus and no other element is focused. - if (options.autofocus == null) { - var hasFocus = activeElt(); - options.autofocus = hasFocus == textarea || - textarea.getAttribute("autofocus") != null && hasFocus == document.body; - } - - function save() {textarea.value = cm.getValue();} - if (textarea.form) { - on(textarea.form, "submit", save); - // Deplorable hack to make the submit method do the right thing. - if (!options.leaveSubmitMethodAlone) { - var form = textarea.form, realSubmit = form.submit; - try { - var wrappedSubmit = form.submit = function() { - save(); - form.submit = realSubmit; - form.submit(); - form.submit = wrappedSubmit; - }; - } catch(e) {} - } - } - - textarea.style.display = "none"; - var cm = CodeMirror(function(node) { - textarea.parentNode.insertBefore(node, textarea.nextSibling); - }, options); - cm.save = save; - cm.getTextArea = function() { return textarea; }; - cm.toTextArea = function() { - save(); - textarea.parentNode.removeChild(cm.getWrapperElement()); - textarea.style.display = ""; - if (textarea.form) { - off(textarea.form, "submit", save); - if (typeof textarea.form.submit == "function") - textarea.form.submit = realSubmit; - } - }; - return cm; - }; - - // STRING STREAM - - // Fed to the mode parsers, provides helper functions to make - // parsers more succinct. - - var StringStream = CodeMirror.StringStream = function(string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; - }; - - StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == this.lineStart;}, - peek: function() {return this.string.charAt(this.pos) || undefined;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - indentation: function() { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } - }; - - // TEXTMARKERS - - // Created with markText and setBookmark methods. A TextMarker is a - // handle that can be used to clear or find a marked position in the - // document. Line objects hold arrays (markedSpans) containing - // {from, to, marker} object pointing to such marker objects, and - // indicating that such a marker is present on that line. Multiple - // lines may point to the same marker when it spans across lines. - // The spans will have null for their from/to properties when the - // marker continues beyond the start/end of the line. Markers have - // links back to the lines they currently touch. - - var TextMarker = CodeMirror.TextMarker = function(doc, type) { - this.lines = []; - this.type = type; - this.doc = doc; - }; - eventMixin(TextMarker); - - // Clear the marker. - TextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - var cm = this.doc.cm, withOp = cm && !cm.curOp; - if (withOp) startOperation(cm); - if (hasHandler(this, "clear")) { - var found = this.find(); - if (found) signalLater(this, "clear", found.from, found.to); - } - var min = null, max = null; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); - else if (cm) { - if (span.to != null) max = lineNo(line); - if (span.from != null) min = lineNo(line); - } - line.markedSpans = removeMarkedSpan(line.markedSpans, span); - if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) - updateLineHeight(line, textHeight(cm.display)); - } - if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { - var visual = visualLine(this.lines[i]), len = lineLength(visual); - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual; - cm.display.maxLineLength = len; - cm.display.maxLineChanged = true; - } - } - - if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); - this.lines.length = 0; - this.explicitlyCleared = true; - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false; - if (cm) reCheckSelection(cm.doc); - } - if (cm) signalLater(cm, "markerCleared", cm, this); - if (withOp) endOperation(cm); - if (this.parent) this.parent.clear(); - }; - - // Find the position of the marker in the document. Returns a {from, - // to} object by default. Side can be passed to get a specific side - // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the - // Pos objects returned contain a line object, rather than a line - // number (used to prevent looking up the same line twice). - TextMarker.prototype.find = function(side, lineObj) { - if (side == null && this.type == "bookmark") side = 1; - var from, to; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.from != null) { - from = Pos(lineObj ? line : lineNo(line), span.from); - if (side == -1) return from; - } - if (span.to != null) { - to = Pos(lineObj ? line : lineNo(line), span.to); - if (side == 1) return to; - } - } - return from && {from: from, to: to}; - }; - - // Signals that the marker's widget changed, and surrounding layout - // should be recomputed. - TextMarker.prototype.changed = function() { - var pos = this.find(-1, true), widget = this, cm = this.doc.cm; - if (!pos || !cm) return; - runInOp(cm, function() { - var line = pos.line, lineN = lineNo(pos.line); - var view = findViewForLine(cm, lineN); - if (view) { - clearLineMeasurementCacheFor(view); - cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; - } - cm.curOp.updateMaxLine = true; - if (!lineIsHidden(widget.doc, line) && widget.height != null) { - var oldHeight = widget.height; - widget.height = null; - var dHeight = widgetHeight(widget) - oldHeight; - if (dHeight) - updateLineHeight(line, line.height + dHeight); - } - }); - }; - - TextMarker.prototype.attachLine = function(line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) - (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); - } - this.lines.push(line); - }; - TextMarker.prototype.detachLine = function(line) { - this.lines.splice(indexOf(this.lines, line), 1); - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); - } - }; - - // Collapsed markers have unique ids, in order to be able to order - // them, which is needed for uniquely determining an outer marker - // when they overlap (they may nest, but not partially overlap). - var nextMarkerId = 0; - - // Create a marker, wire it up to the right lines, and - function markText(doc, from, to, options, type) { - // Shared markers (across linked documents) are handled separately - // (markTextShared will call out to this again, once per - // document). - if (options && options.shared) return markTextShared(doc, from, to, options, type); - // Ensure we are in an operation. - if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); - - var marker = new TextMarker(doc, type), diff = cmp(from, to); - if (options) copyObj(options, marker, false); - // Don't connect empty markers unless clearWhenEmpty is false - if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) - return marker; - if (marker.replacedWith) { - // Showing up as a widget implies collapsed (widget replaces text) - marker.collapsed = true; - marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); - if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true; - if (options.insertLeft) marker.widgetNode.insertLeft = true; - } - if (marker.collapsed) { - if (conflictingCollapsedRange(doc, from.line, from, to, marker) || - from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) - throw new Error("Inserting collapsed marker partially overlapping an existing one"); - sawCollapsedSpans = true; - } - - if (marker.addToHistory) - addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); - - var curLine = from.line, cm = doc.cm, updateMaxLine; - doc.iter(curLine, to.line + 1, function(line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) - updateMaxLine = true; - if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); - addMarkedSpan(line, new MarkedSpan(marker, - curLine == from.line ? from.ch : null, - curLine == to.line ? to.ch : null)); - ++curLine; - }); - // lineIsHidden depends on the presence of the spans, so needs a second pass - if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { - if (lineIsHidden(doc, line)) updateLineHeight(line, 0); - }); - - if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); - - if (marker.readOnly) { - sawReadOnlySpans = true; - if (doc.history.done.length || doc.history.undone.length) - doc.clearHistory(); - } - if (marker.collapsed) { - marker.id = ++nextMarkerId; - marker.atomic = true; - } - if (cm) { - // Sync editor state - if (updateMaxLine) cm.curOp.updateMaxLine = true; - if (marker.collapsed) - regChange(cm, from.line, to.line + 1); - else if (marker.className || marker.title || marker.startStyle || marker.endStyle) - for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); - if (marker.atomic) reCheckSelection(cm.doc); - signalLater(cm, "markerAdded", cm, marker); - } - return marker; - } - - // SHARED TEXTMARKERS - - // A shared marker spans multiple linked documents. It is - // implemented as a meta-marker-object controlling multiple normal - // markers. - var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { - this.markers = markers; - this.primary = primary; - for (var i = 0; i < markers.length; ++i) - markers[i].parent = this; - }; - eventMixin(SharedTextMarker); - - SharedTextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - this.explicitlyCleared = true; - for (var i = 0; i < this.markers.length; ++i) - this.markers[i].clear(); - signalLater(this, "clear"); - }; - SharedTextMarker.prototype.find = function(side, lineObj) { - return this.primary.find(side, lineObj); - }; - - function markTextShared(doc, from, to, options, type) { - options = copyObj(options); - options.shared = false; - var markers = [markText(doc, from, to, options, type)], primary = markers[0]; - var widget = options.widgetNode; - linkedDocs(doc, function(doc) { - if (widget) options.widgetNode = widget.cloneNode(true); - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); - for (var i = 0; i < doc.linked.length; ++i) - if (doc.linked[i].isParent) return; - primary = lst(markers); - }); - return new SharedTextMarker(markers, primary); - } - - function findSharedMarkers(doc) { - return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), - function(m) { return m.parent; }); - } - - function copySharedMarkers(doc, markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], pos = marker.find(); - var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); - if (cmp(mFrom, mTo)) { - var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); - marker.markers.push(subMark); - subMark.parent = marker; - } - } - } - - function detachSharedMarkers(markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], linked = [marker.primary.doc];; - linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); - for (var j = 0; j < marker.markers.length; j++) { - var subMarker = marker.markers[j]; - if (indexOf(linked, subMarker.doc) == -1) { - subMarker.parent = null; - marker.markers.splice(j--, 1); - } - } - } - } - - // TEXTMARKER SPANS - - function MarkedSpan(marker, from, to) { - this.marker = marker; - this.from = from; this.to = to; - } - - // Search an array of spans for a span matching the given marker. - function getMarkedSpanFor(spans, marker) { - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.marker == marker) return span; - } - } - // Remove a span from an array, returning undefined if no spans are - // left (we don't store arrays for lines without spans). - function removeMarkedSpan(spans, span) { - for (var r, i = 0; i < spans.length; ++i) - if (spans[i] != span) (r || (r = [])).push(spans[i]); - return r; - } - // Add a span to a line. - function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; - span.marker.attachLine(line); - } - - // Used for the algorithm that adjusts markers for a change in the - // document. These functions cut an array of spans at a given - // character position, returning an array of remaining chunks (or - // undefined if nothing remains). - function markedSpansBefore(old, startCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); - if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); - (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); - } - } - return nw; - } - function markedSpansAfter(old, endCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); - if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); - (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, - span.to == null ? null : span.to - endCh)); - } - } - return nw; - } - - // Given a change object, compute the new set of marker spans that - // cover the line in which the change took place. Removes spans - // entirely within the change, reconnects spans belonging to the - // same marker that appear on both sides of the change, and cuts off - // spans partially within the change. Returns an array of span - // arrays with one element for each line in (after) the change. - function stretchSpansOverChange(doc, change) { - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; - if (!oldFirst && !oldLast) return null; - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert); - var last = markedSpansAfter(oldLast, endCh, isInsert); - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i]; - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker); - if (!found) span.to = startCh; - else if (sameLine) span.to = found.to == null ? null : found.to + offset; - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i = 0; i < last.length; ++i) { - var span = last[i]; - if (span.to != null) span.to += offset; - if (span.from == null) { - var found = getMarkedSpanFor(first, span.marker); - if (!found) { - span.from = offset; - if (sameLine) (first || (first = [])).push(span); - } - } else { - span.from += offset; - if (sameLine) (first || (first = [])).push(span); - } - } - } - // Make sure we didn't create any zero-length spans - if (first) first = clearEmptySpans(first); - if (last && last != first) last = clearEmptySpans(last); - - var newMarkers = [first]; - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers; - if (gap > 0 && first) - for (var i = 0; i < first.length; ++i) - if (first[i].to == null) - (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); - for (var i = 0; i < gap; ++i) - newMarkers.push(gapMarkers); - newMarkers.push(last); - } - return newMarkers; - } - - // Remove spans that are empty and don't have a clearWhenEmpty - // option of false. - function clearEmptySpans(spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) - spans.splice(i--, 1); - } - if (!spans.length) return null; - return spans; - } - - // Used for un/re-doing changes from the history. Combines the - // result of computing the existing spans with the set of spans that - // existed in the history (so that deleting around a span and then - // undoing brings back the span). - function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change); - var stretched = stretchSpansOverChange(doc, change); - if (!old) return stretched; - if (!stretched) return old; - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i]; - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j]; - for (var k = 0; k < oldCur.length; ++k) - if (oldCur[k].marker == span.marker) continue spans; - oldCur.push(span); - } - } else if (stretchCur) { - old[i] = stretchCur; - } - } - return old; - } - - // Used to 'clip' out readOnly ranges when making a change. - function removeReadOnlyRanges(doc, from, to) { - var markers = null; - doc.iter(from.line, to.line + 1, function(line) { - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker; - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) - (markers || (markers = [])).push(mark); - } - }); - if (!markers) return null; - var parts = [{from: from, to: to}]; - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(0); - for (var j = 0; j < parts.length; ++j) { - var p = parts[j]; - if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; - var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); - if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) - newParts.push({from: p.from, to: m.from}); - if (dto > 0 || !mk.inclusiveRight && !dto) - newParts.push({from: m.to, to: p.to}); - parts.splice.apply(parts, newParts); - j += newParts.length - 1; - } - } - return parts; - } - - // Connect or disconnect spans from a line. - function detachMarkedSpans(line) { - var spans = line.markedSpans; - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.detachLine(line); - line.markedSpans = null; - } - function attachMarkedSpans(line, spans) { - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.attachLine(line); - line.markedSpans = spans; - } - - // Helpers used when computing which overlapping collapsed span - // counts as the larger one. - function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } - function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } - - // Returns a number indicating which of two overlapping collapsed - // spans is larger (and thus includes the other). Falls back to - // comparing ids when the spans cover exactly the same range. - function compareCollapsedMarkers(a, b) { - var lenDiff = a.lines.length - b.lines.length; - if (lenDiff != 0) return lenDiff; - var aPos = a.find(), bPos = b.find(); - var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); - if (fromCmp) return -fromCmp; - var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); - if (toCmp) return toCmp; - return b.id - a.id; - } - - // Find out whether a line ends or starts in a collapsed span. If - // so, return the marker for that span. - function collapsedSpanAtSide(line, start) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) - found = sp.marker; - } - return found; - } - function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } - function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } - - // Test whether there exists a collapsed span that partially - // overlaps (covers the start or end, but not both) of a new span. - // Such overlap is not allowed. - function conflictingCollapsedRange(doc, lineNo, from, to, marker) { - var line = getLine(doc, lineNo); - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) { - var sp = sps[i]; - if (!sp.marker.collapsed) continue; - var found = sp.marker.find(0); - var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); - var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); - if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; - if (fromCmp <= 0 && (cmp(found.to, from) || extraRight(sp.marker) - extraLeft(marker)) > 0 || - fromCmp >= 0 && (cmp(found.from, to) || extraLeft(sp.marker) - extraRight(marker)) < 0) - return true; - } - } - - // A visual line is a line as drawn on the screen. Folding, for - // example, can cause multiple logical lines to appear on the same - // visual line. This finds the start of the visual line that the - // given line is part of (usually that is the line itself). - function visualLine(line) { - var merged; - while (merged = collapsedSpanAtStart(line)) - line = merged.find(-1, true).line; - return line; - } - - // Returns an array of logical lines that continue the visual line - // started by the argument, or undefined if there are no such lines. - function visualLineContinued(line) { - var merged, lines; - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - (lines || (lines = [])).push(line); - } - return lines; - } - - // Get the line number of the start of the visual line that the - // given line number is part of. - function visualLineNo(doc, lineN) { - var line = getLine(doc, lineN), vis = visualLine(line); - if (line == vis) return lineN; - return lineNo(vis); - } - // Get the line number of the start of the next visual line after - // the given line. - function visualLineEndNo(doc, lineN) { - if (lineN > doc.lastLine()) return lineN; - var line = getLine(doc, lineN), merged; - if (!lineIsHidden(doc, line)) return lineN; - while (merged = collapsedSpanAtEnd(line)) - line = merged.find(1, true).line; - return lineNo(line) + 1; - } - - // Compute whether a line is hidden. Lines count as hidden when they - // are part of a visual line that starts with another line, or when - // they are entirely covered by collapsed, non-widget span. - function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) continue; - if (sp.from == null) return true; - if (sp.marker.widgetNode) continue; - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) - return true; - } - } - function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find(1, true); - return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); - } - if (span.marker.inclusiveRight && span.to == line.text.length) - return true; - for (var sp, i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i]; - if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && - (sp.to == null || sp.to != span.from) && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) return true; - } - } - - // LINE WIDGETS - - // Line widgets are block elements displayed above or below a line. - - var LineWidget = CodeMirror.LineWidget = function(cm, node, options) { - if (options) for (var opt in options) if (options.hasOwnProperty(opt)) - this[opt] = options[opt]; - this.cm = cm; - this.node = node; - }; - eventMixin(LineWidget); - - function adjustScrollWhenAboveVisible(cm, line, diff) { - if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) - addToScrollPos(cm, null, diff); - } - - LineWidget.prototype.clear = function() { - var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); - if (no == null || !ws) return; - for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); - if (!ws.length) line.widgets = null; - var height = widgetHeight(this); - runInOp(cm, function() { - adjustScrollWhenAboveVisible(cm, line, -height); - regLineChange(cm, no, "widget"); - updateLineHeight(line, Math.max(0, line.height - height)); - }); - }; - LineWidget.prototype.changed = function() { - var oldH = this.height, cm = this.cm, line = this.line; - this.height = null; - var diff = widgetHeight(this) - oldH; - if (!diff) return; - runInOp(cm, function() { - cm.curOp.forceUpdate = true; - adjustScrollWhenAboveVisible(cm, line, diff); - updateLineHeight(line, line.height + diff); - }); - }; - - function widgetHeight(widget) { - if (widget.height != null) return widget.height; - if (!contains(document.body, widget.node)) - removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative")); - return widget.height = widget.node.offsetHeight; - } - - function addLineWidget(cm, handle, node, options) { - var widget = new LineWidget(cm, node, options); - if (widget.noHScroll) cm.display.alignWidgets = true; - changeLine(cm, handle, "widget", function(line) { - var widgets = line.widgets || (line.widgets = []); - if (widget.insertAt == null) widgets.push(widget); - else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); - widget.line = line; - if (!lineIsHidden(cm.doc, line)) { - var aboveVisible = heightAtLine(line) < cm.doc.scrollTop; - updateLineHeight(line, line.height + widgetHeight(widget)); - if (aboveVisible) addToScrollPos(cm, null, widget.height); - cm.curOp.forceUpdate = true; - } - return true; - }); - return widget; - } - - // LINE DATA STRUCTURE - - // Line objects. These hold state related to a line, including - // highlighting info (the styles array). - var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { - this.text = text; - attachMarkedSpans(this, markedSpans); - this.height = estimateHeight ? estimateHeight(this) : 1; - }; - eventMixin(Line); - Line.prototype.lineNo = function() { return lineNo(this); }; - - // Change the content (text, markers) of a line. Automatically - // invalidates cached information and tries to re-estimate the - // line's height. - function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text; - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - if (line.order != null) line.order = null; - detachMarkedSpans(line); - attachMarkedSpans(line, markedSpans); - var estHeight = estimateHeight ? estimateHeight(line) : 1; - if (estHeight != line.height) updateLineHeight(line, estHeight); - } - - // Detach a line from the document tree and its markers. - function cleanUpLine(line) { - line.parent = null; - detachMarkedSpans(line); - } - - function extractLineClasses(type, output) { - if (type) for (;;) { - var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); - if (!lineClass) break; - type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); - var prop = lineClass[1] ? "bgClass" : "textClass"; - if (output[prop] == null) - output[prop] = lineClass[2]; - else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) - output[prop] += " " + lineClass[2]; - } - return type; - } - - function callBlankLine(mode, state) { - if (mode.blankLine) return mode.blankLine(state); - if (!mode.innerMode) return; - var inner = CodeMirror.innerMode(mode, state); - if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); - } - - function readToken(mode, stream, state) { - var style = mode.token(stream, state); - if (stream.pos <= stream.start) - throw new Error("Mode " + mode.name + " failed to advance stream."); - return style; - } - - // Run the given mode's parser over a line, calling f for each token. - function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { - var flattenSpans = mode.flattenSpans; - if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; - var curStart = 0, curStyle = null; - var stream = new StringStream(text, cm.options.tabSize), style; - if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false; - if (forceToEnd) processLine(cm, text, state, stream.pos); - stream.pos = text.length; - style = null; - } else { - style = extractLineClasses(readToken(mode, stream, state), lineClasses); - } - if (cm.options.addModeClass) { - var mName = CodeMirror.innerMode(mode, state).mode.name; - if (mName) style = "m-" + (style ? mName + " " + style : mName); - } - if (!flattenSpans || curStyle != style) { - if (curStart < stream.start) f(stream.start, curStyle); - curStart = stream.start; curStyle = style; - } - stream.start = stream.pos; - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 characters - var pos = Math.min(stream.pos, curStart + 50000); - f(pos, curStyle); - curStart = pos; - } - } - - // Compute a style array (an array starting with a mode generation - // -- for invalidation -- followed by pairs of end positions and - // style strings), which is used to highlight the tokens on the - // line. - function highlightLine(cm, line, state, forceToEnd) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen], lineClasses = {}; - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, state, function(end, style) { - st.push(end, style); - }, lineClasses, forceToEnd); - - // Run overlays, adjust style array. - for (var o = 0; o < cm.state.overlays.length; ++o) { - var overlay = cm.state.overlays[o], i = 1, at = 0; - runMode(cm, line.text, overlay.mode, true, function(end, style) { - var start = i; - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i]; - if (i_end > end) - st.splice(i, 1, end, st[i+1], i_end); - i += 2; - at = Math.min(end, i_end); - } - if (!style) return; - if (overlay.opaque) { - st.splice(start, i - start, end, "cm-overlay " + style); - i = start + 2; - } else { - for (; start < i; start += 2) { - var cur = st[start+1]; - st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; - } - } - }, lineClasses); - } - - return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; - } - - function getLineStyles(cm, line) { - if (!line.styles || line.styles[0] != cm.state.modeGen) { - var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); - line.styles = result.styles; - if (result.classes) line.styleClasses = result.classes; - else if (line.styleClasses) line.styleClasses = null; - } - return line.styles; - } - - // Lightweight form of highlight -- proceed over this line and - // update state, but don't save a style array. Used for lines that - // aren't currently visible. - function processLine(cm, text, state, startAt) { - var mode = cm.doc.mode; - var stream = new StringStream(text, cm.options.tabSize); - stream.start = stream.pos = startAt || 0; - if (text == "") callBlankLine(mode, state); - while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { - readToken(mode, stream, state); - stream.start = stream.pos; - } - } - - // Convert a style as returned by a mode (either null, or a string - // containing one or more styles) to a CSS style. This is cached, - // and also looks for line-wide styles. - var styleToClassCache = {}, styleToClassCacheWithMode = {}; - function interpretTokenStyle(style, options) { - if (!style || /^\s*$/.test(style)) return null; - var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; - return cache[style] || - (cache[style] = style.replace(/\S+/g, "cm-$&")); - } - - // Render the DOM representation of the text of a line. Also builds - // up a 'line map', which points at the DOM nodes that represent - // specific stretches of text, and is used by the measuring code. - // The returned object contains the DOM node, this map, and - // information about line-wide styles that were set by the mode. - function buildLineContent(cm, lineView) { - // The padding-right forces the element to have a 'border', which - // is needed on Webkit to be able to get line-level bounding - // rectangles for it (in measureChar). - var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); - var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm}; - lineView.measure = {}; - - // Iterate over the logical lines that make up this visual line. - for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { - var line = i ? lineView.rest[i - 1] : lineView.line, order; - builder.pos = 0; - builder.addToken = buildToken; - // Optionally wire in some hacks into the token-rendering - // algorithm, to deal with browser quirks. - if ((ie || webkit) && cm.getOption("lineWrapping")) - builder.addToken = buildTokenSplitSpaces(builder.addToken); - if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) - builder.addToken = buildTokenBadBidi(builder.addToken, order); - builder.map = []; - insertLineContent(line, builder, getLineStyles(cm, line)); - if (line.styleClasses) { - if (line.styleClasses.bgClass) - builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); - if (line.styleClasses.textClass) - builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); - } - - // Ensure at least a single node is present, for measuring. - if (builder.map.length == 0) - builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); - - // Store the map and a cache object for the current logical line - if (i == 0) { - lineView.measure.map = builder.map; - lineView.measure.cache = {}; - } else { - (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); - (lineView.measure.caches || (lineView.measure.caches = [])).push({}); - } - } - - signal(cm, "renderLine", cm, lineView.line, builder.pre); - return builder; - } - - function defaultSpecialCharPlaceholder(ch) { - var token = elt("span", "\u2022", "cm-invalidchar"); - token.title = "\\u" + ch.charCodeAt(0).toString(16); - return token; - } - - // Build up the DOM representation for a single token, and add it to - // the line map. Takes care to render special characters separately. - function buildToken(builder, text, style, startStyle, endStyle, title) { - if (!text) return; - var special = builder.cm.options.specialChars, mustWrap = false; - if (!special.test(text)) { - builder.col += text.length; - var content = document.createTextNode(text); - builder.map.push(builder.pos, builder.pos + text.length, content); - if (ie_upto8) mustWrap = true; - builder.pos += text.length; - } else { - var content = document.createDocumentFragment(), pos = 0; - while (true) { - special.lastIndex = pos; - var m = special.exec(text); - var skipped = m ? m.index - pos : text.length - pos; - if (skipped) { - var txt = document.createTextNode(text.slice(pos, pos + skipped)); - if (ie_upto8) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.map.push(builder.pos, builder.pos + skipped, txt); - builder.col += skipped; - builder.pos += skipped; - } - if (!m) break; - pos += skipped + 1; - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; - var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); - builder.col += tabWidth; - } else { - var txt = builder.cm.options.specialCharPlaceholder(m[0]); - if (ie_upto8) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.col += 1; - } - builder.map.push(builder.pos, builder.pos + 1, txt); - builder.pos++; - } - } - if (style || startStyle || endStyle || mustWrap) { - var fullStyle = style || ""; - if (startStyle) fullStyle += startStyle; - if (endStyle) fullStyle += endStyle; - var token = elt("span", [content], fullStyle); - if (title) token.title = title; - return builder.content.appendChild(token); - } - builder.content.appendChild(content); - } - - function buildTokenSplitSpaces(inner) { - function split(old) { - var out = " "; - for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; - out += " "; - return out; - } - return function(builder, text, style, startStyle, endStyle, title) { - inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title); - }; - } - - // Work around nonsense dimensions being reported for stretches of - // right-to-left text. - function buildTokenBadBidi(inner, order) { - return function(builder, text, style, startStyle, endStyle, title) { - style = style ? style + " cm-force-border" : "cm-force-border"; - var start = builder.pos, end = start + text.length; - for (;;) { - // Find the part that overlaps with the start of this text - for (var i = 0; i < order.length; i++) { - var part = order[i]; - if (part.to > start && part.from <= start) break; - } - if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title); - inner(builder, text.slice(0, part.to - start), style, startStyle, null, title); - startStyle = null; - text = text.slice(part.to - start); - start = part.to; - } - }; - } - - function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.widgetNode; - if (widget) { - builder.map.push(builder.pos, builder.pos + size, widget); - builder.content.appendChild(widget); - } - builder.pos += size; - } - - // Outputs a number of spans to make up a line, taking highlighting - // and marked text into account. - function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0; - if (!spans) { - for (var i = 1; i < styles.length; i+=2) - builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); - return; - } - - var len = allText.length, pos = 0, i = 1, text = "", style; - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; - for (;;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = title = ""; - collapsed = null; nextChange = Infinity; - var foundBookmarks = []; - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker; - if (sp.from <= pos && (sp.to == null || sp.to > pos)) { - if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; } - if (m.className) spanStyle += " " + m.className; - if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; - if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; - if (m.title && !title) title = m.title; - if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) - collapsed = sp; - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from; - } - if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m); - } - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, - collapsed.marker, collapsed.from == null); - if (collapsed.to == null) return; - } - if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) - buildCollapsedSpan(builder, 0, foundBookmarks[j]); - } - if (pos >= len) break; - - var upto = Math.min(len, nextChange); - while (true) { - if (text) { - var end = pos + text.length; - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text; - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title); - } - if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} - pos = end; - spanStartStyle = ""; - } - text = allText.slice(at, at = styles[i++]); - style = interpretTokenStyle(styles[i++], builder.cm.options); - } - } - } - - // DOCUMENT DATA STRUCTURE - - // By default, updates that start and end at the beginning of a line - // are treated specially, in order to make the association of line - // widgets and marker elements with the text behave more intuitive. - function isWholeLineUpdate(doc, change) { - return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && - (!doc.cm || doc.cm.options.wholeLineUpdateBefore); - } - - // Perform a change on the document data structure. - function updateDoc(doc, change, markedSpans, estimateHeight) { - function spansFor(n) {return markedSpans ? markedSpans[n] : null;} - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight); - signalLater(line, "change", line, change); - } - - var from = change.from, to = change.to, text = change.text; - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; - - // Adjust the line structure - if (isWholeLineUpdate(doc, change)) { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - for (var i = 0, added = []; i < text.length - 1; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - update(lastLine, lastLine.text, lastSpans); - if (nlines) doc.remove(from.line, nlines); - if (added.length) doc.insert(from.line, added); - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); - } else { - for (var added = [], i = 1; i < text.length - 1; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - doc.insert(from.line + 1, added); - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); - doc.remove(from.line + 1, nlines); - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); - for (var i = 1, added = []; i < text.length - 1; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - if (nlines > 1) doc.remove(from.line + 1, nlines - 1); - doc.insert(from.line + 1, added); - } - - signalLater(doc, "change", doc, change); - } - - // The document is represented as a BTree consisting of leaves, with - // chunk of lines in them, and branches, with up to ten leaves or - // other branch nodes below them. The top node is always a branch - // node, and is the document object itself (meaning it has - // additional methods and properties). - // - // All nodes have parent links. The tree is used both to go from - // line numbers to line objects, and to go from objects to numbers. - // It also indexes by height, and is used to convert between height - // and line object, and to find the total height of the document. - // - // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html - - function LeafChunk(lines) { - this.lines = lines; - this.parent = null; - for (var i = 0, height = 0; i < lines.length; ++i) { - lines[i].parent = this; - height += lines[i].height; - } - this.height = height; - } - - LeafChunk.prototype = { - chunkSize: function() { return this.lines.length; }, - // Remove the n lines at offset 'at'. - removeInner: function(at, n) { - for (var i = at, e = at + n; i < e; ++i) { - var line = this.lines[i]; - this.height -= line.height; - cleanUpLine(line); - signalLater(line, "delete"); - } - this.lines.splice(at, n); - }, - // Helper used to collapse a small branch into a single leaf. - collapse: function(lines) { - lines.push.apply(lines, this.lines); - }, - // Insert the given array of lines at offset 'at', count them as - // having the given height. - insertInner: function(at, lines, height) { - this.height += height; - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); - for (var i = 0; i < lines.length; ++i) lines[i].parent = this; - }, - // Used to iterate over a part of the tree. - iterN: function(at, n, op) { - for (var e = at + n; at < e; ++at) - if (op(this.lines[at])) return true; - } - }; - - function BranchChunk(children) { - this.children = children; - var size = 0, height = 0; - for (var i = 0; i < children.length; ++i) { - var ch = children[i]; - size += ch.chunkSize(); height += ch.height; - ch.parent = this; - } - this.size = size; - this.height = height; - this.parent = null; - } - - BranchChunk.prototype = { - chunkSize: function() { return this.size; }, - removeInner: function(at, n) { - this.size -= n; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height; - child.removeInner(at, rm); - this.height -= oldHeight - child.height; - if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } - if ((n -= rm) == 0) break; - at = 0; - } else at -= sz; - } - // If the result is smaller than 25 lines, ensure that it is a - // single leaf node. - if (this.size - n < 25 && - (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { - var lines = []; - this.collapse(lines); - this.children = [new LeafChunk(lines)]; - this.children[0].parent = this; - } - }, - collapse: function(lines) { - for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); - }, - insertInner: function(at, lines, height) { - this.size += lines.length; - this.height += height; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at <= sz) { - child.insertInner(at, lines, height); - if (child.lines && child.lines.length > 50) { - while (child.lines.length > 50) { - var spilled = child.lines.splice(child.lines.length - 25, 25); - var newleaf = new LeafChunk(spilled); - child.height -= newleaf.height; - this.children.splice(i + 1, 0, newleaf); - newleaf.parent = this; - } - this.maybeSpill(); - } - break; - } - at -= sz; - } - }, - // When a node has grown, check whether it should be split. - maybeSpill: function() { - if (this.children.length <= 10) return; - var me = this; - do { - var spilled = me.children.splice(me.children.length - 5, 5); - var sibling = new BranchChunk(spilled); - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children); - copy.parent = me; - me.children = [copy, sibling]; - me = copy; - } else { - me.size -= sibling.size; - me.height -= sibling.height; - var myIndex = indexOf(me.parent.children, me); - me.parent.children.splice(myIndex + 1, 0, sibling); - } - sibling.parent = me.parent; - } while (me.children.length > 10); - me.parent.maybeSpill(); - }, - iterN: function(at, n, op) { - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var used = Math.min(n, sz - at); - if (child.iterN(at, used, op)) return true; - if ((n -= used) == 0) break; - at = 0; - } else at -= sz; - } - } - }; - - var nextDocId = 0; - var Doc = CodeMirror.Doc = function(text, mode, firstLine) { - if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); - if (firstLine == null) firstLine = 0; - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); - this.first = firstLine; - this.scrollTop = this.scrollLeft = 0; - this.cantEdit = false; - this.cleanGeneration = 1; - this.frontier = firstLine; - var start = Pos(firstLine, 0); - this.sel = simpleSelection(start); - this.history = new History(null); - this.id = ++nextDocId; - this.modeOption = mode; - - if (typeof text == "string") text = splitLines(text); - updateDoc(this, {from: start, to: start, text: text}); - setSelection(this, simpleSelection(start), sel_dontScroll); - }; - - Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - // Iterate over the document. Supports two forms -- with only one - // argument, it calls that for each line in the document. With - // three, it iterates over the range given by the first two (with - // the second being non-inclusive). - iter: function(from, to, op) { - if (op) this.iterN(from - this.first, to - from, op); - else this.iterN(this.first, this.first + this.size, from); - }, - - // Non-public interface for adding and removing lines. - insert: function(at, lines) { - var height = 0; - for (var i = 0; i < lines.length; ++i) height += lines[i].height; - this.insertInner(at - this.first, lines, height); - }, - remove: function(at, n) { this.removeInner(at - this.first, n); }, - - // From here, the methods are part of the public interface. Most - // are also available from CodeMirror (editor) instances. - - getValue: function(lineSep) { - var lines = getLines(this, this.first, this.first + this.size); - if (lineSep === false) return lines; - return lines.join(lineSep || "\n"); - }, - setValue: docMethodOp(function(code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1; - makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), - text: splitLines(code), origin: "setValue"}, true); - setSelection(this, simpleSelection(top)); - }), - replaceRange: function(code, from, to, origin) { - from = clipPos(this, from); - to = to ? clipPos(this, to) : from; - replaceRange(this, code, from, to, origin); - }, - getRange: function(from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); - if (lineSep === false) return lines; - return lines.join(lineSep || "\n"); - }, - - getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, - - getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, - getLineNumber: function(line) {return lineNo(line);}, - - getLineHandleVisualStart: function(line) { - if (typeof line == "number") line = getLine(this, line); - return visualLine(line); - }, - - lineCount: function() {return this.size;}, - firstLine: function() {return this.first;}, - lastLine: function() {return this.first + this.size - 1;}, - - clipPos: function(pos) {return clipPos(this, pos);}, - - getCursor: function(start) { - var range = this.sel.primary(), pos; - if (start == null || start == "head") pos = range.head; - else if (start == "anchor") pos = range.anchor; - else if (start == "end" || start == "to" || start === false) pos = range.to(); - else pos = range.from(); - return pos; - }, - listSelections: function() { return this.sel.ranges; }, - somethingSelected: function() {return this.sel.somethingSelected();}, - - setCursor: docMethodOp(function(line, ch, options) { - setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); - }), - setSelection: docMethodOp(function(anchor, head, options) { - setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); - }), - extendSelection: docMethodOp(function(head, other, options) { - extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); - }), - extendSelections: docMethodOp(function(heads, options) { - extendSelections(this, clipPosArray(this, heads, options)); - }), - extendSelectionsBy: docMethodOp(function(f, options) { - extendSelections(this, map(this.sel.ranges, f), options); - }), - setSelections: docMethodOp(function(ranges, primary, options) { - if (!ranges.length) return; - for (var i = 0, out = []; i < ranges.length; i++) - out[i] = new Range(clipPos(this, ranges[i].anchor), - clipPos(this, ranges[i].head)); - if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); - setSelection(this, normalizeSelection(out, primary), options); - }), - addSelection: docMethodOp(function(anchor, head, options) { - var ranges = this.sel.ranges.slice(0); - ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); - setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); - }), - - getSelection: function(lineSep) { - var ranges = this.sel.ranges, lines; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - lines = lines ? lines.concat(sel) : sel; - } - if (lineSep === false) return lines; - else return lines.join(lineSep || "\n"); - }, - getSelections: function(lineSep) { - var parts = [], ranges = this.sel.ranges; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - if (lineSep !== false) sel = sel.join(lineSep || "\n"); - parts[i] = sel; - } - return parts; - }, - replaceSelection: function(code, collapse, origin) { - var dup = []; - for (var i = 0; i < this.sel.ranges.length; i++) - dup[i] = code; - this.replaceSelections(dup, collapse, origin || "+input"); - }, - replaceSelections: docMethodOp(function(code, collapse, origin) { - var changes = [], sel = this.sel; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin}; - } - var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); - for (var i = changes.length - 1; i >= 0; i--) - makeChange(this, changes[i]); - if (newSel) setSelectionReplaceHistory(this, newSel); - else if (this.cm) ensureCursorVisible(this.cm); - }), - undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), - redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), - undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), - redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), - - setExtending: function(val) {this.extend = val;}, - getExtending: function() {return this.extend;}, - - historySize: function() { - var hist = this.history, done = 0, undone = 0; - for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; - for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; - return {undo: done, redo: undone}; - }, - clearHistory: function() {this.history = new History(this.history.maxGeneration);}, - - markClean: function() { - this.cleanGeneration = this.changeGeneration(true); - }, - changeGeneration: function(forceSplit) { - if (forceSplit) - this.history.lastOp = this.history.lastOrigin = null; - return this.history.generation; - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration); - }, - - getHistory: function() { - return {done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone)}; - }, - setHistory: function(histData) { - var hist = this.history = new History(this.history.maxGeneration); - hist.done = copyHistoryArray(histData.done.slice(0), null, true); - hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); - }, - - markText: function(from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); - }, - setBookmark: function(pos, options) { - var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft, - clearWhenEmpty: false, shared: options && options.shared}; - pos = clipPos(this, pos); - return markText(this, pos, pos, realOpts, "bookmark"); - }, - findMarksAt: function(pos) { - pos = clipPos(this, pos); - var markers = [], spans = getLine(this, pos.line).markedSpans; - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) - markers.push(span.marker.parent || span.marker); - } - return markers; - }, - findMarks: function(from, to, filter) { - from = clipPos(this, from); to = clipPos(this, to); - var found = [], lineNo = from.line; - this.iter(from.line, to.line + 1, function(line) { - var spans = line.markedSpans; - if (spans) for (var i = 0; i < spans.length; i++) { - var span = spans[i]; - if (!(lineNo == from.line && from.ch > span.to || - span.from == null && lineNo != from.line|| - lineNo == to.line && span.from > to.ch) && - (!filter || filter(span.marker))) - found.push(span.marker.parent || span.marker); - } - ++lineNo; - }); - return found; - }, - getAllMarks: function() { - var markers = []; - this.iter(function(line) { - var sps = line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) - if (sps[i].from != null) markers.push(sps[i].marker); - }); - return markers; - }, - - posFromIndex: function(off) { - var ch, lineNo = this.first; - this.iter(function(line) { - var sz = line.text.length + 1; - if (sz > off) { ch = off; return true; } - off -= sz; - ++lineNo; - }); - return clipPos(this, Pos(lineNo, ch)); - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords); - var index = coords.ch; - if (coords.line < this.first || coords.ch < 0) return 0; - this.iter(this.first, coords.line, function (line) { - index += line.text.length + 1; - }); - return index; - }, - - copy: function(copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; - doc.sel = this.sel; - doc.extend = false; - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth; - doc.setHistory(this.getHistory()); - } - return doc; - }, - - linkedDoc: function(options) { - if (!options) options = {}; - var from = this.first, to = this.first + this.size; - if (options.from != null && options.from > from) from = options.from; - if (options.to != null && options.to < to) to = options.to; - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); - if (options.sharedHist) copy.history = this.history; - (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); - copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; - copySharedMarkers(copy, findSharedMarkers(this)); - return copy; - }, - unlinkDoc: function(other) { - if (other instanceof CodeMirror) other = other.doc; - if (this.linked) for (var i = 0; i < this.linked.length; ++i) { - var link = this.linked[i]; - if (link.doc != other) continue; - this.linked.splice(i, 1); - other.unlinkDoc(this); - detachSharedMarkers(findSharedMarkers(this)); - break; - } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id]; - linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); - other.history = new History(null); - other.history.done = copyHistoryArray(this.history.done, splitIds); - other.history.undone = copyHistoryArray(this.history.undone, splitIds); - } - }, - iterLinkedDocs: function(f) {linkedDocs(this, f);}, - - getMode: function() {return this.mode;}, - getEditor: function() {return this.cm;} - }); - - // Public alias. - Doc.prototype.eachLine = Doc.prototype.iter; - - // Set up methods on CodeMirror's prototype to redirect to the editor's document. - var dontDelegate = "iter insert remove copy getEditor".split(" "); - for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) - CodeMirror.prototype[prop] = (function(method) { - return function() {return method.apply(this.doc, arguments);}; - })(Doc.prototype[prop]); - - eventMixin(Doc); - - // Call f for all linked documents. - function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i]; - if (rel.doc == skip) continue; - var shared = sharedHist && rel.sharedHist; - if (sharedHistOnly && !shared) continue; - f(rel.doc, shared); - propagate(rel.doc, doc, shared); - } - } - propagate(doc, null, true); - } - - // Attach a document to an editor. - function attachDoc(cm, doc) { - if (doc.cm) throw new Error("This document is already in use."); - cm.doc = doc; - doc.cm = cm; - estimateLineHeights(cm); - loadMode(cm); - if (!cm.options.lineWrapping) findMaxLine(cm); - cm.options.mode = doc.modeOption; - regChange(cm); - } - - // LINE UTILITIES - - // Find the line object corresponding to the given line number. - function getLine(doc, n) { - n -= doc.first; - if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); - for (var chunk = doc; !chunk.lines;) { - for (var i = 0;; ++i) { - var child = chunk.children[i], sz = child.chunkSize(); - if (n < sz) { chunk = child; break; } - n -= sz; - } - } - return chunk.lines[n]; - } - - // Get the part of a document between two positions, as an array of - // strings. - function getBetween(doc, start, end) { - var out = [], n = start.line; - doc.iter(start.line, end.line + 1, function(line) { - var text = line.text; - if (n == end.line) text = text.slice(0, end.ch); - if (n == start.line) text = text.slice(start.ch); - out.push(text); - ++n; - }); - return out; - } - // Get the lines between from and to, as array of strings. - function getLines(doc, from, to) { - var out = []; - doc.iter(from, to, function(line) { out.push(line.text); }); - return out; - } - - // Update the height of a line, propagating the height change - // upwards to parent nodes. - function updateLineHeight(line, height) { - var diff = height - line.height; - if (diff) for (var n = line; n; n = n.parent) n.height += diff; - } - - // Given a line object, find its line number by walking up through - // its parent links. - function lineNo(line) { - if (line.parent == null) return null; - var cur = line.parent, no = indexOf(cur.lines, line); - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0;; ++i) { - if (chunk.children[i] == cur) break; - no += chunk.children[i].chunkSize(); - } - } - return no + cur.first; - } - - // Find the line at the given vertical position, using the height - // information in the document tree. - function lineAtHeight(chunk, h) { - var n = chunk.first; - outer: do { - for (var i = 0; i < chunk.children.length; ++i) { - var child = chunk.children[i], ch = child.height; - if (h < ch) { chunk = child; continue outer; } - h -= ch; - n += child.chunkSize(); - } - return n; - } while (!chunk.lines); - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i], lh = line.height; - if (h < lh) break; - h -= lh; - } - return n + i; - } - - - // Find the height above the given line. - function heightAtLine(lineObj) { - lineObj = visualLine(lineObj); - - var h = 0, chunk = lineObj.parent; - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i]; - if (line == lineObj) break; - else h += line.height; - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i = 0; i < p.children.length; ++i) { - var cur = p.children[i]; - if (cur == chunk) break; - else h += cur.height; - } - } - return h; - } - - // Get the bidi ordering for the given line (and cache it). Returns - // false for lines that are fully left-to-right, and an array of - // BidiSpan objects otherwise. - function getOrder(line) { - var order = line.order; - if (order == null) order = line.order = bidiOrdering(line.text); - return order; - } - - // HISTORY - - function History(startGen) { - // Arrays of change events and selections. Doing something adds an - // event to done and clears undo. Undoing moves events from done - // to undone, redoing moves them in the other direction. - this.done = []; this.undone = []; - this.undoDepth = Infinity; - // Used to track when changes can be merged into a single undo - // event - this.lastModTime = this.lastSelTime = 0; - this.lastOp = null; - this.lastOrigin = this.lastSelOrigin = null; - // Used by the isClean() method - this.generation = this.maxGeneration = startGen || 1; - } - - // Create a history change event from an updateDoc-style change - // object. - function historyChangeFromChange(doc, change) { - var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); - linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); - return histChange; - } - - // Pop all selection events off the end of a history array. Stop at - // a change event. - function clearSelectionEvents(array) { - while (array.length) { - var last = lst(array); - if (last.ranges) array.pop(); - else break; - } - } - - // Find the top change event in the history. Pop off selection - // events that are in the way. - function lastChangeEvent(hist, force) { - if (force) { - clearSelectionEvents(hist.done); - return lst(hist.done); - } else if (hist.done.length && !lst(hist.done).ranges) { - return lst(hist.done); - } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { - hist.done.pop(); - return lst(hist.done); - } - } - - // Register a change in the history. Merges changes that are within - // a single operation, ore are close together with an origin that - // allows merging (starting with "+") into a single event. - function addChangeToHistory(doc, change, selAfter, opId) { - var hist = doc.history; - hist.undone.length = 0; - var time = +new Date, cur; - - if ((hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || - change.origin.charAt(0) == "*")) && - (cur = lastChangeEvent(hist, hist.lastOp == opId))) { - // Merge this change into the last event - var last = lst(cur.changes); - if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change); - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)); - } - } else { - // Can not be merged, start a new event. - var before = lst(hist.done); - if (!before || !before.ranges) - pushSelectionToHistory(doc.sel, hist.done); - cur = {changes: [historyChangeFromChange(doc, change)], - generation: hist.generation}; - hist.done.push(cur); - while (hist.done.length > hist.undoDepth) { - hist.done.shift(); - if (!hist.done[0].ranges) hist.done.shift(); - } - } - hist.done.push(selAfter); - hist.generation = ++hist.maxGeneration; - hist.lastModTime = hist.lastSelTime = time; - hist.lastOp = opId; - hist.lastOrigin = hist.lastSelOrigin = change.origin; - - if (!last) signal(doc, "historyAdded"); - } - - function selectionEventCanBeMerged(doc, origin, prev, sel) { - var ch = origin.charAt(0); - return ch == "*" || - ch == "+" && - prev.ranges.length == sel.ranges.length && - prev.somethingSelected() == sel.somethingSelected() && - new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); - } - - // Called whenever the selection changes, sets the new selection as - // the pending selection in the history, and pushes the old pending - // selection into the 'done' array when it was significantly - // different (in number of selected ranges, emptiness, or time). - function addSelectionToHistory(doc, sel, opId, options) { - var hist = doc.history, origin = options && options.origin; - - // A new event is started when the previous origin does not match - // the current, or the origins don't allow matching. Origins - // starting with * are always merged, those starting with + are - // merged when similar and close together in time. - if (opId == hist.lastOp || - (origin && hist.lastSelOrigin == origin && - (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || - selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) - hist.done[hist.done.length - 1] = sel; - else - pushSelectionToHistory(sel, hist.done); - - hist.lastSelTime = +new Date; - hist.lastSelOrigin = origin; - hist.lastOp = opId; - if (options && options.clearRedo !== false) - clearSelectionEvents(hist.undone); - } - - function pushSelectionToHistory(sel, dest) { - var top = lst(dest); - if (!(top && top.ranges && top.equals(sel))) - dest.push(sel); - } - - // Used to store marked span information in the history. - function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0; - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { - if (line.markedSpans) - (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; - ++n; - }); - } - - // When un/re-doing restores text containing marked spans, those - // that have been explicitly cleared should not be restored. - function removeClearedSpans(spans) { - if (!spans) return null; - for (var i = 0, out; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } - else if (out) out.push(spans[i]); - } - return !out ? spans : out.length ? out : null; - } - - // Retrieve and filter the old marked spans stored in a change event. - function getOldSpans(doc, change) { - var found = change["spans_" + doc.id]; - if (!found) return null; - for (var i = 0, nw = []; i < change.text.length; ++i) - nw.push(removeClearedSpans(found[i])); - return nw; - } - - // Used both to provide a JSON-safe object in .getHistory, and, when - // detaching a document, to split the history in two - function copyHistoryArray(events, newGroup, instantiateSel) { - for (var i = 0, copy = []; i < events.length; ++i) { - var event = events[i]; - if (event.ranges) { - copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); - continue; - } - var changes = event.changes, newChanges = []; - copy.push({changes: newChanges}); - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m; - newChanges.push({from: change.from, to: change.to, text: change.text}); - if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop]; - delete change[prop]; - } - } - } - } - return copy; - } - - // Rebasing/resetting history to deal with externally-sourced changes - - function rebaseHistSelSingle(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff; - } else if (from < pos.line) { - pos.line = from; - pos.ch = 0; - } - } - - // Tries to rebase an array of history events given a change in the - // document. If the change touches the same lines as the event, the - // event, and everything 'behind' it, is discarded. If the change is - // before the event, the event's positions are updated. Uses a - // copy-on-write scheme for the positions, to avoid having to - // reallocate them all on every rebase, but also avoid problems with - // shared position objects being unsafely updated. - function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true; - if (sub.ranges) { - if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } - for (var j = 0; j < sub.ranges.length; j++) { - rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); - rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); - } - continue; - } - for (var j = 0; j < sub.changes.length; ++j) { - var cur = sub.changes[j]; - if (to < cur.from.line) { - cur.from = Pos(cur.from.line + diff, cur.from.ch); - cur.to = Pos(cur.to.line + diff, cur.to.ch); - } else if (from <= cur.to.line) { - ok = false; - break; - } - } - if (!ok) { - array.splice(0, i + 1); - i = 0; - } - } - } - - function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; - rebaseHistArray(hist.done, from, to, diff); - rebaseHistArray(hist.undone, from, to, diff); - } - - // EVENT UTILITIES - - // Due to the fact that we still support jurassic IE versions, some - // compatibility wrappers are needed. - - var e_preventDefault = CodeMirror.e_preventDefault = function(e) { - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; - }; - var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { - if (e.stopPropagation) e.stopPropagation(); - else e.cancelBubble = true; - }; - function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; - } - var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; - - function e_target(e) {return e.target || e.srcElement;} - function e_button(e) { - var b = e.which; - if (b == null) { - if (e.button & 1) b = 1; - else if (e.button & 2) b = 3; - else if (e.button & 4) b = 2; - } - if (mac && e.ctrlKey && b == 1) b = 3; - return b; - } - - // EVENT HANDLING - - // Lightweight event framework. on/off also work on DOM nodes, - // registering native DOM handlers. - - var on = CodeMirror.on = function(emitter, type, f) { - if (emitter.addEventListener) - emitter.addEventListener(type, f, false); - else if (emitter.attachEvent) - emitter.attachEvent("on" + type, f); - else { - var map = emitter._handlers || (emitter._handlers = {}); - var arr = map[type] || (map[type] = []); - arr.push(f); - } - }; - - var off = CodeMirror.off = function(emitter, type, f) { - if (emitter.removeEventListener) - emitter.removeEventListener(type, f, false); - else if (emitter.detachEvent) - emitter.detachEvent("on" + type, f); - else { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - for (var i = 0; i < arr.length; ++i) - if (arr[i] == f) { arr.splice(i, 1); break; } - } - }; - - var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - var args = Array.prototype.slice.call(arguments, 2); - for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); - }; - - // Often, we want to signal events at a point where we are in the - // middle of some work, but don't want the handler to start calling - // other methods on the editor, which might be in an inconsistent - // state or simply not expect any other events to happen. - // signalLater looks whether there are any handlers, and schedules - // them to be executed when the last operation ends, or, if no - // operation is active, when a timeout fires. - var delayedCallbacks, delayedCallbackDepth = 0; - function signalLater(emitter, type /*, values...*/) { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - var args = Array.prototype.slice.call(arguments, 2); - if (!delayedCallbacks) { - ++delayedCallbackDepth; - delayedCallbacks = []; - setTimeout(fireDelayed, 0); - } - function bnd(f) {return function(){f.apply(null, args);};}; - for (var i = 0; i < arr.length; ++i) - delayedCallbacks.push(bnd(arr[i])); - } - - function fireDelayed() { - --delayedCallbackDepth; - var delayed = delayedCallbacks; - delayedCallbacks = null; - for (var i = 0; i < delayed.length; ++i) delayed[i](); - } - - // The DOM events that CodeMirror handles can be overridden by - // registering a (non-DOM) handler on the editor for the event name, - // and preventDefault-ing the event in that handler. - function signalDOMEvent(cm, e, override) { - signal(cm, override || e.type, cm, e); - return e_defaultPrevented(e) || e.codemirrorIgnore; - } - - function signalCursorActivity(cm) { - var arr = cm._handlers && cm._handlers.cursorActivity; - if (!arr) return; - var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); - for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) - set.push(arr[i]); - } - - function hasHandler(emitter, type) { - var arr = emitter._handlers && emitter._handlers[type]; - return arr && arr.length > 0; - } - - // Add on and off methods to a constructor's prototype, to make - // registering events on such objects more convenient. - function eventMixin(ctor) { - ctor.prototype.on = function(type, f) {on(this, type, f);}; - ctor.prototype.off = function(type, f) {off(this, type, f);}; - } - - // MISC UTILITIES - - // Number of pixels added to scroller and sizer to hide scrollbar - var scrollerCutOff = 30; - - // Returned or thrown by various protocols to signal 'I'm not - // handling this'. - var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; - - // Reused option objects for setSelection & friends - var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; - - function Delayed() {this.id = null;} - Delayed.prototype.set = function(ms, f) { - clearTimeout(this.id); - this.id = setTimeout(f, ms); - }; - - // Counts the column offset in a string, taking tabs into account. - // Used mostly to find indentation. - var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) end = string.length; - } - for (var i = startIndex || 0, n = startValue || 0;;) { - var nextTab = string.indexOf("\t", i); - if (nextTab < 0 || nextTab >= end) - return n + (end - i); - n += nextTab - i; - n += tabSize - (n % tabSize); - i = nextTab + 1; - } - }; - - // The inverse of countColumn -- find the offset that corresponds to - // a particular column. - function findColumn(string, goal, tabSize) { - for (var pos = 0, col = 0;;) { - var nextTab = string.indexOf("\t", pos); - if (nextTab == -1) nextTab = string.length; - var skipped = nextTab - pos; - if (nextTab == string.length || col + skipped >= goal) - return pos + Math.min(skipped, goal - col); - col += nextTab - pos; - col += tabSize - (col % tabSize); - pos = nextTab + 1; - if (col >= goal) return pos; - } - } - - var spaceStrs = [""]; - function spaceStr(n) { - while (spaceStrs.length <= n) - spaceStrs.push(lst(spaceStrs) + " "); - return spaceStrs[n]; - } - - function lst(arr) { return arr[arr.length-1]; } - - var selectInput = function(node) { node.select(); }; - if (ios) // Mobile Safari apparently has a bug where select() is broken. - selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; - else if (ie) // Suppress mysterious IE10 errors - selectInput = function(node) { try { node.select(); } catch(_e) {} }; - - function indexOf(array, elt) { - for (var i = 0; i < array.length; ++i) - if (array[i] == elt) return i; - return -1; - } - if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); }; - function map(array, f) { - var out = []; - for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); - return out; - } - if ([].map) map = function(array, f) { return array.map(f); }; - - function createObj(base, props) { - var inst; - if (Object.create) { - inst = Object.create(base); - } else { - var ctor = function() {}; - ctor.prototype = base; - inst = new ctor(); - } - if (props) copyObj(props, inst); - return inst; - }; - - function copyObj(obj, target, overwrite) { - if (!target) target = {}; - for (var prop in obj) - if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) - target[prop] = obj[prop]; - return target; - } - - function bind(f) { - var args = Array.prototype.slice.call(arguments, 1); - return function(){return f.apply(null, args);}; - } - - var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; - var isWordChar = CodeMirror.isWordChar = function(ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); - }; - - function isEmpty(obj) { - for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; - return true; - } - - // Extending unicode characters. A series of a non-extending char + - // any number of extending chars is treated as a single unit as far - // as editing and measuring is concerned. This is not fully correct, - // since some scripts/fonts/browsers also treat other configurations - // of code points as a group. - var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; - function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } - - // DOM UTILITIES - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") e.appendChild(document.createTextNode(content)); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - var range; - if (document.createRange) range = function(node, start, end) { - var r = document.createRange(); - r.setEnd(node, end); - r.setStart(node, start); - return r; - }; - else range = function(node, start, end) { - var r = document.body.createTextRange(); - r.moveToElementText(node.parentNode); - r.collapse(true); - r.moveEnd("character", end); - r.moveStart("character", start); - return r; - }; - - function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) - e.removeChild(e.firstChild); - return e; - } - - function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e); - } - - function contains(parent, child) { - if (parent.contains) - return parent.contains(child); - while (child = child.parentNode) - if (child == parent) return true; - } - - function activeElt() { return document.activeElement; } - // Older versions of IE throws unspecified error when touching - // document.activeElement in some cases (during loading, in iframe) - if (ie_upto10) activeElt = function() { - try { return document.activeElement; } - catch(e) { return document.body; } - }; - - function classTest(cls) { return new RegExp("\\b" + cls + "\\b\\s*"); } - function rmClass(node, cls) { - var test = classTest(cls); - if (test.test(node.className)) node.className = node.className.replace(test, ""); - } - function addClass(node, cls) { - if (!classTest(cls).test(node.className)) node.className += " " + cls; - } - function joinClasses(a, b) { - var as = a.split(" "); - for (var i = 0; i < as.length; i++) - if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; - return b; - } - - // FEATURE DETECTION - - // Detect drag-and-drop - var dragAndDrop = function() { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie_upto8) return false; - var div = elt('div'); - return "draggable" in div || "dragDrop" in div; - }(); - - var knownScrollbarWidth; - function scrollbarWidth(measure) { - if (knownScrollbarWidth != null) return knownScrollbarWidth; - var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll"); - removeChildrenAndAdd(measure, test); - if (test.offsetWidth) - knownScrollbarWidth = test.offsetHeight - test.clientHeight; - return knownScrollbarWidth || 0; - } - - var zwspSupported; - function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b"); - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); - if (measure.firstChild.offsetHeight != 0) - zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_upto7; - } - if (zwspSupported) return elt("span", "\u200b"); - else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); - } - - // Feature-detect IE's crummy client rect reporting for bidi text - var badBidiRects; - function hasBadBidiRects(measure) { - if (badBidiRects != null) return badBidiRects; - var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); - var r0 = range(txt, 0, 1).getBoundingClientRect(); - if (r0.left == r0.right) return false; - var r1 = range(txt, 1, 2).getBoundingClientRect(); - return badBidiRects = (r1.right - r0.right < 3); - } - - // See if "".split is the broken IE version, if so, provide an - // alternative way to split lines. - var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { - var pos = 0, result = [], l = string.length; - while (pos <= l) { - var nl = string.indexOf("\n", pos); - if (nl == -1) nl = string.length; - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); - var rt = line.indexOf("\r"); - if (rt != -1) { - result.push(line.slice(0, rt)); - pos += rt + 1; - } else { - result.push(line); - pos = nl + 1; - } - } - return result; - } : function(string){return string.split(/\r\n?|\n/);}; - - var hasSelection = window.getSelection ? function(te) { - try { return te.selectionStart != te.selectionEnd; } - catch(e) { return false; } - } : function(te) { - try {var range = te.ownerDocument.selection.createRange();} - catch(e) {} - if (!range || range.parentElement() != te) return false; - return range.compareEndPoints("StartToEnd", range) != 0; - }; - - var hasCopyEvent = (function() { - var e = elt("div"); - if ("oncopy" in e) return true; - e.setAttribute("oncopy", "return;"); - return typeof e.oncopy == "function"; - })(); - - // KEY NAMES - - var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete", - 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", - 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"}; - CodeMirror.keyNames = keyNames; - (function() { - // Number keys - for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); - // Alphabetic keys - for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); - // Function keys - for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; - })(); - - // BIDI HELPERS - - function iterateBidiSections(order, from, to, f) { - if (!order) return f(from, to, "ltr"); - var found = false; - for (var i = 0; i < order.length; ++i) { - var part = order[i]; - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); - found = true; - } - } - if (!found) f(from, to, "ltr"); - } - - function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } - function bidiRight(part) { return part.level % 2 ? part.from : part.to; } - - function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } - function lineRight(line) { - var order = getOrder(line); - if (!order) return line.text.length; - return bidiRight(lst(order)); - } - - function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLine(line); - if (visual != line) lineN = lineNo(visual); - var order = getOrder(visual); - var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); - return Pos(lineN, ch); - } - function lineEnd(cm, lineN) { - var merged, line = getLine(cm.doc, lineN); - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - lineN = null; - } - var order = getOrder(line); - var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); - return Pos(lineN == null ? lineNo(line) : lineN, ch); - } - - function compareBidiLevel(order, a, b) { - var linedir = order[0].level; - if (a == linedir) return true; - if (b == linedir) return false; - return a < b; - } - var bidiOther; - function getBidiPartAt(order, pos) { - bidiOther = null; - for (var i = 0, found; i < order.length; ++i) { - var cur = order[i]; - if (cur.from < pos && cur.to > pos) return i; - if ((cur.from == pos || cur.to == pos)) { - if (found == null) { - found = i; - } else if (compareBidiLevel(order, cur.level, order[found].level)) { - if (cur.from != cur.to) bidiOther = found; - return i; - } else { - if (cur.from != cur.to) bidiOther = i; - return found; - } - } - } - return found; - } - - function moveInLine(line, pos, dir, byUnit) { - if (!byUnit) return pos + dir; - do pos += dir; - while (pos > 0 && isExtendingChar(line.text.charAt(pos))); - return pos; - } - - // This is needed in order to move 'visually' through bi-directional - // text -- i.e., pressing left should make the cursor go left, even - // when in RTL text. The tricky part is the 'jumps', where RTL and - // LTR text touch each other. This often requires the cursor offset - // to move more than one unit, in order to visually move one unit. - function moveVisually(line, start, dir, byUnit) { - var bidi = getOrder(line); - if (!bidi) return moveLogically(line, start, dir, byUnit); - var pos = getBidiPartAt(bidi, start), part = bidi[pos]; - var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); - - for (;;) { - if (target > part.from && target < part.to) return target; - if (target == part.from || target == part.to) { - if (getBidiPartAt(bidi, target) == pos) return target; - part = bidi[pos += dir]; - return (dir > 0) == part.level % 2 ? part.to : part.from; - } else { - part = bidi[pos += dir]; - if (!part) return null; - if ((dir > 0) == part.level % 2) - target = moveInLine(line, part.to, -1, byUnit); - else - target = moveInLine(line, part.from, 1, byUnit); - } - } - } - - function moveLogically(line, start, dir, byUnit) { - var target = start + dir; - if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; - return target < 0 || target > line.text.length ? null : target; - } - - // Bidirectional ordering algorithm - // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm - // that this (partially) implements. - - // One-char codes used for character types: - // L (L): Left-to-Right - // R (R): Right-to-Left - // r (AL): Right-to-Left Arabic - // 1 (EN): European Number - // + (ES): European Number Separator - // % (ET): European Number Terminator - // n (AN): Arabic Number - // , (CS): Common Number Separator - // m (NSM): Non-Spacing Mark - // b (BN): Boundary Neutral - // s (B): Paragraph Separator - // t (S): Segment Separator - // w (WS): Whitespace - // N (ON): Other Neutrals - - // Returns null if characters are ordered as they appear - // (left-to-right), or an array of sections ({from, to, level} - // objects) in the order in which they occur visually. - var bidiOrdering = (function() { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; - // Character types for codepoints 0x600 to 0x6ff - var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; - function charType(code) { - if (code <= 0xf7) return lowTypes.charAt(code); - else if (0x590 <= code && code <= 0x5f4) return "R"; - else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); - else if (0x6ee <= code && code <= 0x8ac) return "r"; - else if (0x2000 <= code && code <= 0x200b) return "w"; - else if (code == 0x200c) return "b"; - else return "L"; - } - - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; - // Browsers seem to always treat the boundaries of block elements as being L. - var outerType = "L"; - - function BidiSpan(level, from, to) { - this.level = level; - this.from = from; this.to = to; - } - - return function(str) { - if (!bidiRE.test(str)) return false; - var len = str.length, types = []; - for (var i = 0, type; i < len; ++i) - types.push(type = charType(str.charCodeAt(i))); - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i = 0, prev = outerType; i < len; ++i) { - var type = types[i]; - if (type == "m") types[i] = prev; - else prev = type; - } - - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (type == "1" && cur == "r") types[i] = "n"; - else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } - } - - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i = 1, prev = types[0]; i < len - 1; ++i) { - var type = types[i]; - if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; - else if (type == "," && prev == types[i+1] && - (prev == "1" || prev == "n")) types[i] = prev; - prev = type; - } - - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i = 0; i < len; ++i) { - var type = types[i]; - if (type == ",") types[i] = "N"; - else if (type == "%") { - for (var end = i + 1; end < len && types[end] == "%"; ++end) {} - var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (cur == "L" && type == "1") types[i] = "L"; - else if (isStrong.test(type)) cur = type; - } - - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i = 0; i < len; ++i) { - if (isNeutral.test(types[i])) { - for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} - var before = (i ? types[i-1] : outerType) == "L"; - var after = (end < len ? types[end] : outerType) == "L"; - var replace = before || after ? "L" : "R"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m; - for (var i = 0; i < len;) { - if (countsAsLeft.test(types[i])) { - var start = i; - for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} - order.push(new BidiSpan(0, start, i)); - } else { - var pos = i, at = order.length; - for (++i; i < len && types[i] != "L"; ++i) {} - for (var j = pos; j < i;) { - if (countsAsNum.test(types[j])) { - if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); - var nstart = j; - for (++j; j < i && countsAsNum.test(types[j]); ++j) {} - order.splice(at, 0, new BidiSpan(2, nstart, j)); - pos = j; - } else ++j; - } - if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); - } - } - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift(new BidiSpan(0, 0, m[0].length)); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push(new BidiSpan(0, len - m[0].length, len)); - } - if (order[0].level != lst(order).level) - order.push(new BidiSpan(order[0].level, len, len)); - - return order; - }; - })(); - - // THE END - - CodeMirror.version = "4.1.0"; - - return CodeMirror; -}); diff --git a/cmd/mist/assets/muted/lib/go.js b/cmd/mist/assets/muted/lib/go.js deleted file mode 100644 index 9f1c1c4ab..000000000 --- a/cmd/mist/assets/muted/lib/go.js +++ /dev/null @@ -1,182 +0,0 @@ -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("go", function(config) { - var indentUnit = config.indentUnit; - - var keywords = { - "break":true, "case":true, "chan":true, "const":true, "continue":true, - "default":true, "defer":true, "else":true, "fallthrough":true, "for":true, - "func":true, "go":true, "goto":true, "if":true, "import":true, - "interface":true, "map":true, "package":true, "range":true, "return":true, - "select":true, "struct":true, "switch":true, "type":true, "var":true, - "bool":true, "byte":true, "complex64":true, "complex128":true, - "float32":true, "float64":true, "int8":true, "int16":true, "int32":true, - "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true, - "uint64":true, "int":true, "uint":true, "uintptr":true, "big": true, - "main": true, "init": true, "this":true - }; - - var atoms = { - "true":true, "false":true, "iota":true, "nil":true, "append":true, - "cap":true, "close":true, "complex":true, "copy":true, "imag":true, - "len":true, "make":true, "new":true, "panic":true, "print":true, - "println":true, "real":true, "recover":true, - }; - - var isOperatorChar = /[+\-*&^%:=<>!|\/]/; - - var curPunc; - - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'" || ch == "`") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } - if (/[\d\.]/.test(ch)) { - if (ch == ".") { - stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/); - } else if (ch == "0") { - stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/); - } else { - stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/); - } - return "number"; - } - if (/[\[\]{}\(\),;\:\.]/.test(ch)) { - curPunc = ch; - return null; - } - if (ch == "/") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } - if (stream.eat("/")) { - stream.skipToEnd(); - return "comment"; - } - } - if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return "operator"; - } - stream.eatWhile(/[\w\$_]/); - var cur = stream.current(); - if (keywords.propertyIsEnumerable(cur)) { - if (cur == "case" || cur == "default") curPunc = "case"; - return "keyword"; - } - if (atoms.propertyIsEnumerable(cur)) return "atom"; - return "variable"; - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next, end = false; - while ((next = stream.next()) != null) { - if (next == quote && !escaped) {end = true; break;} - escaped = !escaped && next == "\\"; - } - if (end || !(escaped || quote == "`")) - state.tokenize = tokenBase; - return "string"; - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return "comment"; - } - - function Context(indented, column, type, align, prev) { - this.indented = indented; - this.column = column; - this.type = type; - this.align = align; - this.prev = prev; - } - function pushContext(state, col, type) { - return state.context = new Context(state.indented, col, type, null, state.context); - } - function popContext(state) { - var t = state.context.type; - if (t == ")" || t == "]" || t == "}") - state.indented = state.context.indented; - return state.context = state.context.prev; - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: null, - context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), - indented: 0, - startOfLine: true - }; - }, - - token: function(stream, state) { - var ctx = state.context; - if (stream.sol()) { - if (ctx.align == null) ctx.align = false; - state.indented = stream.indentation(); - state.startOfLine = true; - if (ctx.type == "case") ctx.type = "}"; - } - if (stream.eatSpace()) return null; - curPunc = null; - var style = (state.tokenize || tokenBase)(stream, state); - if (style == "comment") return style; - if (ctx.align == null) ctx.align = true; - - if (curPunc == "{") pushContext(state, stream.column(), "}"); - else if (curPunc == "[") pushContext(state, stream.column(), "]"); - else if (curPunc == "(") pushContext(state, stream.column(), ")"); - else if (curPunc == "case") ctx.type = "case"; - else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state); - else if (curPunc == ctx.type) popContext(state); - state.startOfLine = false; - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase && state.tokenize != null) return 0; - var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); - if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) { - state.context.type = "}"; - return ctx.indented; - } - var closing = firstChar == ctx.type; - if (ctx.align) return ctx.column + (closing ? 0 : 1); - else return ctx.indented + (closing ? 0 : indentUnit); - }, - - electricChars: "{}):", - fold: "brace", - blockCommentStart: "/*", - blockCommentEnd: "*/", - lineComment: "//" - }; -}); - -CodeMirror.defineMIME("text/x-go", "go"); - -}); diff --git a/cmd/mist/assets/muted/lib/matchbrackets.js b/cmd/mist/assets/muted/lib/matchbrackets.js deleted file mode 100644 index dcdde81df..000000000 --- a/cmd/mist/assets/muted/lib/matchbrackets.js +++ /dev/null @@ -1,117 +0,0 @@ -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && - (document.documentMode == null || document.documentMode < 8); - - var Pos = CodeMirror.Pos; - - var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; - - function findMatchingBracket(cm, where, strict, config) { - var line = cm.getLineHandle(where.line), pos = where.ch - 1; - var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; - if (!match) return null; - var dir = match.charAt(1) == ">" ? 1 : -1; - if (strict && (dir > 0) != (pos == where.ch)) return null; - var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); - - var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); - if (found == null) return null; - return {from: Pos(where.line, pos), to: found && found.pos, - match: found && found.ch == match.charAt(0), forward: dir > 0}; - } - - // bracketRegex is used to specify which type of bracket to scan - // should be a regexp, e.g. /[[\]]/ - // - // Note: If "where" is on an open bracket, then this bracket is ignored. - // - // Returns false when no bracket was found, null when it reached - // maxScanLines and gave up - function scanForBracket(cm, where, dir, style, config) { - var maxScanLen = (config && config.maxScanLineLength) || 10000; - var maxScanLines = (config && config.maxScanLines) || 1000; - - var stack = []; - var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; - var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) - : Math.max(cm.firstLine() - 1, where.line - maxScanLines); - for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { - var line = cm.getLine(lineNo); - if (!line) continue; - var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; - if (line.length > maxScanLen) continue; - if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); - for (; pos != end; pos += dir) { - var ch = line.charAt(pos); - if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { - var match = matching[ch]; - if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); - else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; - else stack.pop(); - } - } - } - return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; - } - - function matchBrackets(cm, autoclear, config) { - // Disable brace matching in long lines, since it'll cause hugely slow updates - var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; - var marks = [], ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); - if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { - var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; - marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); - if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) - marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); - } - } - - if (marks.length) { - // Kludge to work around the IE bug from issue #1193, where text - // input stops going to the textare whever this fires. - if (ie_lt8 && cm.state.focused) cm.display.input.focus(); - - var clear = function() { - cm.operation(function() { - for (var i = 0; i < marks.length; i++) marks[i].clear(); - }); - }; - if (autoclear) setTimeout(clear, 800); - else return clear; - } - } - - var currentlyHighlighted = null; - function doMatchBrackets(cm) { - cm.operation(function() { - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} - currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); - }); - } - - CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) - cm.off("cursorActivity", doMatchBrackets); - if (val) { - cm.state.matchBrackets = typeof val == "object" ? val : {}; - cm.on("cursorActivity", doMatchBrackets); - } - }); - - CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); - CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ - return findMatchingBracket(this, pos, strict, config); - }); - CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ - return scanForBracket(this, pos, dir, style, config); - }); -}); diff --git a/cmd/mist/assets/muted/muted.js b/cmd/mist/assets/muted/muted.js deleted file mode 100644 index 467411577..000000000 --- a/cmd/mist/assets/muted/muted.js +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301 USA - -// Helper function for generating pseudo callbacks and sending data to the QML part of the application -function postData(data, cb) { - data._seed = Math.floor(Math.random() * 1000000) - if(cb) { - Muted._callbacks[data._seed] = cb; - } - - if(data.args === undefined) { - data.args = []; - } - - navigator.qt.postMessage(JSON.stringify(data)); -} - -window.Muted = { - prototype: Object(), -} - -window.Muted._callbacks = {} -window.Muted._onCallbacks = {} - -function debug(/**/) { - console.log("hello world") - - var args = arguments; - var msg = "" - for(var i = 0; i < args.length; i++){ - if(typeof args[i] == "object") { - msg += " " + JSON.stringify(args[i]) - } else { - msg += args[i] - } - } - - document.querySelector("#debugger").innerHTML += "
"+msg+"
"; -} -console.log = function() { - var args = [] - for(var i = 0; i < arguments.length; i++) { - args.push(arguments[i]); - } - postData({call:"log", args:args}) -} - -navigator.qt.onmessage = function(ev) { - var data = JSON.parse(ev.data) - - if(data._event !== undefined) { - Muted.trigger(data._event, data.data); - } else { - if(data._seed) { - var cb = Muted._callbacks[data._seed]; - if(cb) { - // Call the callback - cb(data.data); - // Remove the "trigger" callback - delete Muted._callbacks[ev._seed]; - } - } - } -} diff --git a/cmd/mist/assets/net.png b/cmd/mist/assets/net.png deleted file mode 100644 index 65a20ea00cc191087fd90704f5874dc376c0433b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4669 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 Z4%d24+^kq*uX+uL$Nkc;* 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 diff --git a/cmd/mist/assets/pick.png b/cmd/mist/assets/pick.png deleted file mode 100644 index 2f5a261c263a476ffaa7b5b4db19766077b87acb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 932 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}oCO|{#S9GG z!XV7ZFl&wkP(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1aGPZ!6K2+p@t z_Ifcp3LGzvmkMM~N?a^>BwWB-I(zk$uHGM!H(qdaWTh%1%w^#lL zhh0O(&d=tvVk3DIAYwdEEuSyVLnJi%UP})Z0xvd(j zg56ADpS*oIEQHK0e>nBWlcNPBm>|1{`XWay0$BktQHz%nn{BK_|kKweF zpYrnwd=C~s@k*4)Yx>j{a*#tjFtcT&?#(O5Tg?;ro4Def_wM@nN#mo|&bA{D6!m;N zJRi?AS*YgnF!;o~gOQ>80w!=T*OUF3`ib{s^Gx$ZsfZ0H-iG@g&7E~3g{w@kRAte% zP5izEDMf+Xzsji|y7hl;fSudheFbI0rQga7H)a<^Y`&>fqE#K>>tNG<-=J}=-y~_v zG%s5<#xj?^N59vFINd2Mx_n~2;B2;{GwL78)jqJzuJEqBm$&>6DC>B-`njxgN@xNA DTr*?p diff --git a/cmd/mist/assets/qml/QmlApp.qml b/cmd/mist/assets/qml/QmlApp.qml deleted file mode 100644 index f5c503f4c..000000000 --- a/cmd/mist/assets/qml/QmlApp.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import Ethereum 1.0 - -ApplicationWindow { - minimumWidth: 500 - maximumWidth: 500 - maximumHeight: 400 - minimumHeight: 400 - - function onNewBlockCb(block) { - console.log("Please overwrite onNewBlock(block):", block) - } - function onObjectChangeCb(stateObject) { - console.log("Please overwrite onObjectChangeCb(object)", stateObject) - } - function onStorageChangeCb(storageObject) { - var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":"); - console.log("Please overwrite onStorageChangeCb(object)", ev) - } -} diff --git a/cmd/mist/assets/qml/depricated_browser.qml b/cmd/mist/assets/qml/depricated_browser.qml deleted file mode 100644 index 7fb1f2068..000000000 --- a/cmd/mist/assets/qml/depricated_browser.qml +++ /dev/null @@ -1,486 +0,0 @@ -import QtQuick 2.1 -import QtWebKit 3.0 -import QtWebKit.experimental 1.0 -import QtQuick.Controls 1.0; -import QtQuick.Controls.Styles 1.0 -import QtQuick.Layouts 1.0; -import QtQuick.Window 2.1; -import Ethereum 1.0 - -Rectangle { - id: window - anchors.fill: parent - color: "#00000000" - - property var title: "DApps" - property var iconSource: "../browser.png" - property var menuItem - property var hideUrl: true - - property alias url: webview.url - property alias windowTitle: webview.title - property alias webView: webview - - property var cleanPath: false - property var open: function(url) { - if(!window.cleanPath) { - var uri = url; - if(!/.*\:\/\/.*/.test(uri)) { - uri = "http://" + uri; - } - - var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ - - if(reg.test(uri)) { - uri.replace(reg, function(match, pre, domain, path) { - uri = pre; - - var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); - var ip = []; - for(var i = 0, l = lookup.length; i < l; i++) { - ip.push(lookup.charCodeAt(i)) - } - - if(ip.length != 0) { - uri += lookup; - } else { - uri += domain; - } - - uri += path; - }); - } - - window.cleanPath = true; - - webview.url = uri; - - //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2$3"); - uriNav.text = uri; - } else { - // Prevent inf loop. - window.cleanPath = false; - } - } - - Component.onCompleted: { - webview.url = "http://etherian.io" - } - - function messages(messages, id) { - // Bit of a cheat to get proper JSON - var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - webview.postEvent("eth_changed", id, m); - } - - function onShhMessage(message, id) { - webview.postEvent("shh_changed", id, message) - } - - Item { - objectName: "root" - id: root - anchors.fill: parent - state: "inspectorShown" - - RowLayout { - id: navBar - height: 40 - anchors { - left: parent.left - right: parent.right - leftMargin: 7 - } - - Button { - id: back - onClicked: { - webview.goBack() - } - style: ButtonStyle { - background: Image { - source: "../back.png" - width: 30 - height: 30 - } - } - } - - TextField { - anchors { - left: back.right - right: toggleInspector.left - leftMargin: 10 - rightMargin: 10 - } - text: webview.url; - id: uriNav - y: parent.height / 2 - this.height / 2 - - Keys.onReturnPressed: { - webview.url = this.text; - } - } - - Button { - id: toggleInspector - anchors { - right: parent.right - } - iconSource: "../bug.png" - onClicked: { - if(inspector.visible == true){ - inspector.visible = false - }else{ - inspector.visible = true - inspector.url = webview.experimental.remoteInspectorUrl - } - } - } - } - - // Border - Rectangle { - id: divider - anchors { - left: parent.left - right: parent.right - top: navBar.bottom - } - z: -1 - height: 1 - color: "#CCCCCC" - } - - ScrollView { - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - top: divider.bottom - } - WebView { - objectName: "webView" - id: webview - anchors.fill: parent - - function sendMessage(data) { - webview.experimental.postMessage(JSON.stringify(data)) - } - - experimental.preferences.javascriptEnabled: true - experimental.preferences.webAudioEnabled: true - experimental.preferences.pluginsEnabled: true - experimental.preferences.navigatorQtObjectEnabled: true - experimental.preferences.developerExtrasEnabled: true - experimental.preferences.webGLEnabled: true - experimental.preferences.notificationsEnabled: true - experimental.preferences.localStorageEnabled: true - experimental.userAgent:"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Mist/0.1 Safari/537.36" - - experimental.itemSelector: MouseArea { - // To avoid conflicting with ListView.model when inside Initiator context. - property QtObject selectorModel: model - anchors.fill: parent - onClicked: selectorModel.reject() - - Menu { - visible: true - id: itemSelector - - Instantiator { - model: selectorModel.items - delegate: MenuItem { - text: model.text - onTriggered: { - selectorModel.accept(index) - } - } - onObjectAdded: itemSelector.insertItem(index, object) - onObjectRemoved: itemSelector.removeItem(object) - } - } - - Component.onCompleted: { - itemSelector.popup() - } - } - experimental.userScripts: ["../ext/q.js", "../ext/ethereum.js/dist/ethereum.min.js", "../ext/setup.js"] - experimental.onMessageReceived: { - //console.log("[onMessageReceived]: ", message.data) - var data = JSON.parse(message.data) - - try { - switch(data.call) { - case "eth_compile": - postData(data._id, eth.compile(data.args[0])) - break - - case "eth_coinbase": - postData(data._id, eth.coinBase()) - - case "eth_account": - postData(data._id, eth.key().address); - - case "eth_istening": - postData(data._id, eth.isListening()) - - break - - case "eth_mining": - postData(data._id, eth.isMining()) - - break - - case "eth_peerCount": - postData(data._id, eth.peerCount()) - - break - - case "eth_countAt": - require(1) - postData(data._id, eth.txCountAt(data.args[0])) - - break - - case "eth_codeAt": - require(1) - var code = eth.codeAt(data.args[0]) - postData(data._id, code); - - break - - case "eth_blockByNumber": - require(1) - var block = eth.blockByNumber(data.args[0]) - postData(data._id, block) - break - - case "eth_blockByHash": - require(1) - var block = eth.blockByHash(data.args[0]) - postData(data._id, block) - break - - require(2) - var block = eth.blockByHash(data.args[0]) - postData(data._id, block.transactions[data.args[1]]) - break - - case "eth_transactionByHash": - case "eth_transactionByNumber": - require(2) - - var block; - if (data.call === "transactionByHash") - block = eth.blockByHash(data.args[0]) - else - block = eth.blockByNumber(data.args[0]) - - var tx = block.transactions.get(data.args[1]) - - postData(data._id, tx) - break - - case "eth_uncleByHash": - case "eth_uncleByNumber": - require(2) - - var block; - if (data.call === "uncleByHash") - block = eth.blockByHash(data.args[0]) - else - block = eth.blockByNumber(data.args[0]) - - var uncle = block.uncles.get(data.args[1]) - - postData(data._id, uncle) - - break - - case "transact": - require(5) - - var tx = eth.transact(data.args) - postData(data._id, tx) - - break - - case "eth_stateAt": - require(2); - - var storage = eth.storageAt(data.args[0], data.args[1]); - postData(data._id, storage) - - break - - case "eth_call": - require(1); - var ret = eth.call(data.args) - postData(data._id, ret) - break - - case "eth_balanceAt": - require(1); - - postData(data._id, eth.balanceAt(data.args[0])); - break - - case "eth_watch": - require(2) - eth.watch(data.args[0], data.args[1]) - - case "eth_disconnect": - require(1) - postData(data._id, null) - break; - - case "eth_newFilterString": - require(1) - var id = eth.newFilterString(data.args[0], window) - postData(data._id, id); - break; - - case "eth_newFilter": - require(1) - var id = eth.newFilter(data.args[0], window) - - postData(data._id, id); - break; - - case "eth_filterLogs": - require(1); - - var messages = eth.messages(data.args[0]); - var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - postData(data._id, m); - - break; - - case "eth_deleteFilter": - require(1); - eth.uninstallFilter(data.args[0]) - break; - - - case "shh_newFilter": - require(1); - var id = shh.watch(data.args[0], window); - postData(data._id, id); - break; - - case "shh_newIdentity": - var id = shh.newIdentity() - postData(data._id, id) - - break - - case "shh_post": - require(1); - - var params = data.args[0]; - var fields = ["payload", "to", "from"]; - for(var i = 0; i < fields.length; i++) { - params[fields[i]] = params[fields[i]] || ""; - } - if(typeof params.payload !== "object") { params.payload = [params.payload]; } //params.payload = params.payload.join(""); } - params.topics = params.topics || []; - params.priority = params.priority || 1000; - params.ttl = params.ttl || 100; - - shh.post(params.payload, params.to, params.from, params.topics, params.priority, params.ttl); - - break; - - case "shh_getMessages": - require(1); - - var m = shh.messages(data.args[0]); - var messages = JSON.parse(JSON.parse(JSON.stringify(m))); - postData(data._id, messages); - - break; - - case "ssh_newGroup": - postData(data._id, ""); - break; - } - } catch(e) { - console.log(data.call + ": " + e) - - postData(data._id, null); - } - } - - function post(seed, data) { - postData(data._id, data) - } - function require(args, num) { - if(args.length < num) { - throw("required argument count of "+num+" got "+args.length); - } - } - function postData(seed, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _id: seed})) - } - function postEvent(event, id, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _id: id, _event: event})) - } - function onWatchedCb(data, id) { - var messages = JSON.parse(data) - postEvent("watched:"+id, messages) - } - function onNewBlockCb(block) { - postEvent("block:new", block) - } - function onObjectChangeCb(stateObject) { - postEvent("object:"+stateObject.address(), stateObject) - } - function onStorageChangeCb(storageObject) { - var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":"); - postEvent(ev, [storageObject.address, storageObject.value]) - } - } - } - - Rectangle { - id: sizeGrip - color: "gray" - visible: false - height: 10 - anchors { - left: root.left - right: root.right - } - y: Math.round(root.height * 2 / 3) - - MouseArea { - anchors.fill: parent - drag.target: sizeGrip - drag.minimumY: 0 - drag.maximumY: root.height - drag.axis: Drag.YAxis - } - } - - WebView { - id: inspector - visible: false - anchors { - left: root.left - right: root.right - top: sizeGrip.bottom - bottom: root.bottom - } - } - - states: [ - State { - name: "inspectorShown" - PropertyChanges { - target: inspector - } - } - ] - } -} diff --git a/cmd/mist/assets/qml/first_run.qml b/cmd/mist/assets/qml/first_run.qml deleted file mode 100644 index 0b1dac4c6..000000000 --- a/cmd/mist/assets/qml/first_run.qml +++ /dev/null @@ -1,155 +0,0 @@ -import QtQuick 2.0 -import Ethereum 1.0 - -// Which ones do we actually need? -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import QtQuick.Dialogs 1.1 - -ApplicationWindow { - id: wizardRoot - width: 500 - height: 400 - title: "Ethereal first run setup" - - Column { - spacing: 5 - anchors.leftMargin: 10 - anchors.left: parent.left - - Text { - visible: true - text: "

Ethereal setup

" - } - - Column { - id: restoreColumn - spacing: 5 - Text { - visible: true - font.pointSize: 14 - text: "Restore your Ethereum account" - id: restoreLabel - } - - TextField { - id: txPrivKey - width: 480 - placeholderText: "Private key or mnemonic words" - focus: true - onTextChanged: { - if(this.text.length == 64){ - detailLabel.text = "Private (hex) key detected." - actionButton.enabled = true - } - else if(this.text.split(" ").length == 24){ - detailLabel.text = "Mnemonic key detected." - actionButton.enabled = true - }else{ - detailLabel.text = "" - actionButton.enabled = false - } - } - } - Row { - spacing: 10 - Button { - id: actionButton - text: "Restore" - enabled: false - onClicked: { - var success = lib.importAndSetPrivKey(txPrivKey.text) - if(success){ - importedDetails.visible = true - restoreColumn.visible = false - newKey.visible = false - wizardRoot.height = 120 - } - } - } - Text { - id: detailLabel - font.pointSize: 12 - anchors.topMargin: 10 - } - } - } - Column { - id: importedDetails - visible: false - Text { - text: "Your account has been imported. Please close the application and restart it again to let the changes take effect." - wrapMode: Text.WordWrap - width: 460 - } - } - Column { - spacing: 5 - id: newDetailsColumn - visible: false - Text { - font.pointSize: 14 - text: "Your account details" - } - Label { - text: "Address" - } - TextField { - id: addressInput - readOnly:true - width: 480 - } - Label { - text: "Private key" - } - TextField { - id: privkeyInput - readOnly:true - width: 480 - } - Label { - text: "Mnemonic words" - } - TextField { - id: mnemonicInput - readOnly:true - width: 480 - } - Label { - text: "A new account has been created. Please take the time to write down the 24 words. You can use those to restore your account at a later date." - wrapMode: Text.WordWrap - width: 480 - } - Label { - text: "Please restart the application once you have completed the steps above." - wrapMode: Text.WordWrap - width: 480 - } - } - - } - Button { - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.rightMargin: 10 - anchors.bottomMargin: 10 - id: newKey - text: "I don't have an account yet" - onClicked: { - var res = lib.createAndSetPrivKey() - mnemonicInput.text = res[0] - addressInput.text = res[1] - privkeyInput.text = res[2] - - // Hide restore - restoreColumn.visible = false - - // Show new details - newDetailsColumn.visible = true - newKey.visible = false - } - } -} diff --git a/cmd/mist/assets/qml/fonts/Simple-Line-Icons.ttf b/cmd/mist/assets/qml/fonts/Simple-Line-Icons.ttf deleted file mode 100755 index 2194f1f87ffb06e2664e4e56e8656060967e4f9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35304 zcmdqKcYIt|nKypV?QME58cos6sB5Ir%t)54=5EWj9Je^J6FJR}Q>+w+Bm|=1B&6d| zLRkV1u+#t!yRsBt~h+d z$&U(xdPWd#O&_}az-9IJX9BqPb9}0Ya6@jgIdJo=@bALY*dIdq^tA`Bx%}SmZTOZT+~LLh&DkS2+<2fgyi*X4 zCGpO?1!@~U-Jd#i@P&dp2x8+IG6c7?D@055PC)7 zY`rdsj6aEPY5pnv%!h@i(0BAlcRHoU=@5TR6xeY=5p*`iuE6p7#`nJqG2u?SK|wz? z|4{wKzv(O1UM7q$2xkPgaCSlHMcuM&?;Qul;GP# zjeREU5pL)EeL^3`Y8&=TsClVzJ=xgD*svs5t}f1!4KU z=Tuto2-CvMvip|x3!cn`BCa#+(fdGWulcuuUr9HvcjLPxl+N{xEtH-%AQIyAdb!CWS0Kc1A$o;g3ei+4DMOF<0;>3xAH0SMlr! z?ulZ=<3a+@Z4pu!m$YCAreFy+XvdA#XN0VfL(TF+0c~v;Is~ua6Z}Fz2nrz~EOZK8 zLbuQ(^r8<-LccH|l!ZZ|B21EsaJTSg;U3{$;XdJh;Q`@6;UVEI!g1kY;jO~kgtrUt5FQcUDZEQ~x9}d} z&xH31j|%S--Y=XG9uqzwd{Foh`X7DikQu&-V$P+SrHj1F|9`)63vUO5xr99pZjHD8EZv#DHvQ#{o!OUpIxA*3 zWFN}Oxp%b%fItM%FI{$Z9wd-5m zS9Cwn{f!>Ar?=_i$b*lPE_1Ri`ZC~wuwSOKO9s1g^dqvxdn^yegihmuM z8u{?b?8;kL5t{``om~KLULbn%v5Y9xaZu;zu^=DPh z%|dSGVJR`9xy2S143{$l)m01yl*(XjV2o7ukD;1>{&5)F-N@Yrs49Tx+Qn94nFPr{=i_ND0Xz{fwq=>sg!SN3+NpkqNu7yyFSTexdXj{-f8qjnfQEdaEy&IbOf4P zEf0jzdNe59%4)??I#(Q!V?hyfD@Jpwk00^%Lw=$#5Gb%`mj)PR3Rz^_&%0pO}tUtMTdNx`36_ zBk5ptM{c@(!-n?h%+A;(Q+;~L6-bYtb1#30z{i-qgz+zfPYUJApW3iuwcugJf-{=6 z>KNl~aYtes+KU^bQMcmV9@vvgQCm_Epe=qk8;^e_X0GkDEkzl&EK!_lHe+3Kc{7TM zj#q8Q)j|8pF3VC}%8+e~(v6KayvWl}Pb6TOcGK}IFi-fC1c6@oA zOZ8JUM$6k}xXn~*wAYGQJ=oYiJ$A(E?ZF{SH~T)iy4m;5CZ0P|a$Jk<_z~`L?p}Hh zSY!BAGy;iyE5C5T)g^n2a>DQY;c$RtQB#8J~LvrBEw} zf{{W#sAdbRSSF%sM15g4`y5deZSIy_TTQjTpczvxiHU|gQS)r<nF-r{S#g|sL7Vu`-sbXBS+7eA5BM@-?<(bp=`swLc|=*&%d)8Gq77R}2J16aj-3c5>%4*N z1YND4K)FDi-QYCFnfHPRhOF zwNES*!~Nv}`ZvPHM2F3yUm{>a;Jmf0hxLlNY!2TlXS!N8*NHCWC$ykLE7Z5OYGoy> z)QEcUEU@XyU@t4;8*gDh)MQz6A2yk&Dx&IX3HsV5491wm(u%BQGYs^dG*!hmN89>p z(>_fUnY8=jl-s&85XvR5j9xPhbHZiiag&|Cc}!NV9z|j~-fh)V+nC`pa$%LJtZb-qD8!73oIjZIsNmKj zGp`J!lUHI2n;8QP!tS2%FpPm>cI%s%Zg@TNN^|s<7MtnOs7IW>Dt4u>Go@K1>?ENG z`ui#9uMc|Q0cWIXVmZ9}wZ0vhMf1M_8S0hqnAiaF{H{o@6%YBnOG+VQvsnu>f+2go!#t z{4WngAoIX#Ao=NJ6|@8XQv~_+4?v)U4WSI!j*44*MN${Cnu@2O7ojO=bQ%O$9vJ16 zTCMe0*#nWzfLpTyGKh;wUN90*usuASZMB(Cv;A(j?(#{tJK@PB;u%lUW63_3?sf-l z%`2L%-hq#b41{JSEY0?&{oOGSb9sUx(;pT+0XrU2+)6lR2Rtm|GebeQ%Ny>MT?ZRRMju!jjAFh7fbRq_9g?4MjDog<$wfF>0u$Wu*df z*^s?S(d&+>YRv5wlODy89XL@4a>ec%uu5_6gT(+=tmU^=l&j?M5vU>%5*Qg04WS@g zFtl0C=*YJ9^POW)9!pOzOf&C^+3D2-rIBg&w42^M@y+}|x$QrlefGVJjvc#5I6IEN z`uKIz?|)bSx;5o@y?+{W>;m+|htUs!BVgGHtY0fjwPJvi8WEcsE=M4MIaLL!g<=lO z3F>5)b+*0fGx#quO_Lu2p=f)Au~0D*R7J_Q6-m@$ss03GEd!~TE{eq;J@Uwp9{J#t z$Iy}WuX3UE7kv9EMNuU)2Kw{_VwR*Tic6K$LGzWdzY!6x3t+1RcH141>E+4g^R-|skBrIayhE+5GG&fj`sQtyNHdu?Oe9Z9; z@=%Hcm59m?^QxwU4@rfDW$qdn+JEey;=y1%aQQCwU}QM(kXT3<#;#Ir|1oySF7{A_ zE$}KH?(d$`jYL7dCvj|5fbRIny=*G~XMJ5$nwBU?_r{Lxy@yS;QN5RJk3HZ#eGG~u z6tG++0u8K+!(ye7^@uoy;}A%}DWTa;V5}62k*yqI11c*7zM_b&$O%PZ&CE zfx?qHLz8uVNRlyMqhoV1y}^SF)EAD@#S%+kET+~{=i#sv)ruBUoE|Z5S9ilmZ0-gNyqbXWi*2kb5uJnfqcP8DcB#5lm_}? zW-YfJB<2e+A3HO?5~}A&{m0NM98HHwphCt-)1VV?sQ)IyjA_<^a`uQ*1ec(CNTMpS z#S<)D|1C4>3;6sNauImW5IE~S(92>?4QRQor)0?bL2awhjYzQ!1yy!xNxe$er%1P| zj~nbG^%*X9*geVM8B)KnNgG-^jmu{Y?f7xc0RK7!{`D^Kujbqolwwn)a<&Nysc|cl zcp5jPz%j`36dRMWy7=wTIeW)0uy<2UXofuToeAiL2|BcPX}ZPymi|RP1+VMNWco6_ zLC6%ha@iB4vufW|CI$%`%u&ksCLOtP62g--nL{8 zmdZ}&ELn@A#EH)_4LQ4qLdOk9CNwO-`x*4brdfDl(|T&!!utKG7B;_V@lDE}G%SqO zTF&-!3nR@?C2#PatoADvl zrAcag+^fo(OZ5gMM>CQFURgFVc~oyKXDEgusgh(Ax-cSLMMIKQ%v8n5MLjqT*(-Y% zZ}fXrmnx~=L?@5}x->j-AC6t>9!+=q{RuyN_L0MrH{@i=a>=oxDY+~>tI&m^@5YmL z)g>8iQLiq_F2(DIoCeVZrGQ6q$)fIw<_yWDf`JsfFpIhhc)o=jI$|iTi)}ZoK0GA3 zY)KlBiDEb`E@LhgF_+#A9J2#hCCO&u%5E_fgf@kqBXQS@c}sc|1Cme!zlKeRDFxm~ zWaD&ibx^BB*pJhn`&2dD^RJLOM!^_`i5$CtM2jXQ`PFa2hLXv^Q0+@;`xey?aeER zPZO5wLA{^gi0fgZ@CcMUjXp3)xQ0lTN0ptgRUm)@ARsgfU)4wvdLNWZN2P=j%3DHK z2{jY~w?RUqVg*1^Ww2PKvSjkG-R+5V!b&A$fkbZXid9?2Eo*!r)n^#G%T9L&A{}<_ zl3}TO^1i-x>U7!kFy_;Jnw}9QGw$`9khu{}*31pNCucWyMtrJU^%@qeQ-78{+@g8X zKFLZ1RJCXCrrvf|VA%vZzdy}PmMBGo9sQDN<}00>R`vK+SM4X#+>_Pc^^ zjjYYI(RyhrA?1R8zp7h$B;!`ZX}T~SVDq!3`-_(8jcn2lWu>?Ev;BIgluZX*v7B4+ zyZc>%cjUv6bOE$-T0*xaIY+Ya@Oe6iig_Si@ zCUX^FNw5`)7)WkM5!2(S7uoYrF9)iS^3)paRceE16c{?oNu8|2wAi$@t~560i}@=( zt`$EZ7l&R90Go{VpR$ESc5+hx_s;9UW?lMcB zc-rsog&i6o@5b3*g7^Ix`e!%%2ZNY}Yv31{LZiUqpiPiQ;bt5N0^35Zp??sT2_3ys zs}Av!BYJ3IR~H>|(@y76m1&waB67n+V$%naCK*m}jGAhB!F zGWa}8NZ9Dg@IJ$Mou+h0C2jSPDy~$uwLwvCXU3Kb43`uiR1I_gujR7^7 zw8;?FO%n6kOc`FSNzrauUtd(j;2KRM^9yvh4RrSe=&l{QJwz$Xg@PK1^AOB17~|+w z!ZKH)1tbvYhy`629NMw+$zPbh9l@_k& zMx8!McE=vT=_;5jdWIXa10^ONXy}_Sx^>d55e7vol{E@Y}vbOQ$=bS}u1Yl=6zA zJM065p(spANTMhveMT@GE{39D>E3WpY8&$xl7o6YD+3J9Xrcw38kg*7)E8I7c1DUv zLUKrH?`+9gE7I-$U#0O^qRp+g6}If9jmrvI>`7Y*^;0EM9p_iASfZsT?8C!C#c(*J z`;u@+NC|*CifY-uu-n%fPI#^XET~(emO%w1mW}I!$%3Ex+tb6=z<642yx*@Re6d(E z?Zum?({oF&wXKlpa-k~F*GibDr!Y_Z5CtGa!0QI76G_fNk*yH|L;xopp?gI-QXREi za-b8AQWc6A4M6rlPYckDRZ{6yE@J8z+!%DrN?0=7z!NRCwKWf%5Qveadt_Zyl$b3W z9;U?n_UnG@zhr95<)+7{Dv~9!h?cTb8t_^Zz?aKV{Y96SzHWDNbwW2pt1TQfM~8F6 z>4?TeTemX1GN#M#38rAQ*hXttOK;om>sYuayW!%CH>3-(WXdqxineZcCdSXtpVzW6 zsTpojR8v6$!O7N7gCXdb}JP?d?tfy0G4uOoLb^xa@TfYMetbUnE^@iSl01a84xaw?x1 z^n?dPo^q(OH4OnsaRq&lzq!`tGMWn`&_E{5s-@fnzTU|`Y;y?(rjeWx6!^wZLpD8!h?E%gsdm_NLLP`EDUsxJA$6A|D3k~V%3-xu z0z)kiw6aXT7RuME*vmnGq_V{t9t4NB^aFRh`v-2v#;?Em;5{N+ud2E-U%#5IxxBvf zY1u7*mL+dlkKi=e-UrH_{l@)lL=XV{DuoY`;T8#l*f}- zud?jn!)}sC`eL24sBu4d=rFL)jfjM4)|@NhyiOS776{K*w1SlOW-E$lK&9xkB-Ch1 zMXQAt+q2Wq$}7;O6&1}mui37p8^4Bt{S4}&AIaYg)jX3 z?Nw|o2o(%=rIERCVEw>FY1&mk-<3KzSAVZ8$vO+D9#vU;*}AeJiMLg=ht^zt@tQ+M zAY{cvU3VLBT;v7@a$W@tQ@=hH4i70di|J8s*g90*yt#U)7aBh4Wejyci@FyO=~N|L zDbG<{G8YMRA@&_9aj*rICkfb(v5ADM3K=jpOjAD5)NBNYML;*~>_r|3Fz-ch)=eiR zi<$Cyu%q>z@W5G8a@w@(4+RzX$m-nC{+;A|_#bX1IJzRYX5}Zd`Hcq;ZY*RUH++(R z%4Ej70AlFOobpS)i;|NF zIoK@hD-A9%VCY?}1P?XHj+%w`G`*@mU_n2ubns|tSTN$S^3$<$J#dlUxenaPw~Bwi@QBRPdZnW{gf>={k*BK?vC?mcC~{b==U zx#Ef~Jr;IZ7dZf=?K{a)KE|35Y23kXGAYO4CBefsC&&x4h6s%G#gQ_q{FpKDr@K#iu*gv_5 zYGpU$?I0fE*z^uK!LdQ-MCz3#6aWJ?d;<8eGv1N@X-C!bn{Ve9!rPmN)BPiy*Yn}@ zZXe@U$F?t?t8YxFPx1f9*~k?sFVrh9zv$(=sVhd9V{(wspG_Y0S=4aLcW`pq`SJ8Z zy1tNhd_rf@2VVi2(F$%+qi7f)+D&hNL&t2IM6maBz6`K$>K>E|hHK0ABMsW7^UY|0 zacG#TvX2?Ws_Xx2(+r!hA7^Q*6GdFWSX#C}PbX-@=27^xE3ge(rhFkJLk0u<)W(f0 z^B5u2aOyf=bIzB8MLT+BH|a8R7UBpYJ*2T36 z`q|g2vhp)o{u!o-VIowAMSz-T08i@MWVyc;IA3Ov9+bwDEK5@`$trm!2Js-Pn#c~e zwe%VlT>TmAtMbR-VO#VNV+6lPm?T*yf0AC#whwi3nY@7cwg5~jfl=(^2y3pAA+F+3 zX(&T*6G?%5CX|8OA`=M$f}#>QiP;z;5X+%wplm;1S)X6&357f>**JaI-vO^X&`|o! z$aGPb*%xGTrvp@^@j7t(?IF)kJ)xNy{&n%i_4l8gl4ob-pUQHJV}Efh=3hW-KY%}_ z3zlIG^&I2$MiZ#vsw3@+SUs;gcgljm0GkyDFa#)-gYrZcBh9A_0LBPD8SINfz*UQ; zT33%p*A-h^qC*J$0^Q8v>$aA@RIT=t#89}FDzUj!r|RRUPNh$tWOMi+WF^uX%^t|F z%tl)y0oTka!rV@sipN@}`&&~3C&$Orr%rL->1piVwmHu35+IMQeO~8l1cNt)VqeF!8;*X(jUQLqpR;$E?WLL3oLL zJ`vBu?F$VK|7V=9J^Wzwy*ez)`ul=?P~0+b2j6(i3fEuswWQioEk4eh30qizpQ#rk zK-M_~4HS6TjKuK>0`wq0fh21gW>v8^2+teE$H0q9fmVdjL(GOF(Dval{rwkIzvu%3 zw7at>na~yOns>X>j~|dKD&xQ)kzlz(dI8t%DjC(8*>LbXp-L2BN%2W@cNwk~huKA@wel|6 ztsG_ZZ*YXk7jPA_1%xyU1~hxo8}2gA%GIoA#?&jvRQdY9o8#6kuT#UH8G>HiB4nsv zp&RD1B<>I&Nk9#uN=nVANfBRBDf%MpSC5@|j7gTEe&GF&5iD5$_T1cwxj8nE&wE#o zjlmaoK()p3i7}hKN3+A_`mr+mWT}3vGEic-)zA+lYiaJEMhv+h`X03L0LKCdu|>n( zEDvp4DQei(icYj5p}Ga_m8YzKl6CovZv2y`pV6UDfA`t%viVZB{n_t!Wd{uXpCw#1 znBJ2sJp0}DY~SJ;w($;8yaTYtEi(QGW)B`YaxfYQ9yt;U#N?p-CQ*Eo9JneR@E((oDj-GR>BQD)I>AZ0e18Ca z9b{)aq+%>Lc3`{^D@p~?K#ND@2z&UYThmnh4Z?~ivY5<)lp^-oFN1N~jfT&mA%FSYh{+NG96uU*{ITeN$U z(gTmCKO&c_P3KJ#`JsJi-5P06+;ld9(H z=;`W;$0c?|N;AROT$R{^4>GB`ss6n;>XZG_?YB$)tKWHqN%43#BY!|sHuh!;r72n6 zah;|llDVv+6+3eeEAr~DmT1Sgtc^RoDGJ{7QDkpqfG9$n3UERi0H1U4gHP|h*)%XeaQRf^#q8Ni_ zu|4zzUL28TvyCUxF{feRAW`s=k0R$J4$U37ZIS9OHS~3GuY9=`0a6(sGzYeDrgVa{ zMq;A%^26=sOFYu^W(0Rmrx*C8Gy>R*M*6IalZ)m+sG6XTL$J5kde|%H_<{vM^AH&{xuINE%?D^242>*d1 zHS@=I83ITC>xEB1d`BF3%V(QbBN1S8h zL@&Zoi9uBdDSC=ftTOerCQG?oDaS@km-)!` z)UdgaeF*#4fBgpHU;97)`i=F^S2kBFn`g59xm^D;Ij{klNQWQ?fWFZbARMNlz&gq+ zNJ9gh#?^OdAPv(DxWJ;B1{D@Kr32PiGtly(|3YnaLJbusg1ULCA_|iA(4|+r4VYTY z-vzkT*QLnH9ea1b0b#p}(&>*y4kGD*npkT2b4iTBrP9?UtE$|ks4BZvRXXuao2Rph zOKyMQ%BTx){?+s#Y+zTg3txX^mlkF*-&JwD9dyA{ss_GrQ_WI(6%h?axcO5H?oOj+x z@fbo8c%L?O#wh3>S%G=zW*Gu3c~nLNvRujf2lJUo&JBVo<`fuB9C<0Tvnyn~{;*4` z!WY}XDbHhj`rg6vE85t**kWoJ!9ElQB+y^G^q-oh7f!5v1D6Y^824o zWwT(Z7~h7T=z+eLh73lQ4beJ+CCWayE6`LQLILxR1@7>oVj$zgW%!$5vbX{#=Vqae z&h4mg;Zxg-{h9ii<8w1R*h0WH2QV8|Oz+q+j@duwu;ID-44a$7Ij1iq_>(C2r2_xr z7~WsROlpWAV)#zP0*{!7VZ1zLhh!0o68u)xGR0b^My4ctX+Y6F4O4uMrpnx>HD$ms z=oGY&InDt1sk`gn%H`P5Q2kqMD94TsDNe*ULTpttjg%O3NO_nd!5`*9w`q0A{7JE6 zW*Pyru9uZ}%$NU4R~pC#V)DQNz16Wv}(R z`d5&{!8Xq*8G2uaV-C;J?sLkFHGKlka|6+Br&%3(k{?k^QP|Zf$n!Q>O`VOmm%vqs zd;)OA2C4|zEtWk9(bI|ubhargF~$M^r^{wKbcJ)ce8?RFn?yXsHC_cZ15U*f(nbouTB$A9yiGiT1Q*TH?S zF4Ns|$OI)DbUSL3CG~;O7^fSERXP|3TxAaH%S2EH=ip*Rv>**4FAQ^Nai6Ovjq~h; z8VBt_uEVj~J``7Bd>+at<`a1~J}xKYYBHbyAh$L@&$n0dEx-|?`7{gzF&7HyGcgdEtfj5k_xQoHUP(cD$Sfz!$Vy1Q96JhB!i0vg6nc zvLlbm(t1V1#FO4Fi&Ki{8(rP;?(^fz0*~3w)spYe)0u1{F80aiZ215fEw=vWfh^k!X9>x!I#1UG!*ie6<{=LNZRENNJKtH z;0r>;J#1vyeYk~E1Bx|`qbrC)$7F**)k2t9z_Zz}SM+Lz?K0a^J-wlz;xc=phR<#3 zi4K`n4l{RmSTPaYlh^mxPs>t1B*`q*CMiMFj=;e8`PvY$-!a1OzYm^T9f5a>dV@?} zvCa2dk&8N#V7kF@Pfu%`5%aCjSh^DGbzfQkj?|veJuUH29*@iH*Yh5+YZ!t4IlnK{ z*B7zPkSxVIq|^6qRW$1c6)}eN@O!N==O5?v(WU==eH1RkOa@67G=#dscy*+DNGrqn z@ZZ!;@2CDz;I^FtmSP=4Pzjv3?Eki(o=4O@I>^P2A;#p`7DY2}ge0fDCdXHnCF_=z z5CjK1un)uDBoGRVBR~a7+~hWmK+uahRnVNkNYD}X0~OIRdybD(o8O!1D@80b zs7SF+Ne&f|)S2FIU?f|0HQ3`mT>q}zk(TgYtsthc{IR~ zat>zRWZ;Mc1x9DAN!DFd7p5;DE9~jp?_e`{2I2^ zGr(u7#8+wqRmd+A{N(@1fn|`QLwOf)V&NNDjYg5tHIPSx%c(iF2vtzkpsIV|mG4DB zvWI1hIc}g25C!4>0odnsOMmr8=O1Oa?A~*0XFE%PJeio-gvv0jC+JGas_1Xc02w&2 z$>U)gDTuLxC?Pl4i!V0X(NjJkYRocBs2n03LH4=__HCHB@WP3%sZh8N&L2(bv&Edx z6L1G5DQI{{GlLs83=YG!%qDZ5V6?Lgx--oXy!k9WF1p%fQxwe(H){j0M_-&lU!39* zd4vP61-&eDwLmy6w>g_ydrkvhy{PHuB0zmLpg&D7Oc^HWTrxNlOgc&r#8;sHLq5cF zC)hj^5Yy0|&ZN_48oO++l{`d(#N89GIATBlq3n^Lb%(vy_jTLSe`tHd|M`sk9Z^0bKf}KN zeo>s&RLNGcMS{*BIGUYRZAsN;VWA*90*cvd9kyOK+z_jOQATv&okNeLMa!j$*sAu-YwVv+i<-+4)3$0|^s2igcd**Z*}sQQ_EW5( zL0PHfLqPOumxJ!YUkYUhoC1aolrn6`;7bLS6f;fx)dAY7gUFcF2M!u>^YV_EonA}2 z;aXieU$%c@$x~mRde?`(Qf7nOvXMwO@)5peo85a%bIrG z=6}?LY-^`}Vc;iZU88on%&XK(dyPufAAeH3KS%&Qw0BTG?d zGwk6M&7>4~=5f*i2`x|2L`v0X*=&YF@iWdAT|#*yf({($bI_kotRYkZT`P#V8 zt_9331u|6gJo<)fTnJ&%B4C8_4S)PTw{3(^g>|$0Rku4!A7>ezFMga|Tqcz(67B8N#ID5Jg{-CS7Z| zJXKNfYuh(&RCQCnsh}ln&lduLaG>Jk9(jr<`7n~vgC1Z3!Uk)L%@tLLf$++-N_8W({raKvgzrdQ$pF|>ugiC)ad zL@~Lb8FRDPot;aoH+}o4`kZQhAk*8MAqos6lYtMI>V9CnbeNWoY?<1*lfvFPW`7#- z(a(XKP}bGUWDs!@Alu~8uQ{H+;vf#-`wzf(nyp9~1hEtZEn;&?atQoB*Z`deInILoewPSC9=-Sz8$CtOQ)ffJ#D3;1FCQ0$A7 zzbcZA*$l-m!iQ5G5mAL;la)0gIZ=psKddFJmki@+BVoK`W$IsfNpxu+*49?YyIgks zS>BI%BPf$VA(XLSdiq6C`K?n})yuB3dpf&{1o$cc5*FR$@U zS6lq+>Gq*FisB`*eBmK~OLh8hQa;@CdGGdW%6Fu3-j}Lw{|L_dQobes*#bCr1zwP= z(C_D%Y7B5FY&E1ksNtqXf{bE{plaAEH2<*h3kjbPoT8+{7PJtuUWj=h$*UFy^%in) zumjH&gG5i@7h$ZlvFFunwh!Eg9Bi9HK4GUYdkRJu+ib(J%I<>(d+%l&$-wdrD&q0# zwJ95V9pAT+qkSKOI$8SOhWUZM(eNOoFj|qLuXgf_H=3HV1y-VU58_u1ya2`{`{B~Q zx>%smPmIerS_J1Ru@kh9bTN?{jUXoMkSW(i26Ch0z&s-eltf>k zQ^DkG$XSI!fGk&#k3izXjg@R%kD+&~ybTB|!Ny z4*x~6E*7-F3`g%tIGunh;~c>|yOhvd{C05lyYFF>i}|>VDYZ9#@1A!*^Kc{E_p;&O zs-sI~{x*4GdMV>pZl>@e><6i?FE$c-_a^r*D+8VkuKahy*iZ~)!4;;rZM!lf8M@D*}A!ZdPR_!JCC))Rrl2txn?(Rq;& zE;uQg;kM0hcCtPCLrMN&v;*kIWS{syqdDwkiqRj66edw=PbS-w^%wXTTf@KR(pOoC zlRlW?aTJDeD2|=fRi?q8z{YVyvi;Y5`wZVY7?u-*ME>j!%#vGR=OImyfT0@fHVPbb zAR`<#)6|>W*8aYupJ0)T?MI4G1xF33Md2J14R+5N`Ms4{2*@Q z{40mA)QnU@bom2zK=-$Vy&a_hGQp!DVUh-gG7r?dow?Qa3yZxuUx!QGt0^N``RQUU z*%lOaDE~N=(#CM!%=>Ih8gQree8p&26$m78qarDr+Aajo@E6^w;^cO*;Iiy|)G&+~ z!iu|xye`Bht09AJ!rKa!5gujuDDtGRu!O%OxIJMi#glObcx9$inc@aD=lFo z)0@7a_t8R94<(d{BI`Tzt7K`rA~Rn>w{ly3IZt%oqP!&CLBlF}A^6-E<&pyn64*(J z05#&uWxiMybPEgtGEArs!IB%oht?$k`uDqzj%ZsC%g6k|us0Yq3W^y?b~WTn10Z~| z-2S@)tm$AlguE<&IO+FV;m%mD$bB}B%#1;ofPaCTB2JVUX)uu2oJO%nnxbR(lPD+> zbug}*?7aHskJF+-cYOW+H@?--_8&8}Q<{n{a<%5?~b{-V$zN>~HX$+JZgGX4=6Q9w^k0DmsP3m=ZC8qvHCZu&xT|BYAH ze;*6^G;_00iLm>C83ck+(H}yn5Bp{;QU96*Al}sEoC$y+7i~?aV`?~*So77WFJ#f( zzfr@!h!j^mo5=GY4+JgI?+f_-#1ED*Swfh`1)&2A$<&IObGT9feTqrZzu4C1WGD`D z6qz)2o*xnph1v1?@r4XKD>QAD^qz36B_dsW7&0>fw;WcmnCO?pA8Rqz=X%=okNDM7 zy31?3kZ60n6?$GB22Q~Bzf!{4P*}d^up}q;>Z;73A&5WJ;_<|=>nT$WtPJ2T8@Ugp zYkJ^M_!V@`Vk4@#1aP22l~z#Ya|6Wk%fiJt3j-ZN5F$r0*w%2tvNMtkL9Ks-nHo*! z%jHdF=56fMk0aeA8csn@d9YVX-_F=pQF4h}Mc85W=e?aPJ3CW|3|qIp{_oC#d>irt zkkAan$5X>@44x{I1=H}ke1iP~^D6^dDi&T|QAlNY%J}4pU`;&saf($-wl!nb>c4MB zs^!_}qs_Rq)xEu0AOuH`*^&CQ6qSZ(>K1yRB+TG_CorceCvPjH4>zrxU^?<`NKI?i z@oQAz2*7D5UcKUy9|P_xE*EHWHJnwWbXhnnXS=#Ha=Nd_l?)&|JrkM(4V-PvuJe*{3o+%oR$tgr5q<;=xM{ZS{k(p04C-D!F>c z1tr{#|0PduLwPkIQFInQVd&7G;`VogRGU?DywT-+(>v`f@gXi---En>U{H-PHSQ}} z31G)S__<~2-zgvk!qAcLfb~0cL(+^QVr2vDlOW6mSHPv&w*EULWLf%u=(e*s$H>wO zAbO76gUAVnt-EM*UVV5m4m7K|@cJsb)&{Yj+gHG$m~EKC4O{U28V z3BCAY-cS0v&yI+q=vnb z9jAFkVR`63XMG9c@qWx1A-_!FK)t92f&W7N7#1vo%6QR5c1Dmd zU8Z>VJ5ZQ(5tIeTW!^tjKNWQx#~9CnUK2cadOfXH*Npd}(I&D~8kHq-R6v?bUb=Iy zkr#ORwMd5UAirKPTyl(8RGxjYev-F=h@w9HN6%l$IQ8(G$PL%L!RwIh>?_V-MZ3j9 z4Z1#OEGo#_gP$H|9SM(K5qVIM6%eT!aj6s}2oAwyfl}iG$%9WG7x>ax#T+H;Rp3Pf zbrDVtm8M9h6HXwB71?~m#etW9{C?aSKfQQkxBcy@1diGzd<_AVG$0YDH^0j9<*2M!+$-}`-9!zsuoe;*4 zV-u1JS6sxn5tEH@;aVifUOa=R{|ZDIGJ)Y5>~`)m4C`iW1Ueo;|g zgb^4yLo@Qk3EG~)LK#-aODBkCPQ1j#FMa{xCA5lhbMBMhCI_iR(b$`5jZe@hLx z3%r77$vSp|22$fXSJP@h&pXxxx)+L3wNe`FcZ>`657~%#z;b)-DHieiBJx&E^AXG| zZPOH=y*Y|=hjbm$yR%qWL)&Rs1rLI_4gCU%uwb9AT`0QpxWgyz#TnFs{PxZG{2Y3D z1AGQogHLd+umx@ac!0QaxC$-<=!gAWr1q076M+;UHRm z&vcpjmt9}R>noIj8K7nMNJUK{{)ZMRfaVSWg%)VQ>MPi(6l(kfr4Fn_Aw~qw0SQ6M z6uz)aD~~`UL$AcsG)aldg7kGA^ zKkqc2ciOSTNN+xg=QVjN*9izhAx6)gf;m_)#E@Qg?i9E?kA5;D)6)xxi{kvA4roon zI`2KUfWY50n@_*|gwvLD`Z55&1h^M8Wx@*hST-9*BB%i^z_Ib%e?wQkjCOdKa{+xv z6Ej3fry!YpV+AdA0>k*|wayqI{GY}8j+@zI8A2;X-eNgXYUp~D| zj@-d*Gx<))g^BX!0*VzcnC0&fbN7CV%#}44x z6xi^ey-a6omTT&M;92}R&0~0|F+=!=Sny*0N%Q0^AK`O1d(S=O%GsM=hXE>v&|bKv_@cX{L?W&j>p?NL>Fo!jk$@=0yYsnj({cyGq0fY4 z!DJ#7TkmyyeXSXf$MX7u{++k(^aj|%m7BA}Skg?2*jR6}H{a8f?-dh<-?Y84N_uns z-gq>mX`yKR8*W$18#MHgD+bvf=}C_6-aQ)c0L#NVk~-$=@0QJ1(uH1i&N^vnOXCj> z4H=!UoX7VppU3m(9xR{K=<}r|W9suPjdaiFXf|N;+*erZE2cPg_oggPagXY?5V$`c73*q2A>P8?ce`x$Ks;Pu)qE* z@1#{yftGViwa*C^I_I6QY{|>t`Lb>x{`rcwdL3jrEAs?U>SPUzZ=$*6!g3rNSxPH; zg2d7#Y%m%<2M@<4DwLShsPb&pX1f~8+`jbTDMv-O5;GcLdz^=iPyT zo2A@=JCV4C740N8i>0LvSzYzQN)=Lj3`JASt4xhkL8tiG7J$)kq9N^=SeV?LBpV>D#xo>hCJQ9V>z1MiYv;W2)`+zRZ9Hf5@>f58?qyz@-cR$0 zfexO6hOq^^PHqZcJC5W!*A6I10j@pb4;X)*FHX7u<`Z`{XiZK*N*HG# zMZM(<)>xy3zP0Gmfo!Uzh@O$HyDT=|)3pJo#0zS*=@$*7_yH0-A1D~Qs2k3rygC7u zOKlq@#Pv^W+X#iY!C)m&qq$zOqfqfREY4{if}9PlcUkMKUbL=_&bAFrPJI;kq@)ZR z2HKki^5&qHf4q5nhicPEJ8iCGoPUg(`IzGbrLmKQ4Up|$fNXccHo~t*aTowvw*y~l z09(ouC0F=Z^dwiwN&p6rOCOwr{tg{#oSz$aNyjO-?PUE7e`a&th!|ouy6{Z0k}_ai zWOXiM4HYDlz;DUG9mwO)9o?cJs_FVn){6`y)`nkV2!!fG?8Hz0rv!U!M)Unxw&fqQ zs}(tce18PGh*-v=EgNQ_Kqf!_307b5X@B<#N&3X!p)uSqFZ2Pne;Brt2dkwxni!W^ zi;l(8V6IdtRUEP?D+WeK*+(kja3!0) zBr827%b)dS59Ctm_O9EyzwUNFC3fG|-8G6ebe6>zIlk#K@bp~MvLUr?nbV|~Gc_=; zS4p%;H_>6olo&^^4)V~V`<5#?Z(%s^*g5!`=Md4OFUz!`KJPyJ0{aQ(CPh4v#DYai z+%Xd38f?wkR%vzJWpeb`>vjU&c+9f4L1wM)Aj!1`E7o*WSMI!o3sC%Az{*MoQ$7fh zH4QGlwsReA_b6I!=gp6Exw*`zXyDze@iT;cu~T|`4PHE&JCKqfw;D7O9D^+RTGmxs zxC%g0jjtp^tA~I%a~f)h;%_ls^3(8wJgr=;$0tH7J40h3tUMMAMY>wYQmb~ijz=ul zf6#Z-bjR!#USuNFVvBKKq$@R%y2((!imHB1_U02~q0W_|iI5aCTPISxSEa@xtCGLL zS9G!^){){@$3rm^hdWoD6{zGqZ7?8s~sbDn#&@k5Oe1XSBam`(6tW^d1g0Pe@sKv>c zWxxNk-lHErdUVI;q4!#m-`{`frT1T|JUX;t$5EW^f3FpuyX1jOE_ncba?bNGOJD1W z#bu+*=dZ&!X{Hp|?;kAP^2u9o-LrMYLvRK>eCW`_2WKc1VVo+?e<}szpuAxUV{e`|$i8|EDxMZFM>n3U*YOgqR1NDjWXPYpbi_OsOD*!rW_vLpZ7x^6--{)sI}-%wmxZMSB zRZm)AsMd*t+cDyLt}v9CncTAd=BDD2ufPj_GVKG^gIsAt{eF(Ipw<2m14AoskS~C{ED8Om{0lOI;V2+|0z$X2JQtE( zthyA~i7VaSySGkt_xOyV4izgssr?gHU~q76II`^xKJU6uI%$s&Nwnlf%j+h$?)7aku7a;sRcpljl?pj>s*(x- z`sT_c@U#*|+JS~(Sdxb{!2Pa`-vr5_4Xq5q5|f~h2l0^mgKJ2m>_2*uRc@#$RVH`Uu0`tFy?cA-3Oj@}MMEjjs&uT-vBJiBRF-ab}o^bW@=I7o;lhS3!e zP&4!Q+`6~NR+(l_p&`&V`!rNSOR}w3AN}*2It#9#-BV%<_sm>ymma~-V37QCahqs5FF*#os1RAQN~be`}j;d8>5QB9h+v_2S^3ljKfnHtgx$gPMk zL^qRCKw=6tcj^y)fD1CR5HUOu2Bab27bJ*(kr+l)5~LFWrW#KP#F2(oG(~=pE212t z`ou!9QYu%=xRs8JH9Qk*;))2OE+IS%Z{zwTE#8D|Q^X3sVxBE@$a>iC4_h&-&FwKn z2;!J#dOdk7ZsI(CCZL0)bEm9EP|A#3d5_nWd^Uu;Xn5RhxQ}kvS>XM zWO2}Exe&}QwTR5^bKAa(B!!rm(cx|%LE4wZR$&t1HwjRdReiS0hv=vjex(TO>-w-x zJIbbYO-7s{`vL`S53h&$0O92|-JX2X7cr3Vp)06ex}N3hT#!VTe)%ScFet9mVy*9*at zmhG+bf?1^0swEnVu#9PvI@8iwR*MJ;90z8b0Ic<{1710NG!!}-mc0k=idg6MnJexNyFHggfT7uj zapR2!z5-I@5|2B4_X_sKTS9Vh#v6I_m}QNIGDkY%K>pq3GG=a0!eKREap@AZfmsW83wFTAD-nv2H&E z?dj6{+21HgO9p~=dmku3kY+S(KF&k=YM91++0wOtzsILjv#` zj6mUB^1!1S(4q1n1ZHYwtY#FcAYq|cK@oPQU%6}@gyy=-lzw98=N{Jo<1Nbe-ESG* z{&9Q{4{uk_th-co%Bh#~+s-|FOQY!GEf_0Wv;Qn|QsyCB+h}z*%J6BZz{ohj5J9~9 z{=d%7v^k0*jN|*y?q)Z;_z8UDr|={A#y6Dzp7|58K+0lYO!v%mKfmsoo#~$L=jn$wg?s^B z)4t%pN=;m%;i?9JmBiNe{AI7Rx3}zF%J2o*R5_Q)4(E!6+;BE?elL}1^10HIu98{U zwYdSy2L|wKQ{(CGj>GLsPg6;zfGbyDoa044oXMr<_OZ<@Ak$keQMa&|Yeu%VqC&;n zOe)7R|Fux&?F*$YQ@P?6rRMzE%?f_)V63jI%CIhjrY_}P{JS!FE-7Owb7_Dc4IA=} zrLL|L$Hl1b$m*22dRAlOs%mu=-6Up;>GV(--l~Q_S8CZCEBOO;dloe`k8D}r(m(@6 zv~SzbWf#o7;>yDKQ}yPWU%FQ}t+mIoLAC|FSMjXH^-mx5>{z!;K4;B(JN=8iQJFk% z6vy`pDCF+VX3qWM@)2}Be(Aa{JFKq5&8_P3W0I7ayoFfOcTDtyjqTVGJ_{V^F-=kO zg~fL3x(_Y7h{*NPSjUgM9XC4sg!xVq0U5PK2(0&k2RbuE}ao(6ORv zS$|*HQEExIPMH%Ug`8JxYiV2;c8;$Y>tD0BZ>(oyIb75_SZr%64sw0lEY|jL+$rRM zX=}7(tYh`vrLnHCwXiZDqM_lq$v4`+c3HV0U0z)p<(Xo?Ig{?;YQ)7sTKAcoOTX+F zVl7V7M=>*PMx)cb&kFRJlEl;Ov;3rZhEAmOif2Z+_x`^&-|_@f#t|nck2tE!{wVTvlu-bcU(w8-VJq6`s*Zkp zXbf1!Vzwk*=*Ci-<@d1HxSaii3i{B`F_~2~7`y{~A>dBj#a`xWRN33S2Q^r*X^`vE zA%;(bfe;afIYzmL53q43x*j9gfKiNL923}x`>+Z3V>2f40Jh*kY{fQg#|}J%hp`j8 z@CbHe5BB0wJch^d1fIk`dX+zbr%=a1OyLlwaTrH%6vx0%Q%;>7#|fOoDa_+(JcDQP z9G=GuTuI_3oW{#|1+U^YypA_;25;gmyp6Lo12~8Ccn9y|J$eCsA0OaDe1wm20iV#* z-KSio{xf`zFYqNUQtSINuHY+totvMTo~YGoCLI4Kw6*UjbQStZXeqsAX_<{I=_<{I=_<{I=_<{I= z_|&UTT9EYr$xhu*-xjw;g&Y! Y=6j1jlOpxo+1WVP?`OupGy5j|8*ns+>i_@% diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Black.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Black.ttf deleted file mode 100644 index be1a3108ed52e1be8fbbfb0cc7fe8b1fab40702b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117460 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 Wb!&dJP!hd(-HbItU%KkgSN{)weI*wF diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Bold.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Bold.ttf deleted file mode 100644 index f47161c6bd6b20f64d8db1253154de828977d744..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119096 zcmdqKd0eXUii)>_;8w!9XEsj0?v-akc@mxaRegogO*VWCMvEqdG9YTK{kI(V-HMMn> zUrj$v=*|Xw{#|{0+svDPsm>wv)?I{@H`LGUsurF*d>f&=41|OXw9U-UoB!plM+u?( zaDD&cRSSndS@8OP{C1HLzuzrexOUj(A_}xuiQoN~4Q*O#fBK$jgv7NI8v5?wl7$1x ze{~$g{lWOXU=UxZpY{7IKG)!L^5CjB8ra37MuETC;fJeZ&1|JMvXRRC`t} z92r*JOlITvL0oTGy>Qi%;zxr4e`YcvrH>4+S-Z~E9)Qow-bJ6w38MuKEOWenF|#kU z^j{=Mfp!Ub`|BHZ^4S&R+^+nE;w@b3PXzWY{&1h-J?Gy+#IyMQzm>n>Es4MJS49=S zrkczmYW@Yglk%%7`DZjBgb2?OKSG54!W?|pES_mE$)g5*8>Ch!lnOym;sa}g!OH)t zYN~6Aff&9KgbOYegM@|~2pwZT(u=|YoD9TYc#O33Z)V{2ZTvEebOs$BjvV?LNoBv|J1cD=nK+lxnPeKiOTkfxLysd0hX#iZM>>uy92q#+ zeP!%k_Fg{duSmLLFUb{3Twe(b(0>iF2%B*>;t0YqiqH1~1_sABBve>}@02*c!f^!0 z3H;u}&l$opoHNjNCW#jAAdNz%>q|uz;42_OLa^&gA)c6k$85kHk28ZKkA6;qas757 ziew9Aq>BEAB;#xrR3w>pp`9qSSAy>&iJeBd-V~DYUQen(pDLjgM<&0Xy*JZC`0ZJu zr8kgpp^%gU{$Pba+7L*H5I}>n=7TyQL=LFzmW8r=p(;QYzv2Y8epm?w-^*?e)I%cajh$2o`u(rnBr zHhzqT6V8fRq@Ir_qahntud`wau_y}gJ?0$ad+BU)f5tpybAiprDbJXre4fZ>#vg2q zuJO#~HJ@9Im)JPU^BZ%F&vWlH=qNlZ$tM|)2c-U_ap(LDo^s=Pjc~ZfQEpepSHg>r z$vTNg7=P50EV`X!kQZEkqD(FZVYOXI{4tIW9QEWr5=-uf%*rHN*g?iHuK6U4d`gnZ zr>-;XGrr%C<7FH_!0{rEVH`)u&%hJuxPAfFBH~(!;}IN7am>T90mphAkK(`@$j`Un zyb}kzCI-iIIIvc_zQ7@0cPHMn<3Swk{tZGeiQw{R2m0GVV(C1L<#M8FyIc|<=QG*Qvmd5iHFTR)f#zrp1cUV{9ZC^P=IKYyDn`Ig_o zPqmN@Mbg>s=53i*|F_Q*=ZrkZzU}Nihvm8KeGY@Z6NWYK49QdzAhY|cP$ao}L* zdg{ddV#i#Prg(?UP@V;UW?`&iNIOj?xi|_)zpD#tVk~(M<2k|)wst1t$itD!zY8W6 zSc6S$uHthnjusqzjpe_K@29?J9^_saDZs(jbA@zN;mp2gpP3%Tey_z5LVrgB*%~iA zNFs13h4)AX@U$vwadeOb=^Tgmaf&kNSj(YfEyuiBPSW_f3jOTIn(_+pjDoDey2o%7 z!pWmT3+}O!6uJjc+7a$3`3{aComd>^pW1TXWdj@*^C5 zQylCX`FpnZEW$DIyvpnQ5$SjD^J;vzlBB!-jPrx!X6$#^L0qd?Yxq-0N4&U)QoO-- zp!hDHC>1Ah{+MhhDl$m6(OlX{m(Xo=JH3V8O20=>($n-K`d1-Na0t_d4q>jaP&g?( zE<7bXC%h=UA^eYU4tumW!Jk z24lZ*Ny@z`kEcAD@_foqQ(j4VJvBUag;`_n{6@h3o9z$prTMgl4oaBbOCP0g(hun; zLbMO2j|oo-&k8RHuL$o6XB9-D0;Unb)TBstV_FYP+kk1e8`EIDL7%M8&==^d_4D*Y z`tABd`dc}s_X5)hL$o2@VBnbM8H#}Euwk8HtKp!8=?@Jj3_k{@Py1jxGiiR(VF}Z4 zU>f7bbO4w>mhwc(b15$Y)7MhNBut6RFj3$Eu}&$=FVop2p!vBnbl{Oo>_8c@tOWJJ!d-3*w5(C#GO8S`t8$ioqqlFtEXQ+ z{j<|sPpABG>mMuBw~AbiQT_k_pGpX1NMiD``Rn~h-L@IQ`|By*i+3uB61Eo=EGzyb zfCLikC3P}+uCMBell#y~$K`KcVsV37&4XGt{*bg+2M$$x@ zNeh`lT1gveCmp1d%!K8ri*&=5HHXY4^T>R%fb@`F(ntEqLSVIr>?Jor&W&MLaEyGP z9LK)mhvWz3N8|x=f;>nbA`g>C$s^<>`7wE%{Dhn$Pmrg`laS=klIO__u$Wv=2FMb! z9DA}6@;x$4R${lifvga=k$vPSR>HNy4Z?P^jBFIv3LAv=^cJlCLu3?v-%p+)JIG?P zTG&j>gss9lvWjdKipU~zBiT*vpkXvzun1PcCgck_LN0k4HmRS|e4#?<5z2&eVN4ho z9AuM_C)kBzvWpxbJIO(^pWH$Ylkbp2QeO_^?vm!_1o$X)nEFn{G~nu;Aq2{@~TY4+g)Ef1gZ?p4KvL*R)5b{VXIR zBtK+0x= z4}UQHy@-g2mWTrpk41c_5j1*DrDjO8T{EtENb|Pli^#0VIgz^}pNRZio2PBj?$bV` zeOvowlr^d|YB=hVs580uTyNZwxEJC+jE{(KiQgQ5U;O!m;Dqvo;e>}0&O_q2>o@Bk)c+wdFtIdo zDDm#ZmlMB$q;EB>FdQ+wVE7^_I;kmXL(<8lcd%ZS8jl&@H5Hmxo8CzdPQE^QJo$y> z^C`h8IVrPJ22(~;##2tFyq$6>H8RzZT9Z1MI-dGM>hDrNH3ynA%$?>H=6&Yl=9kUy zr;)VOw3f8dw1?7umoB6iq%TU}pZ-$%#SCLcd&Y*0ComlpQ)=Sxj?7HlA*+0zwASXJfI%jpxy*cmZM&!2Vj^sX= zdph^)yr{h5yajpN@{Z-bo#(XW*amFlwwG+5=EvrD=C8=VG5=Kl8GE3;z<#~`5&NeF zX$30^9xC|6k>==iyyW=0Ft2c1;Twe)iu6SVMJtNNi=HXESR7oOQ`}N~eesdvQ^ju= zpD+HhB(NmDB%`FTq^@LENq@$Nr|&Gs`hMxf zvWT*@vbwT)WkY4#%Z`?vDtn{s{j#siBg!+%>&oYqFD>6w{#g0x3ROi`#c0Lt6+f#u zQyEy9QCU~HpmKZVy_KgbPgg}$In4vj$D7}8No^Twd8Xxy8KpC>pK)r& zC#_knL#k+xZFx3-;bC+!983);uqf7T&%WONL49O!tZkR`9IKS;MpLpLMz`va6wMU)Rgs!QJiMhr3^&t(sjvd-LqaW`8lKV9t$m zUY{F0w`uN%xyR?eJ&(-Gn>R4;_Ia<)7v`7F-!}iH`Cl){ThP5=*MdhDoaqVfsqWd( za|-`n>UpE*y`J;Eq&L2|uy?TcNbjq?AN2Y6#rL)J-P?Dv@72CP^nKd*b$?{PwZEx< zUH^Uk&n+YivliAYT(EHS!tsSaT=@FJFBe5FDqS?R=*C5_Ec$G5;9}$AhQ+rperF(Z zpnPD%z#{_}mgtwXELpeY_>w;?4O_Zs>7k|1Ed6X*-m+cGP7k&ZzOX!YdCu~N<^9V? zmfyepXUl)L{IeBgMaT-nit-iPRy?%g!=EAL+U$jVn%{%+-k zm6wJxhFXROhQ^0p8ah36aaHQ7d8-brdTVv*>IJJ0t-f#dORG<>zO*J|P4}AX*W9}1 zu{H0l`Fc2cxOI5j@X6s1uS>gb=(@YF``z{N*LPmO|N58LlC`C4Z(RGuz0l zdcAf1hV_rF|9C^jhT#p5ZTNa)>BfdI%-Np)lLj3Uz)#UX(UcWlY_y^&9uo z-ehaB;r~Z8Z})EJTX&?{?P+Ga9rw1-Mf6SK5!@R@h$frbLMZ^j>*@sDmvE0>iC4Pl z7rS@=f*rg+Bh;$TU}uPfmP2d~lU+P)YMTRx*2E8!!=%>WhwiARu8_9*+F6lKE(;laws&>!5AcW6v(G+DW3WME8k^a5D}7h^3v?zz)u|?vQ2I^y3e`F&85h2~-@ZW|byVS5EEuCZh`InpGxaDnpLF*!Uo-qjUuhn@SyZUqNPC zW_w{)nKnJc5@V$Io7!j3UAJ^?MPb^)_Qu%_l?5~Mb$e18s-H};##YvwX_zr9+N!su zITvgU%d1}5R?(H*T-va>y{4!uv!ZbN+|7%Opf`AcoZ&nmaez4X;;7^I2Gf1bDrhnmV@iUr0WX8Fj8UaoE0k;?Amqk8T!sM zslRu||DIo$N_*({g;$|P6OGwncIX^7okOSAsmQB;5@JZI8OV{$&*7TPxd}F_!R!L>#VMFDDV$MOD8%r zs4Egxq-Tr1pu|5V-)_#e_x!9?Q)#xOrerr(&)kUnGRbQ+iRNOo(7sKZ`NeC4a1m2d z=K7rc9qk3+d-vQb6K7SsJe_deG*>?@fc*{k>ohjSwAcDyyH~OF5?tK^Nx?k*E9_+f z7=NPVqs+!vomY^bYE)?>>G0cIHovp^T!z&;%NqRfcaJ^rz_IU^Ec|T2f=z#5Fx27Y z574-QJMa!S*})azHf`PhjdN>jfw$Ey49%x9i=2f-j=dPLGaQ6~_rpTkcD8T+F zw3kF+4h7#9uomr@9lTwUQPo;K#XL0`qiU)fvkMy+-JYJ}sBG$8F|ct(QSH8g!>v7) zX(p>>uq!F0a9+oP&VGwByse~b0JPDdlP`grn$bpMv*$ZZDzzU*)?`nzYi!~7?olbj zlBu%sCg8xp&hZJxX2=J8c)7UkO(RP3VvJx3G! ziaurW!v6Kg?zx{?mMC^8gnkIv5zk;Nr;a3hk~T!4{%%0y9OpUujAMFAsNeU`Z5o|d zy>`zH%fMY3faznv6pWpxMUo`|%qo~w4n8)Fp`z6J4!c{9sI_cG0G#(1rKe_xSrgN9 z_nOm_6VnRb8tS@k-s}}KS8pBY-}-oZPI_vjJ|QH+ve%N6Vo5b6TmHPLSXtSPC8=$e zLs`0_WdK`Cffxb9hcaC>5M_{H+DL^%4=!_rfH>~1(d(t6)bLJ|Wov7gM3t^VQ02gF zL#t_b#V!!W`N<@*pbtLp=sz%Lz#$s<%nNtFljfi}6Y01#6`kkYb5amx0dFIg5Xf-| zRyOYx6Xn8le2x6Rmvo?ob~A72@~Nn@7& zcvEq7XC{UybRG@hs5-@FNlvs_J6cxEU6q)b9;>)BkD;3P zQFd2;S+qXM+BCnr%UG6eElF~#2B3YeYnGy0xCb_hGA8wiC_6B$W|L=hb!^dBNdkd0 z9R^>A0k;Y%k+!@F%D5tzs-FMePY=w=s_+-IHHoDS8)oH43nBBZ+UeO1d-v~s^G91- zn+$VTw(MO|PAl>a#^}(*jDk1cq>5LLZ68ZFC8TuJ_T8SBak_g++xnxwK7Q~Hb9+wq z{9F5`TlOX_057_}!pn5n5B!rFET~H+KpLj%T-rC}VHvTS#}e*E;9S?c`%>!J40qH6OYjxYw4aV+swM zni7>#EvI&_p4m}QSht|Nq2Aunxpns=wECW>yXNO!-@o{};<^1yK0r^yOABCAGaZjX z78Ry4nHeytfaa;Y9zHQ{iGR9(ZoF{dUgtAE-1yF#9^OChqkqSJY|RKy(kAiMGD+J) z?{t3i{`)jkI54_%%k50aLl3~q$G8?e?YXvv-tGMI>{(oQ$LM8ThU*wkHNXk8X%bFs zO%CVWVR`DN4P6}t)h+!!^Rr@x{%&4Zx&JW>oL2EZOeqcL?_ci*4DkW@}6ewYFtk@n7Hj`6tJZf#}YE(IDp~=Lppd z09uhwfC-u-?;q40rxY+;l-5c%RuAKM9sgZ}8G;4O#Fn&BYJ!#@l|WnWUS(FASKPf{ zqqHw68OT>^(9IvOzn-RCUiWv~i90S|zT<@L?_ys28)$-}UIPd~-9bPl9 zW2CgSLpboxs^R~kor8IqjK%`is#f7{z!AW-5=~?j?;gr7lM<XF>qr#J+>; zIQD#VYBuHYc_yx&>hwY)6_-+DS8M0|jG**cMa{bgM!TD8YEmt6aYjMmC(PWjd-y=- zlA4O7C{=i}ZfAub|rS_rs>8uPby!GXp2DH;ewaM;05(02gx8>i^kj|*X= zqn8=Wm8&Vs`3a>9Yw8QD#30QlbV?Ax{3+O86@#9DCbFd3`Zv*`{?K!h?Rx^8Rzv{+?enC0NQrz=B)lv=-XwE3%={q69W zIe%4sVCEK@3;s-NY~2>)e2?P=xg=zw4{)eWqp;~1a0L~V%|bJ4K9mNXdhiE@0ZA%l zba?(f51hKMGCD@7jV_~Yv}{XwQ^@qxEzakhPwmbwEwJzQ;2ViHvA?j{(Ix=Ls)9DP z&%Jz4NrXumnBrf2^yeSb`)2-^P48&rPfRLiTCHx2>L$u^?)ai+B8gbgwnjbHr%zz zYEfFO`1OEu-S)kEw*#JF*E;&K>laKW>LBKW>1k(j(M++O?Ls+SCcMjj)0l0#OQVP8 z3gx#m+qpopAv6D*UJ_S4>};44r#54u(uQO5unFqGD(g_qWXsZLln?I^#TVtLSdd&X|q)hjy#LuTjGDSdFntKuT*p`Zv~Owuu+j z=&CVgS>3$lqg{0+%3y;jE8W(el`cI0P>bWH>$lumnSa30*tiD@E~9xeV0{6wVl4%v zo+*jOxWG}QAp z8Ej_(TLhcUyiG_5b&?x2hmGy;lMnPRU8QpVUbEU>klWe2>d?W*XC~XfTz7caiqz<# zq`8F$PAr6F0Jx$Rx=wfv<09HX5-4Lb{Iff_U4X8Oi`Ny+ojX=tJ*O{McycJPUcVL+ zVCyQsxbEc)PX+XIi=YNf)8Jz&2VXFygY6A6snM*GwgwKnEZ@++DAdeQPf93LeK7hF zlCaiB-c@4Dtx7T5tkH3s>aB$dsT;eql77+_wyHZJF`~Ks`8&4ttbM*THMKOgJWg+l zjS5#q=ai-?^0M!GqT!Ajxl!oXlmu=|s_ z1soX8wwEe(c-5G?WyaC51Ve0EESO_%&8yBgFhSF!Vx2!`_Y3f$5%MSD9q4~p$+@it zDpI5ZBJ$CuoSc-@>|QD#j>M$P5B=|v}$M8Wl@tCXC@J;991n8o3dCL^~m70AY( z>aic^n__ig3A#0Cr74Hfe>gS22pLkR3In_`H|%=AF6$6bh#|ey+NxWW_uTu)v)>)A z5T19g{`niu(?6}>%y0#-MBsYJJ_qYnV&AH<*g*e?xa_@01=HowFosw; zK^MqIusz#y%EVDiL;{V#r!7s3%;pBmU7%D-4tvR_7b{z4re#X>%5nafkqsv|%{kAy z+m@SUG)H@F?Gn-H#fs)hGzZUf{^EPH0&cBhJQKnBjE!9Kp@GGR4lN!Cuv)URv$HHa zE*v~~;UKNs)!e+RSsb@2SA!4*7`U8p=$IhoNJ^|Iax6sBul(3NtZAG#INDW_$K^z3 zMq1l-SD4?;Matl{W2&MWpZQ&u zdwI?sEe_B8=KP6R4+f`5D>eqAE-z9lwmB_X7o8B3SQkSpQU~}22~pLMsHxzcaP+$xUROwDW-G%A z$hCi&-@0mA!Z&Z+SgDQG73ZHg_1Y@cu3c+?(H6Ke0{52U-Y@AzHXk{UvVmZ4L?Kx^ zmXH)@jvB*CP&4P~b2Q)ir~Hf8z+AXUCWA@yNp{_U=RbcPg%1Q&;O0`6eg z884$vtVuf1sDgSS%eF!0mN->al={W-`k;7aRB-9Rhf?}yr6e_|s$%K6-41sHvza4NM+P)MwIenpwI$ zxwW!2Aw71b-eC_=2G|{mD`L|VS}Q<4^xKUrk|z+K$aD;_LU;eyijOaWnCv&E&lEwQ zVK9lS48V~V7rx}!Me9LilujE0R%Z}qQtL!eWDuJG#EL`-2>nV1L}hF8@=^|_K5;O) zO@b+bT%`Y`_px1xhN&&w_QcH(ApY`}=`&3g`BCO1`3)6HmZhc^vlj+8^PO~31?DFA zoy1X{$)RyDw+W!ni~57N?}P?8-`c&K=6Nh6?EX^M@99UvEr=3zlTF<+5F23wzYL^P&~b ziz-gj91!*&u&{+qw}>Lwt$FkzZ^r)a7TMac6NN${D{Cxkp_`uCiI~SXln56z#fm*nN=RtWM+Ac z6f@1MjOGHi>wu}cr?JeKRN7dZQ;?rmi}%K|#=7jG?9kk%+}x&_P36|A3Tt^&T}(_} zQ@N$GJh!~5K05mJoPvTm1spHP20;m1XFSHtGYi4%CN7^$+^!FmIQR~mAwsE63d|cH z+kEus(Xl)4ymPa#W%r!S@Oja@oqw!z)Qyedg^h!UH=&WU9g-Tds=FV5w2(gGY#MSF zqi<$|e+V}C$FMgj#C4H+L5B%sRhU&NlBY=lbj8Jo`I=x~5nW9p#lL4tZ;3Q&%qhhY zCYmtakylXI-d5PDTQa|BFsUnd#9UlkY|czc=$pBac0{FUje*+Kh=k~fm;l}71vzGo z(U>(OZ)Tn;qi#-Sdb2GvA~DKjuFFcP(HV1VXEFFz2_^JJ>={IRC-XTmJw}!1wpu=> zH=Ff|X7ew~&E|5mP?A<^HkYQQ=@Zh@5}+h7z0czMKf+7kNoETJn-_$M+iQa$jh|vl z<=OHQjePM%=cl8$pSk_^Gqu;ZHI_IG$yQrlMoMN*b#>R!qcrQ(soU>(lK$eeBS${F z&H0b6l_h1yQmd`hSd+gJuqTj9v{LATEX2q^zi7oIhTqv>_vf@`r6E& zQhw4sxo3}K&6+)X_ZF;KQ+RmraMqC{S>g#YiTjG^HfE=R)fMYMY_3BzYS4M+Db9ye z`+AhbKppg9;g=YLaOhp2pvFB8siLnYQYVTtwsM%Xcn>DZq#w;%yLQ&hwQI+=x3z6= zub7)`F{PL46SN^=dM$OVePk{E=g!(cYu5hwpBoJ+;WJ802f~7}KLV@=gm!wb@G#$_ zLGT}-kwSY9GvNV$pS|C6n#Q!Dm~OW+Sxf8 zoStMzPd6l`^EQ~zR`i>}g5d2rW436~d*(b(-#E5!@c#P;_Z@@Ni(=FH6m3;Bv9(RZ zWe>XJdqd2R5DG7^WzI}}oGH1ibZ&KPQnG0SeX6)&jxoWIUD#e%uCKP3=W*QP=tHyv z?ZA7Yk#~M>*AY{sn1~VQTwIkYC)&`{7OOKD%95%rh3!T4bIVuIZ)`a+QMU3Njm}(P zGL+^PCB;|UYXIZR*xQ~E_qJ4Ra?lf_E9VODvdt~ivkTp8Gt;xNK6~jfW}UVQDso&J zQ)85=_37GxSB0m%6q&}TdD}($yG{zQt72>*x%|+Qg7bC>4W~Da{d4%%o7ZNw3#Tt9 zQ|;!}85654o+b zz%4n{5N6DoetAz{-=4nXMMZ^|dRyCid)r!r=gptbh6?u=` z>MZB?y6Dz+KV{lW#eJs^?x89gJw3n}e0jkG>FZ~7)Xkn<@YP=cmx8x%lG;xKO~uB; znP*-xC2#I!Jp{oy-__&Ir6$vQsT1dB=LNXv2YpyJD~;1ZNuq&II{GspelvsZE;X|A zR4r-h;!Y7Hl~{R7M3-Xy5XzI=jkXW>-_k!^P(QJ4;hVCNkus-d0=VwB z>%q@lGom)`*MJN(aiL|)o7~IhX8#iCs=*0?&FYeLeQR+1(TV*j>Z|K4795v9pV%c) zO87MJxhwYSUVAdA7?U!&*R7IH@Cw%n(kAvOJeLLyLHh5^n9!@-=T^*It+?J%$wS3f zm?*dWnA~q{xK0-yq0=QTEh`_Wcw%C|in?fow&)@?(Fg68tb&3pi_3Pl4jWSH?ggo*f!AM(Kicl#j0 z_>ftug#qwk5cAwQB;P9IKKOp&ZiVv~i`SRj%ermb_|tbibYlFcO-;#TBp&2}P&Fx|kC$)PXQhbVb|7%ja*s@#+ zUTM%LwH+i1a^)2518&CZZrJNNO<-caQXi9sVN!29#3Ar6X3`vD-M?gtep}q5!Rn=m zL{PH_CFI33$lA95Rd;C=+;??c`Z(9S^MA z)OhGn<1M%F*WspH4mTaf|67_4b6S~QzeldcPoTSnavzw2Da!VIKaIG(pptHGR&&z; zHw)1Be{ag1-s=48X_LLWjsB{o;P{^2y0RIy70351Yph0e!N20xEy_5ADYIswoi6R0 zdBd?Mvs;S0=fP`hXQ2_8BiyG6z76F*Tdtv_Uv^d*QW?8?Je%)ryt{ppcT>m(JAGR_ zOe65LLw^8aGr6G$xQz9{gZa;F2;N>+jl_U!F~7d!k!jJmkXpWH*X*RV5MavyIbXc@viD861#CT4v+pL0P3AMd9mdO^!} zG*-rCpeRYTHp$bEO)j_NwU5oCMeoY46&PD!Ta&h~;Z>W~EgUkNW6f4`?84biGiCJ6COCX=>a|s zZ_l2Jan=>QnKh%g%$dTYNmpP)`S0}sl3$^Ze`1F^MIQp0)CaTsT?G#X*K|$lEA&&= zzrKI5U0Es9-cv|hGa!Hk2(Ls0-5|HKU;eJFtQU#RN_T z!^-N~tgPx<3v=!&rSTKtNI`bo)gkeoIowjKjl2RZex8YhDKixu%O+URWLPe8ntUrP z9@`MYYPdlrGU^Jj^xDeHZF%M8d6L>Z6*TRI3kvby5t|W<{~(RXcf#MW-}8qDDHoJs z4jcrgsIn=O#W*|%g#tNX*GKmRy8;8gPQHBW0pB_(^_u&;|g&)?*wWQXiq>E*5mV<@=K|19P;^Q$wf zq9j%(dDb16)Kh!cOSc@FJHf+#j@gHbZI&kS z)a}>w@i{y(LICjd>5F+I_VWs-kC92}7BkT>k<` zoaQz-Fa5u2Y%$_Yn5*3#Yr+g;iQd;S!d8tnZ&^8qU&qaMSj#Trx@3Nxtp7_ysv0}r zzrGJb%`UeKGALYUalMVl*-VpS?!uv3Npiu1Y}J_e9)Pz{G8rALfh@M#DV&E*4z^z& z?`;+}A;f%(W=hHblFC&g7=m;T8kJ?E=3)z6aLSRr+gJ7P-PAeV99wcIb)CskIiu{B zl`YNs(9F`}qDmpN?50e|}l(`iC`Kf^@wX^*zK=cpS#c-W?b&pm}Ew7FVZ0Dam8oQ!AKyg|F7pC#oA z?M@=~#CV2H-U}V4wohNrxJk|Dsk^@f7GXFgCR40y6Z>>XdjU~1^y%-32`d>J4^1XEmjA-&^%39? za_J8 zp3$_Fr&0gnhNT-1rr9%!>y~XiXl8yw=37M!0(dimMF+Crg9#RVrpWn5BD@N=oDhv5 zG=Y)6y)Cv)@NJ83*fKP!F}TJ6nooOJq^E*S5?Q`&)=T1R3K%7QOvIVZ|9B>Srf3-s zph=?5x0id$&CqpVvcc=bp6Vw_JVA_M0G+igTWIPi21cH#BN^ywOx;Q042lDsP%I7* z@jY^^9S`sEjs%pwK}PkvV`Ivq={>7PyDIHUDZI!09mV>G>T+3lPxf+md=I=ZEan1p zR|`!a-mR%2o{CIUV{n@nxh5eZ{Bt6~WSg@Evw}yCQJ5+xWgO7^oqukaWDvFV^jtnW z!2~MrD;~aXpgBjUC{YEwalH`_3aC!2L=wufw~sPStL zvRKznLZM)!ve4>OO+W&3LdJu|EXHx(y~^GNqr*E#TH_Vaxp!B+(5cSL3Fs82LTg2P zNpW!rpNp=qTuH(l>{Q(OR5WWz(CbtdKNY zRJg{S8dB3_%FD{AjSw?Llm&(eI6>Il&vscU)5ldTqDu;oMY@gGhEwWEj7nu7h#Syn zS;XuCPav%&GbTJDLZ4o0EzOLb#)E31e9zW2x6P4*YNut#Xf(mqNjaJ3vT%Dv7wezd zm$I?f=ks+^1_qC+XY+Nc%#vTiE;k{)M7Wh%QCPc7mwZ8%16+@sl&!+rog&JXj*qUK z;~Q!#baA=sfi(dZkSPNXWXsAF@O~zl`X+)LE7|$HVMhB?!>o~2Y~QU1iw+)ODnfzM z?h877QP!_zTF(ZpuL!@qrcMDrZ56{teG__w7{0)I(fl`DmR$*cw^lF(<(($0)s$?t zPQc(9-UHavmtU@k1GTB)-P75o!eOCo=bC^8_@>MY2ey7(c??+N@NZ9n!OPrAvABN% z1}{QS<7=&$m(>D(XZA@kr^YAyNh87TodtE91hXd_iYB>j!-)SDb|?fMb1K@3u#KKF z0z3soQBNHPP9LaH^$C-L!9RMxmeb^a)0e>Dt;8A{z~Zw~?BZU;mZ#Ao_*WDx5HTDD zF(H~RXL0KDa=xtD5}+(@=vmF<*l)XS?9L|*)#bYcb(P=c-((f;Ucct%{FbcxrY6jN z(Klp)-5Bv9KK>=FI391%_i3E$R(cx?i@b+^nD0NYwm)Zz=G42*d>T1nlld*ts3m<7tzP{%*h@5s~#(n&g)a2f3s&)~(2K~TVQPXs_eDqt)Y>3f3Gz-v z1;wmZW{c)|GswLW>DBlj)5}ZQy>^oAVqzvBCr{le{JT^WRb!dQW`8S>xfPfxGj^AH zt1v$Fign8>nP$I{Xa-}}f5>AVv--7@tXk5A{!MyC`|3(@f|%RP;yx$ptDbr3$D_b_ zsGfOhR*R{2u)vbcDdy&zNdL%TA${?&L2iCKEzz#&Kc}4-d#+=l;nz;RrPYqbt$_F6 zq#jWLmwe!o5F042d%`TpH8~Q)oyje0`C>+Qp<4jUncXZ(gv(%o*>eS=Sc-KIS`=)c z++yHu1C?B{-dSNc%7GyhvcrT6BO|3~4zXdvqgdw@OoK!@7;TD}PA8?*@r-jVefKPV zu3_x#SOa^Z-|6bQyWSbg^3LgpRjNMxVU3`!%M3o~V}MS>(i*)$6BG1!p3S?Sl(n&% znz08SpqE+R+8H{H=dJx*$g1*dZmNg9`%^SpiC7T@G-!q|i!YrR9WoxIpD|6031M$o zco~m@@x*}$uJdRohugvBb|zUctHv(EFq|+0hT&$Iit#2oh+D!drq@W`I01Slp(X{h zZ^-t1rUQ=up2qSnnc{~(fxRG1nZ+!7T~{^sE{)_(y5pCp;krcd1dGq%_(d=wo#(K% zjOQ|WJTC~rPCTB6$zNW1mTDn?6+D9%^nlJJTMMej{5^tE^a4nh01CT(67|Cvi#deh zV1Jl5Mbfa58W@(1i? z&5!4rk#~^?q!6i9HOBBnJE(6Ugn*9I7@tU0c$ifb3Y0v%Je3aqN7?~-RXh-0XH$&l zJ|%WDuAU%fvx(BtQ%RwoOPHBi z2xjuCsF2|nhB3k7I8>osF`rUySI(&PZr77tX_F+aSC*xxQAk*@ANQ;1K~r?WBnngA z#2n2r#nF2oeDb@)CG_H}uOdbB`G)mu%-DX2#kBdc*}!l^G8VIeqS6BkAp!qf92KJ` zc&;eNk|8qJAducqq!nc1=*QRzOf0^Ct?p4UaE?MmBGt5^%aI}QG?3ZBO-OG#A zi2WH`?e^9Jj_>F6=Nw}p^vxXd6 z^@o%?hZ-Bl9(iPR^eyxCX4>Ms)OS6EzF1o%5&fc9s&;Q*$|%2A>!68MEO|G2 ziaN+7`bzshA9z!wZQlfV;Q*IxSpw=f6NOHA8j=FG9Aqro+3uH{Z{S&Wu=H*(!XO!X znPHwnm6VlfwB(*wv~?gII|(`PVfl|`U(8KC6MV5fG}6aa`AboUkl_?#SCg&? zCw2p}0x${OYROd*)E+Vg*v;@(Sh;;$_W8cXVMpBQR32CaNyr^dbiA(F)qo9IE^|ou zpz^e&f5>s4avbi}BU@4FQ#}cl_{A050xGu7oeGZ;{E6`%ZhyFrMR8As1w7)s7Ux71 zI%?PVchs)y^MU`VJMhQl6AQS>gIwfRR%8v@q~Lokgrre{nh@bgH?ur>gg*4;uYXMi zXZ5Z6pGHUb4BStvkMkIJ+V~DV#*{-&YefX+yc!Xu@X?_r0MDF*o8*ciODQ~7>1j)Q zc6R&E_AVYMtLW`prgEO;fl9W{-oC1erHgmb*I0}aExNI#<;IqS8xPK&?T%5JJ^R3q zcz6=}$NDXFN;)Ug_^}czw3Dj>(cf>}&@tbqG!T=p&a=Mdfw(+CW%GBj%E1Z5)=LeGQ}lCq_K`Atab9JMs5)Mhft?J-@iDP{ zQGbDF*%o#(P@NZ?--xx0AiGS^3B+0ju*gn=)myz_(#s3x)#!_FS-mP4c!Vu9DGyzl zEgsy*a)Ov0OorVHbT!?|L-p;~UG||bHhN`c6A8@u4|+2F4yUoG_p!1)9vUmWB(4|C z(S3{Hz**eyU3I}NaCwbFApm?}_Nu<{ZB?BZvwT}+Ct8NZ`P<4nDXMu~F|YpsyfRr_ zqf}YyDit7D_t#Pdg4Th>uB8-&@C)!^PAWOVVEe!1DajoFZ9Mgkq@;ZtPqAr+eeJ)^Q<6Zr z7M|K5X?EAhQ%v1MO%w1`1Y|u{j3kqHkSwzjvC3k7aS=Snw>Z_r>b+%p2#&|Ej*hai z569TE8ZK643buefP9qdN^-bR zi(K>u^D1-^(##gC(TT1Sf!CH9#=cL(T9~T33|kr0z9nWT#V(L~7nc#t~1sA4PIKTJjj8A;6G#NkKn713^hk)L98u+;L+ zgD>0zHS7D@YuEQp1i6v#9$0^G@^#o6{L#kKV+G9#~`;jaE;tTSgof%=- zQIdJKq!fjlm@F)HS%qM1Z?SXsf!p1KY^UWx5iJ_m%WCQLMDr2$ed>(u1okIrsGNE#&oPz6XWb|e9C^Pms(2ffl9d@=Az4aR;7%=ZoW zA%NQ{-IYO^J=o-_4qAcGI=MoqXr*Jk1ldGSVLYXK<*HunUa7KII<$DXx|dkFgxx3h zIh)%mysDAHGsJe#s0ifM^Vt+u;V>sh?p<;vAo@%0|2J|w?*85FNKm{e`A*%CpjaXc z|MtMb@Mkt^5B`#t;04J8lCB^_B5DgBI2avx8*Vrx9ZZ7aD=8Mt4TWSm6I_?!`(Saz zJO)amWeXpxW@7d!E9&iilS+wtRTo_=df}!&X{f0gJ=o&dxq8FF%6!=k2U^vkkNwyK zsMwlFc|uhIWktnUt!-wdL;bBJc;@Ioou8;13kzDDA5_lSx8vU9J8!&)3iRRdL(SB` zv9*<&mUNtQzVgK5cdNr9RX^ggOYgcDarj4=9>;ZfJZ42}f^6hzk*Mg1$G)I2ii2q$ z^g?{nv?_n~vbDP4nZ0E(k>PR4hJf(qrfGh`J&UZup4CCEj+M_Z9S&Wk7KFlCw=Pj- zuIUH-%;tAU5eC}=ixXo60rhN?U63Ok~)kw0*Rc1bm#zaB_fG57c$RD#~qQmIc^ zD_4FNuFEo6=IIxF|JakPDs-YcE-n)Nu-pkfp8v+{Iinvb>&>SZ(avMfM_vr8{AjhF z8c0~!gj$e?4h`gFJ656qB>vNnSO@V9BO6&^NKJ4y1dmwj_?L=gJ_-zS6r*Gr!8|iq z)CyT4G@)@oUsK4+9<%z#btx9%%PgbSULNFp50#I<=c$A&#F)@5Uq3zBWoTP@chk!>P!B(hwE zo-X3jvS9dc6QioRO=MEV6t-S_=e0s6Ad<=}%y@EMD@-w0%E~nHNY};vQ$|xu2I{G5 zFG#bzWnAN4$;4U>%uYT&i?YyMi_*kyF-YM85oyMB0hkSd%o4N=ZL{nD03f*ec|!l_9?#n+3VfAw-0@ zKx!jB;A1QD+X9oRz<3{jos7gEYil1e#l@OTv8Vx-&rYyUbNyIRBKvf-h#qRq=hQ9j&Ju|nhUF3!L#IgO`nl(T4LfZ%D7)X5N z!A~4x5E`x}mLBXLUu?>`c=C+%vtBqazaqzG`y&2#7FFYmJKGNdhAGCIXyJ?hRmR@aJ?owGfbZD9GqZOs4dRIZg}+W1e8qw_Yn*@e9(|@$vGx9% zVo0SipE^!$L{j3Xh*J~BBsnF=_x=6`$%Sn=P{ zNhfYtsX^ACxUOX7HL_z_KCj#-&)8R~y#tg`n-dBM)1+Q>%-zIRrCF`hS%*A3NGTQ2 z-dL6sw0{+prH#GoQ}hloGl-t{s;6y)e@T3Xg~zUbC9Adk6boMxMSPQ23B(&jz{)Tg|GP&6l&KUF3WX>;fV@-JXjvu z2RvQ`dX^*K!S-AThZ1KE<|j|NOIFeJutj!9Zg>BZo%b*R|t)b=lP(2(rM47H_Y(*ZZ)52=#QL;N5jp|Aq+ zs8v+G#V*XK)@BTkubI8hdDm=w4Z#zV{9fx*m#B0_(ag~`(lM8jKe>{%cysohr*r( zu(QM#6;)JM3&{oj1&YE&g$%A~xbBd2oz@s>)2gthA1W%Utf~?&dR?~#wP{bn_JinH zsDDrbOzJICO#;d4Mv3<|lA82KX%8ZKu@QSF#FO2qN1;GF(BHJG4Jsl2)mO!_L*3wH zPu<`!Pu*bDXhHu$=pXknpE3=CrAexd>pCNplV6Cxv88x{=b13*&-s7IZr4lfJ{`c; zu25~Ld<}T-M|VpJ-Ds|i$jTI#P9OrjhJ_0HEaIkNnVRhS8J<+*!K;LZK#mAysGZJeERHfa zogb0nY=kl?wg$3+Tq4gwHefO2+Nl&FnlTuzRs}~T^x?7fi=B5S2+bfEgDDg>d}A<| zA-j3aWL~6P5?fNGazE~;#?#F#Ie2PpSWuj5PJL0O!j$0*e*KR=~PFjVJ2iN~D9OrC`~%kW2DlPCaC+L}La$bWF*nz(pn zWYiFz*_L2X#z20YIA+7&gWqMZh=*SZUg{KiNdaDp@!}=dBlzt$iO;};x4Bsm_btV5 zNAVjdC)=`*;xXBaVKtEFhie|{(*IB#o5`h5ekl9j+>SV}v7xRFLOXbt#itV%=(gW$ zZn)N?@0-EP7!RJFBe|ohz5Gv%nI(r4bv-H+kq+=PV3oJ8$qg1ugGFLxCdX$BCFB9X z%J~?g+q3tQ-qmJ3$*~0f5?nilGV+nkx1c`f+pUt5$HTWi zVn6uubhP(xgK@t@f?V!*x1Tj zb8&1x;8KdyYql$mJm5Md(puic$yZ}s-32$^!#nvu+P>2jN4i|UW3YH@l*v*kyhn|c z^t?M=CenpHEi_Z++vCw^Nq<8$_}rF3+)YTbE@ zFf{GK_no@{@Bgc31whVX-C;TyG+*_Xzond6`7T`knt1r(Mz-j@;!pb?Mn(N;8dH~s;X0&Suo^J z8~b~z>KgoB4r)v@mgr{&Zc$^vLp*H_Fi#%V^p}d(c)8$s@(kATbVH z+4p|Rm#pzlc*vJX8TOPf_6X|8mGy?SoTS8%@L5)Uilw7CDRPr7pt&eg6O?POtXSGz z-m*P4IyyD_f0CoZbjo03x=tCHoD!{!FD$C?ZwZMhC{hIlN2O)uPfw@nxV+fdJhr|t zy?71i2cBkYA2S6(Kro$Hxo~)7`*4$q5#D*}hMQj)&1wfq;ypqfaDt5(_lUYIQvgMU z8v6k)Q>@vU>9)DHs`&hTyL~W17im})p^MU^#l}oqVPSpc>n|iG=uh((iSGZmwed5^ z4dAUVk+-mA;!sJvrPJCmaBN#;RA7}2xw2AJ5^LQ+-%3hnjAfeM^MS-!49{Tb z1z!u_=aC`Uh)sM(Q;{Vvc=n7L=@G#ZspfU`hHWzx-QDe5^Zgpx))n`g!AG;Pc0=!R z81ZOO>|nr;B4-|6zAP+1VQ^-Ukb7y@n=cyT^rxLqrswke*qT2d_c2{p*7+41RxeA7 z7h=;FuVUo8W9ia6oKK<;#;aMto9|A%bP%_W^=!lZMRhgFIlAb?G?Xok&#+!v(9zm! ztd7V_OV5j{hPj2o8cLPqvT&Bk3=Pv^_%rP=ju0PQreD@X1t%954_Yi`RcXR+8~yUb z+Q0g0h9bDMh2I|osLT?~c%XnCTP&M4=BAOaZaPSng+Fb_e_Y36Z1wJEuT5k1Ji?|#hi+;3ccIn;E3uLhe+_yDly$HGKsY^y22BDe4Nrt!0~zcM_Xo~Ty?{Od(ahnU?uHlh=PK}0G&eP@RO$S55~R)nbRgRuEs%?B zc5-TXYO3>Ri-@`F%*8OJ&G8hXoWx=xKKaC`j)d`(ZH*5TG5@+68vTEmuMRk_-OkuR zBmYekW408Z#rRHqhOwC6vdR6#5 z3WYa(W2{ZCTugj|qtr0R9W<2k;h@m~M&#Y8-TOzD750*hCd-EN;0BsW&s1bmido2{ z9hNt-q~|Mcm6~wphW(CDKv1967DNBYePwxn;`{>yaQkZ&K2SI_X`IR%5&>DUms;KJ zxLjyQqu7BpnN@%Gfr#xzJgvF&)v9S^*F?Y+*}c8rd?UBYcmwi5q7NjuL?0#-K$!w2 z3qTa6pmAE}#m0bHypY7U02#0WVHV>p&e|+ZvpRd*v`Ld@bK0~? z+qBJ1a@!`|(tU0;uI{&lkw8Dv(o-0OJ_i-J;nJ%1PUzG^n42!+ zgnEs1;ic?T@)!uY73Xo6(8x&K%(?ls5;vc9yHlOh4L&XAKeH>&hd?GMR}1`3jfX}7 z0Svm)pz~r^h}0~hr^V#jh#2b(buKR~oOXJAN! zAZ=Hp83L;wNWqs1R;l~IFJ_t&$C=?|^N3l4q4e{u6E;wu7nFKx4vfUU=Ch4I^}QJa zm}*P<0(9Pn;*M4!hFXM95g+LjD?z7i8rAw#z4^3Fvy?x+H{_s=;H4_axjbuwIA}5M z<})jLqDau1&aC9BaSxmhQX^y)zDuV#drzmlA$w$^lcGcY72oT3hXdRKgZl2Zk)XF2 z0(PvA(3vL94QA*`QRxV}5DW%c@{4njpc~8HeL?gG+7RvQ#aSoXSD}arb^gjim%L)T zfev6(7vg62t#m6pjyFwVktS6T`XzZaJI*!vc9B*>UI6GbN$YTDuu>IQnCQIO_j_hK z$|RXWpIO)m-x$(A%fyP4hKWQ&K;!iNUT$Cdb?p+!)U>!G znD*Mj%s@$V2Sb36*Eh|*`+bH$+%)z;aaC9n-TDi!K|d|omRy8p$608{AzI9I32vo< zb@*Px2Rlx(Qs4LLKGb!bm7bYmYg^h*uJHYYLW~JlCt_`TtW9;4&;3Rd1D;zx-9EDFD75%&&fINAtm z{iA)5XxJ_@uX;xt)u6Czz$3@^dDv~CsiTiDAX2OBfJv32QzXW;Y8#OKeukB?}qMIY6Nc!pF&LdWVmbKO;2!+$j0KXj@EYf-|tk zEBzo-47YYrvIBAKPYV}PM{xUHN5GkjHst-(G&3sKG28)-7a^8hYd!b`vp($Yk6F6l z5s1?j;WUoMRr6M`_E~5eHM17tFX~lyEWgA3zNP|FLZyspr`QoO@5`0`lX}Lly;b%ClrU%-NI)c8dGW zU_XVQPPvpRej{4kuisKcNTs|@0T3qg*SAHRGk+ZOVeCDL3`mrnLT#PQ$r1ezu_3i> zpGN5`DuXhAye2+nWo(NTuB|T!tus>!ueaDwv1fG-IigMdM?kD5p|E4gLv3O3V!KT{ zWmr>E_bMI(WfP>gOFQC=RCdKV=<&M#Zr77#LwhgYJ5)aB#z@PtBS$_^IWbY`TVWnJ zU?}d6;pJS8TQ>Ao)REJ>o>=vb6t!KneR})(Mb_evG>q;Ihv$JyE^#`W4<8PXBSJkR z<2bLYf8umR9C-v36^={aD~^>|@{cf#8pqcgIwRxwv>C@+#e7cQkLl;qh?uhb5;N-- z-aH!#SN_N1xa5^F8?3EuJnXP4oKr2Cf^V}8q$!Igk$PM!{jf#Ka;{PTQhbJU!7Upj zj&OxNE@hRq*1END9q9+n&lIzuVt?n}P8yjWV|B4*+39tOE9W_59XV-riL2Tp(Z=$8 zRZVVgRZZT*;VDDwwc?C|rB2ZX{`tAkCQo0Y>c37Z0(Vqw|G@TrrB?guO|hjp85C!(Q+D^{1+<3Fcg)6X|JjzFFVm3c06P97|wMJx62fyJC4n%`GpD zeODUs^X4dUq6zdj_QXlgWgCU(Mw7rKGXgF2onCp7HM+dp>)l`Y^}6Pjj|mS?oRTBm zm#S|72y+3zM+UZRw%0E>QQHt(zhL~LP$h5q*v!l@t^ug+q&6eF?h>9=Yarp3?q4>T4yPXUVk|Ksk?@-Q)l;pg~ z!~9NS=BhOdZ(a}u@mwgzMT;yOV_Mtd!VWmmTgm^R81r20K}VH;cy~I(67Db4U`Eo9 zbPI$U_tW!N1Ke9`!%01EgTUYyKuH4H+8CiFHQ$qtOh@!}0bD}=&2?J&#L2)1aK_vl zJmzZ2A3+)x3UY0nBNJLr4p-oY4Bz4q!7$ND>d8E#Iy#*KDX$hXdG$E$&xjMw*kX<# zDtqc1xht`zI?=@&UkX*1^TJZD!C|*M8g5n^6N~Txo$2Q%^KBtf)TZg)kfMm16LVXn zhLr`DVL4v~`RG&1p0U_&JWX-xNt+!alGiU7uUZ}h8A%zJ20>QC_X>3(d? zB#;e@!l>~#F!S+ebN{AlTV)mxOnsnzbI{H&#oGIFI-x1{Whvw%Q-*wi31u4efEfs% z(Oqv7g=7~$^Ho34fEnEWC(B{LEY{EiFq@*v{6POTk^JawItRVUhX>z^^K{sAqMQdJ ziaH|PCU+-1;Eu$?_Qemig~0v8AXlB}Ensf~?3fRm>5V}K?`zo=wij?GK4mBW4gVJv4==mS`!w5;13xV}lj7 zvyRPKB}fmEnlFUI&^%QTV+B3%Jn$6fK+Mv_)Hu!c#Qh`ZyIJA6O3fJ395UrxGSO}=y0RI0}=Z)tDt96m%;@xb&z9l)NxCMQ01f7EvG4EltyOzU1 zcj0l>cYju>&4~~U#T}p~Hy?V_1?u~t^Zj|V&AR@UQK5XHF%BF0~#-^0D< zJT)p~kHsnOp!j3Mg}B+@!Y=yrdh6B1)?0GbKJ=L>{{o`LC`bKQ5eGOAQE#wHVx13s zk!(S@M!=MQ8jGcCa*OXiwM9n|U_(4Vzv0YB2!wz^rL*K2;yfSSdvC+uu2}aK=lO7S zKtu$_CiqFs}|Qj z>>AkyXj?X#ZWiozq@OrbMOB%tjXj$Sy?BSww#Y>pN2zZeZoQszaN!MgOp&&`&yV2i7s7(IL=zDE|81->Pt$SKR;WH=9!TUJslt@W;V{ zv@&Kf8xN5uMn%bsAZ3|3=O0M+6dOK!4sG6^*{F|zhfSe_-pFsy5NBo<&|FaU8#R;8 zBiO->3!6=c4)vY6J#tDNWn;{EVnro`VNZTt6>7 zp0&}@^y7ILvXmlLeEh2GTt?L{Ox#fTaSb?47oPcC^x^g6P3O3hDgU);FAIP~L;tVR z%%+7WfXM;#)kGd}&DTvL>a7g?1r;Vklu2H1e zJhMA0Wi;Q*H92VBuy92q4;$Yar*1aKp})1O+7g#{geTSWbuNJ9Dme3l=yb{uIkObM z1om+&&p|qRl!nO;PZhPj`{k%45xkP2@@XXrt?OT60}N4Vu}o>#oUjy7-9H`~easnJ zpmW>d!;2{8B#N63&bumRG0CxkR4L4&ke-tw#dnk6sinL|8SFoCJ}gpRBOS{doCk%a zig`mw_7fT2gh`5k_buLTIShE^`K};%O;Q#B_*D|9hqlcDm*;BdxD-=VYCDkI6JEZE zm!>EIDq!6Ny9cJ`gTa1UPLV>u=G7+eSi}BpVQb)hi#-@|xHD{aGxi5qnEwpPa7L!3 zHd>N1fdg`!(RpN%X%725!h%J}boKyD%2RW*oxz+OiJ0(A=D`Z!0gWCL1&`ZcL6|iJ z5!jCRga_^4M8l*1;PLCfH5ZTCC}=2N`Zjnep4QEf=ubsEAR;tU&N;SLXy@BP(eclx zFRY0+Jd(#SK4cf*ZI~EJbgJ)j4M|A%C%J6;&|Cyf=HR?Y1E$A|Y(YUdjVmY{KF1z= zWR3-RFa&qM>d%UTx#mmK`|xk)YW=9AJGxb`t6r=LHL+7 zim41AkM;~=Dd$F`y-l|e2pC~=l3{ZeQiNX!jDdBaAV{0kI0Qi(SPP;Ux?H{(_9jXU zoi;h)VP>BRA4HcWjGBZSz$ZgrEEMNPLTRhjM{E$_BXVmc2=0I){}JrA$h7u1 zA0GVAOC2$n>c24?Asm!O5C&sq+Gx=@JrA4^0~LXP z=&S*4effRU@TfUxi$$bc*H;(L#quA4T^5EI`WM)5SOIJxBAPQ(&SPJC0S5@=_n$L= z|3Uxv{O_jk`M08f|G%A=rfGJk@wV|8d>$heR*K>n#8eb!%9PLMA)N*X7eawu!B>Ej z{ZQo3fiDo6L1#_mj5_SN$gWdxUS?5gPTuwRKhJJfy%WKkg96G+|@ zl!V9MyubkM&+cTu5_qHi(Dp(+ zWTI?Gmqc4@4MerGo8Su=6@ejrZM?O$s=D=f$NCNJ?HksEi?_|bg`FyS=N5UUGNmI7 z$(k^wZQ|NHJKO4Lb>RQ3RetVRTVB34ue>}j27dyWe9#fA+V6Zw6&N|^pTbI!k$^*D)W%$KQ8qPS6*4^^;X?DbYsCCcZe~nK%KwII-6KtWh&0%dcBobUO8~b z9R;XHb!L08-!)&*&xixfb`bhNO~91KPP4t1Eub<^4}?(Dswu=y`-wn!WHYOAC-Q;O zK8emYlOlFWj)?4E-XVTWCjIh_uofKA7w42{j@6l{Z1x3>yJ66q+p1K0#O4(qCBm#42zwSDFMida|8`fWfFu;if4Zs08PLyJ`= zw20%dbVxkVrqp52C8s+wR$8+@o}azCJt3#Ks;+%~+pc{(8kjFVt$gL$T$Wv*Hk?&o zwZ7fEXYT~sXNH|Ui9082Np6s@35ftQQx>wg>6p^;PqExh1+nbOU6*g~t?9U7l;E)# zxqxRo;8_5F1Cg6aVv1W;khZRRwmC&jGrHqXi43(JZN-FacTWSq ze$_UR<%@ojJT(b=Y+`$iH!ODwdK59l+liZ>?hK7!!f`TG;^2BAAAG0-G*4=Yi6V;b_?Ruaa{JA&+X*lw` z;<=*|neCRRQEEFR-SB6&BVI`Jz0LL-w?yZE-`ghsXV|OdY^iZI-Z4^fstQ?cmfXL4 zbIA@LTTvIESEHlwaEuUFC{9q?^OJ7i%L|7Vv&w~6M2gMty#LXcgu+;(AmTB^;qF|)3) zs-wDTckO{MJ4#j{KUqln8{|;HaDLF_KS0qIiMbejwCPEfd-;XS=ohyo<#U|f_#v8`3Bgmrf!8x*s z`rk$U2(sw=MvyGx93*nF)N#rigdOxs@){}~Cf1M5wO3}}*Vq#KwZz&yTTa#H=3N&Y z9f_NK_k#MQR3}mf?P=S#uYD8ozQw4Ry%~4Gya72&B)!Ni%TkljmL&;VX*I(QXt<*y z4;v!lI(gbZMb;yV*u`ByM5t;l6;=*^CZNuhq>>=tj&Ji&eqoMxc+{t<-qamI}crTI(ev%4;)%v+_5Op zHv%pK9cgX&FZ?PIqlHMjOvpGG3%KTqzj7-^WgSU{t->rfB|G+y%;MX$wmNQL%QEZy z&Kis5$ezK*4qOFM#O}V{8hgbhahF(6oWHa#-xagi=89do@WS!!9r?w@3*xpewrwea zq+-s%6FE-!fGQNDg{U2tm%SSQQu9(B#Vpm47n3c*|F9;ga@SD)8YC`2J{kw}Sc?}{ zElAJ#rh2k*m&Z10hV#K+y!hfbN=lwQdGg7Unm6%ZS!_vJ?C)T9?kOSTVEYM>Pvi?8v;fw)XUMX{>bX zCz_j^&+pvv56-Z@Kn|hsR zUw!9!=jGQVzWgft{OOfFWglt1;P9x+8lM&45aT`G)_z`X^_G<6_^pR123gZA7NfS9 z*13`#WZFPA6Y-$OVHwOc6hj9(9%tRrSlJwh=u+(bMO#TVfNF z=H0mNxtyGwn)s!Ou{CuKFR|XTn4+?nOD_@l=FZ-X7|}P#j;ujel~~G8CFBOIkwOw9 zZ{h$ngZSLckgyYlXP zFs8L-(f)yj4_<%G>7+fq33ctO=lOc!U^0puVm|=CVWkJWB_)Y6bb$pxJQ6x231&aI zqGUl+86I*%4tE1g|mNRe?xmTR|%xw z%cFa?#Xm<1?%Jk*f2eNfN8?`pYAgObbu<3ED7L9=(V~?rQ?I^0=C|v%udBqr=TC0i zzO54f1RdtX*Zvv*KBO}nW1J#vSuEzZ#9^@eND-)gI8cYu2L0F0+?17%l<(|nI@4tU?AHis42LR)JBI3qiVPMFF=AdMNY(q$IzOU?L3wE*t!EOF} z=gwaf59XusNBPG^Y#ua^5FJ6)I4Il9a*Q+b(?M6H$}Hh ztZR?A-1OjsH?8K6{NmpDk^c2%8ylZv z%bxq%hvKbYi2rfSlL-lX`w|kLh(UiAqX={L49o?|dH|;+<-aCjUTB%)U&{HFaxbqU z7dM9Hj)$Dm(M(?kM{{FWReKfrnJktquP67{_eXx;nMX`sXT9I)v>2<W&<%u`b8`=C3FUmH7GMPk8du{;-YYV0|5`%^Az(S%2*vKYyyJXY zkPwn_?t{XNWwU?cP96_W5bKRBH4d&Y4zaUkuG`pt-(9!4-m$WT_A92YXon8Xn|+eeSepYi~6Sau{KzlijDEgR8}D>O<&%T#+EhS#yq|c-`0rguoWfn z0hd6h#|y7W&#{&vDp{{9DZ54!Qf57WW$s2?x@q6k)qiN_?u)w)9ogGbF+V#~H zaNuw1-SUYKJ@UiRU4xfySo{RFkGLs5#BagqV)lf51dgPXHE_|h|?ykQbsVP zGq`CL$gP5$Dsg$=>`$0)jg9|k-%s}6wk3@{>HD|bf`VLr@4F}1hgZ{BTcBkR!5>J6 z9n2JSDz)A$QftZO4NA>YnSm`CvbEV+F><_;mwm6Pe`v?P25Z-7$Jn8s+P%fr#v9gb z$X!=jUeM@!y}GcpCM##%wFjE_ja@KuXvgres@e-)v^yMY3LIam+qz~0TycUuf3}Yu zw4{=KPlZ>8K6ua^ZfQ#LLXN}?RmqEUSLAk#u1;H&n3}s{&7!<*)!EAmtn0UIWd+?c zm&6^UqVJ{dn$D)2dDJ%L5*7~mO zO=ZjSGF$7qSC(b2TN+eSKeCyc!Q3^~HG`?EQhl$82R`JY58#t!ti^qPBk+T;{02vv zRy{B`#_R(BGULjccAskbIZJ8Y(@X{5@0-^i8@z1rnE0c37w?x~WH6dE8)M~bQWmk4 z)r@$?SH`|``r2zx4-K)k$F4tGlx58-Ix29bSizw8mZZcWYixNjD;Mvnx9$zR#c*%< z^(>oROgu@mk%~WD|ChfI4oOA|-+;ReVuWsSu#_a0WMxZJIG=y!Z7yl6>u{__;}(%T zOaxHzi?5C&wH8&Lde!%pKz(ME8!^y9MWW3msL9GXPdM}U7{1Q;N2~7-0ta13w24)9 z#Q&q>t*^YYPt<*Q-0M3Ls84Vv0nXLb<{C=H$XKrL4^$zE&*%Ki+eFVKW2vYk+GN?O zqFy$;<5k?7B-&!nyuvo1_TLFF1}hN5(Gagp>8aTRO-%=y{&nrD49XJ!>B-MdO?`G< zOLa|ia}6EZ0GwsBZ?ix1yFnY;9kf6PVwZmtgBD!GQeVFJ-Xr(kTWhT-EUchE^I13R z_MP^fK7MrHzN7dj+t@PuHvf0zAhrlAler|*vZOL|N!%6O@EJ8*d9$;Gr=2;?N1SKw z-b#I@0-@epSXJC$n}r2 z4TEj32pU%y``Ix2sG^UfJR1{Pte6ab<};=Bf3Cj$bFcfV->OIZh-ToQ#+?FK^ALA@ ziu}eR!Kz%a31rH}FGBnAPp7R+t=_%+)I+E0>Mqz08us@~m7+&h{YqZ^T)`rGpn)pecedfmqjHN#0J!VZ<>%uTa$tOJb8u+l;h1n$(s6g=v>vY6IxNO5KO?SfU zoWsvU8<)X1?0_u&ALbkudk3&N{@{jl&p_Ny5w6=3RsaPV;X404CM3=XL_-kYuS2eX zip8X?P2dDfqhWz7Q^i?wtRFj1HLqBjuslQDknN;HR_Qf#QNW_5CFj+b5nqD`J_a7h zQEPd~?@wHBn z#pKt?ccmERU5E)1o*dLM)I738rj#`|vz(Te6YLi3503~R3;P*VSDfXe9Kn>sSkP@sVl&dm;@R-lJ&EG4YYl>F8pyO!`Jc!0*SXE2DU$QiR3&?*=vMk0CxpfJip!YO1>fKS163zd% z%7zw=*6I>N_5S%Gw5G8lTFd_RxpyBuzj^=zhS13X}EAzKR}bSF)MH2YnMdy3R0gN5n3wSppfv0%Zv zhGe2~9@aqLMIM3wzB|__$35EQboNGMbr)BxiT!~&H@Q*RUxeG-evg}fLT_|q&xqWD z=iWXAMn`C$-GzAN&<=Qyj4KSr0e*5c9Mrkv2>l$OTe>Q&<)K{>F755GS-LN}>ql6v zXnoDG1QB}O3$>3pHDPUr}gn zx|S?LH>?pEWsuswG`^G1>F*hNdl{|!OMa!ZvUGDN<@<_ETOAffAyE3jMx^eo_S#xI z-Db8lH5K6`sdHesKlo;|0RB=o&%)P`O}btsLhs+Ao0}^7_s!|_8Ffi2(HeJMDBS`( zdrnwK=#A+F`JvtUKBfQ^PThuwAn4?+U#={4)|Fs^wLS;h&pq-Q0i;88^3`rFU5%^|IdtF^ zsp1^jlrwG)bWaDJexUxn_8GE|gwfLhUA`PYZ>Cmz#5^Nxg^sZBmz?rGN0IDVqnuyJ8v$Op-HWFL{nly`i z)FQq_*pUc46m;V@W})JQU2Z6W3iFpQS&AF%))#GXCCsFbE!x3dde? zGAA+wpVvop{4o6dz0e~`#_5Ql*{E>rQ5SVbhUD(pyxfv9>-zXrX%xohhvz-<$P(qm zMTKQAF-ZTu$e?^#-+Qme+Q#-1m2--!A##dC_nAIrckevJ@4H zgF#1wXzmmlsHaSGCr0sb#!I*x3G4N=CgwcF|K&_Q^as9Y#g9Wt&Uxy{T&lh2L_f5$h4%FBp7YdZvA;)k z{d;_L??yUuBoSP+?t=Q}TSJ|v#uN+ETOoIca=OpO_?dW@_LS&dzjk+?+M-U-(VKdC z0y)3+JynG768RR5eZVd_PyL7`Ut@aNk{xm zb`=%vDoXqet2q6r?>p=FzS-ORCf=ue77bP^_l;@&k7CmAo;km6l)Zlbl67Z3AnITp z9*mmLOwb@05Lp_;ms(QCy(7CVBx}<%5&j9FwxfV9OXdfKsL~&jOk(se^G2+As z?i+F}`RtW3*2Ot2rsW#nAAb7;n>Uz0klp;j@jLGDu#>*)h^EX)1&qHy8`!4_z?c;q zmzRXa+rUAO)Vcf9x4b=%^~^b>K*n^*S?9oy~s z(5)lmePxadHeJDfx+^K|`HVIF?tRmDfAqn}1nlte*-rpF)HIIAQs@JnA-OfaX@~DG z?DXKK`1^i!^hEE;pMDFH=m0zvi=2p&6|*N8SpZeU&mpkqv(@Wzix(HIURQcmUVcu- z+KTUu_8jWnd7x|bqW*m+A759pE;l)2)xxEPR~445Da_5zDf~@ejdk;mj=g)^yQ-|~ z54H}ti6(Zy@V1}{tw!ru3K3FPsTT4jQ^5aViB)TtbY&NuY+F}zV&3wW)jNic^?I(o zWps?~*mMPG;``mM!f)721OY#w{onI8_}$O~kPoa$5{vl-#QVaD6EB?b{dGrS;f}(@ zk6nMm-FM$`ec`~TJf2SpdLrb5{Tr_%`IhUPBq5HJ#t+Wyc8$!;unLHYuY5+-B@A9e zUs2>_&GnZS!?ZtYa}_?1=bN}TOwrDMA`AGshPC!d6zw2_=RR7_Sh zIjL_hs@~$(a?*bUa&k@ojTbtL))bWvU4Za|-tBuk2Meu>yEbB*4RlYM{Ve-W;3edw za;}_w{K{CXEty%RoP2e1*^%b8H;vzOkB5EGcd3w(PeMlO&MqUahSD0yNbV{rBUx*9 zPF~gb0e1f8Do07>!ld)qmgAQ$9O@fB4iW;cbr`QdoU@E9%P#B!PcU2C63B>TiQ~Hk zOPFLNh$R4f0dPk|5y=Rh>rgWCvG^@JeZOX38mfzLd+=|^j`v>t#tQ_K1u-6PvERN= zIeE||C+l)nudR4tM9Rt7MFaaTiY_PJmDUXhl$@l^ep2x9Ji`XP79=MXa|9*#txe}G zx-h3`tlVB+za=JZTjp-h@!qMculs;w3yZD0qpEDo_ajfv1qW8IIppa(^4M+nKD!*W z$9^T^O(M(6%voeb+7jX^SZT8@d6aC))1W0I=-G?t12NftTSD>8TK!3Da`{F1dCT%s zm$jE(;5`4(4%icS_uzFk`NhkUQ(;j?cRNq)BuOEA@;@sl>9e23{fCj|DblUfAaC`E;_by>zcgQOIPK4)4K{VGl6`pV~-gR@KV@6f>dmj zWaX~QsmQ_q*`L#MbJJJm`Jp966Y-a$1G6?z8z~ryJ83QT+Ug}Ic7<5i*F$| z>Sl@p)qY~Yl~oEY`Wef5Q-pKK8B4%74jjZ8OW5a#=bk?ra>f!cb>cmouhKAq)l4zY z;m$p)GnRm6?iow8*9{!S8B38n46VJ_GtZ4t&R7D^U4U2ls}%77a}YT5>_1`&JDjWN zt}0m0i8y0fscrFlIq&>(_%oKXpETZJzZ8DS-1E-8rX!X( z>x{bJMP2x%sUiR%_^fkH(D6!=Q)JM2z&J{B8pyMt^gxwaPG?UVpFusyDP^LFpa(7s z7E{n9&3K3H73V`Bry@WrjGVp`BBwaIAn$bapOcVss!xQFoT5&fIQN0sax^*B2Rd+S zqj^`*sSTm0(gELgv;$eyvHt;CRnty2>x^(_A;NJ4;s?Muju@Y_<|tsFAYpCVv7_Q0 zk)r@G(H*|LQ)i{^92M<(9r?%opaD$H*h@n`~)#s9}`FMvvCw(=O<`Q zORHFwC-W0z)&=J$h!rs(kX6$egMh3u|8W42oa9x}oa7br%X7|85H&qP_hmh7l8!{j zEtoeyHo>xN&vG1zPFbY06O^p4DJ{>k<}{RScGB4RX@ZC%zu&wptgvRRqT~eWllhsM zNZAm`PQZSaf$Rh;Ry`@x6V!Bgk)8m&xyd+fyun`=GNt5oajH&FaJuQzhc9ci9rL|| zgN~3_)cr2%f_9Y^i}MhWPD>{`HNkg|vDjm_#>;xTFKZ&&L0%D~`T$~^!`khQD-lbZ zF738)x$zm)gS=M4i6(&+v5~@V=jCd{eR<`AoRzi;ZMR8Y-^Ez=pnX`1q{uM@@}GSX7I&N|cS|3Pic)Ik1d!PnV~rpk?2M&c^1LuO+mswPjab zGgVQ>FBur{o!Hafy6^n@)TQ+}C;pvU$(x~VBe)<^+b7o#bj6>0+y67P%`lF!^LaOD zOwkLpP_vPR5SX+@9?X#llu1eM$uG&wvE=60ZtbpgWLf5Q_IB3S+_)+wHDkH$SIcu( z#$?)dH8r1~o8f!9am$+LSB@mF%iSh;4|y?+n-PPHHRL3$w&o8Z|HTVFr1XlK6Nb(1 z;ZGY|MIK0lA{O)Mwp*Eajm>@zzuhZ;qm}1-5soOs5Ygr?{PrMz!@SX=A`dH77#zJ1 zC!5Xg;LjKjBi0bBIM|+s52EwEQXuN4Ibnr75KhQuCvmR!I&t^7L2JO*u{18C`l#I* z^nH!&dubMSI1$)-{OyI?6M7Q}_96txu-Ql8>-Qk`5Af-Ioi!rNkL$}$`Rq>ql<^Sa z72`+}bxfd+P;4-TCi0MwM6~~D{EC_P6Px>GTO@OA z_RiUCqX%&+iAc_b-Uvw%_};#DM{-SnTS8ZBM{!bRsRR2=*(*{1f!R#sGUyeoY~#8w z72T_p%EI0niYUw~T3?DV{^CLvNtoY=wg0_*y>XAFT8ssvHA6>Z4S1lrB0IYx`xD}? z4;uk|eRf$+PFc42dz;Gzc&VMI(9WZf0}=H}yrXY|&?5_8`jM$A%aF@;S~r8n2yYEf zhrb=*9@wRiQPVZm}QvTdEv+r-ycmt zfxoADEnA8BCOZ3U=$&o~oVs@V)b?H+#-mG2d96PpisY-0KaB%G@?KVWcYzy_4mIH7 zqr3N>q>GQr0yiGfJLt#wXJ|hZD5d+Mh$z{Qy6ZsnWBk$I59&g)@Hac|Ay;?b%etGu ztwg#XAL6FsD3)2{BLbu7@Cc+*_xI)b87tQ;Jhf5wNik207IS@Br|kO-GPu$CAF*nn z?&j0CDO{6aTa~lm6mCzD*v`F8h|iAljm9a&pu~~SpkbLC7 z&%nUmQp;=Sh7|#JiSr9+i})*G(fky%iCZ;N0tj9B(yUIdAM1`C&BxZ z(H%tZHDYN6zMuaH3PI*doI;e5?>BUZD(+44^G6)76;VZPftvt{z6UWbw}MCF$+HZ! zJ(u%p{ZRfm44(*Scld9KVza;DIYtBa&#jOMXuY`nO|g5q*fVFd593VYApbdO5p!%t zw%+^B42rTa%Lcq2EgKbnDr%WHbgYiM;`hh9xRiyPo%W(4J8*;!f*d>tIe{8%lMEg(|-3~Rhe>TB&xCnbKu>oY&DYE1F9Tj zRO2kDY$p~c8E;hOIAfp1qssG)G|RiH9B(9AOI10+SYe$|ri{F7yd^DpG%()TzG$tdQ5$`+%MEm37F zPQzZL$}z?SdrFmKjU0YJmE(+O#Ti3-cb-uOo|5gv8_TV!s+?fht+lGWAp5gcx?76s zFEpBK(qtL9B-i{&m9ei;^KDh;C_kXe7Gr76HAcPRHO8?qp%OJ>IGPMI*y~_M-Bl^6C=2YDP8^2^FGdS_Qvo16VYeZv2}P zj5YwE3HS+sZv*)I@%R0(Dz!{RoPrP#;4ACfoy_QTN0_n|FT{=C%!w*`|g(ww|$Ju)3{l3LKBu z#|DbM6E-h?nXvVHr^luyhCP$$;r$?NL>4Ur!r}%VB(@D0ew)#(urfN_(<8QqB3m;$ zH-x^Jg3Q-|7{$hn_+JrT)taJ65M&g;O+jOfgCNGx)YN!Qaq-N|Op%*pyQtqgT0C`h z96$Zf>LMG?n3H}xH+a_x?KdM>UV)mJv75kpM_Z8O?{@hEV!Ap*+G<#~d1=c@mR z$;_JT|2{@v0Pmgtb%V|l`T&gxxBZ~j3}`hWXeDcqo*_+5I$DYvi4O@iiIWz_E?AgW zd~O#!L}D6fxizQ-vRUEuBB}Mc@CEm-l?w^+I9iqPki{FpH#34G$eNHs(4#W~xV`x7 zhE8?k+Y$Wj!(ZZt0QZo(YJ`+-7d59KFSZa~oCFm}WsC#oNx({4eFRTZF@unwcD&!} z$Dj~v;Q#yoBl-nKq63DpP2kmzXE#c%7^QmgZ5RGV8V4I7C%>XXyz2qACZJr1D~^iq z$<9;?O#k;Wq#iYwbU@}^7_)6K!>uT3&Zdza#JIRIK4c7}$f5~qmz8n|2M`|Jo3-K@cT*Qgm8ygmWmJKqf zwbnRV^%@7zO26Pak{k`iG+LFO9O*ZWTi{*dRgZvB`yL*&OutWvwlr1TXq&77nP`%8 z!dJ=km>g%gcA0{etM96?H4c+b#z^#4QUqno7B;g zn&c`-b3Y?=RX_d)XhWk)E(P(U^mixmyBsN!ece8dl!ip=3fbnks5^z8NsH0DB-dtr z5O5ht)-}hG-X!=XcThhxilli6B0UPhI*Z`Z<05O3Hj+?J<2{0l=tnf3MpoAxZ==BZ!H*{irAL&^?ZcmZZfXE+@Is+^$D^QqX{Sk+?xphp-}E zBwa0OL|jV04d8$JyJ)nKe4yRH0B&ZzFQKE~f~}wC8!6F55uydbF2{kWLw%d)NH)ML zxtORNN?SeJnzm=7NO(HS-U*&??@Kz;OkxJG(RfXmD62uWwhy7bVL>DEy`=t=8pzBy)GA2?y+JZ9B{bB>2J%_ci}{!JE_QL&Fl#ks5ol>5^-;EC=|Ta1MApgjb{y2TMj?ueSD*cR4* zZ$>*L@zmE^v_dxT+^Da$EJ-|Z5!pbZyPoVxs!EMBi8e`xYaWr~sdcznZ;)0YX$-6o z1TZ8WLt23_CVma}$;^@wJl0a8rMExPrs1$)-}k3CLfyW+rSkh8&YCPYshcOuOZ2!-eqkKs~iFI zD3KQvOzq%0XX6AZHzb=RgVc}Y8uAFFMkYy=<0vtctFNeItA^B9uvm7j3nvlLD9anZq$Rs$b;VGchY_j;uBe9k|Oy%Ngq*x z{8#cfNN#5En_Nnw@sSiT+dYzN(!>Nm)h0-#91!=1dSH?Qdi)~ODnJ36sdZu=(*o;2 z^Ea{+HbhjB#-?(^9Q)BBAR?cA693b(E48Xz>Y{lYjku%$!Kpna?ICIlB6)&lu^z$O zdIY82491<-mq{}bM`*5~vDP|Fw|RE#i6>=G(l4UV+6O+Wd={D?$g&(i4Pn3!q_+Zo zvaCy1Fq|Huy2Sg^a*#}q1ih`-6LcN2f`PX6uM$%^?|E<7N^PO%a~gY1DUw4yo6wY{ zz6f68O*zJsSeekXky2r++kh?ot`|6Udy)B0dP~IV!5W8JAx%!bQ=fA7Ml*k+6TuRy zhlrw7n`T6zwn$3R+4Q#bSG6A?{Zf)M^BhFNMdL;5-Wq$m!2bRBd+uW=?F7kEqyRNOsNACpkt-D2=A(2f5ZjGlD>UIc9QCNqW$7txrQO-wx+{ z7onAI!E@w|Qj3JArV#Ojo(D=VFqlWRPe^bQuNC4c=cv>cX{samOSVb-wnU2|SP9~k zG1MoDleG@4@KOa7DG8K42p4#*DC-(l3JzU254C8@S2Z0n?d2wLiqo)R|V z$pIlVdPb@H(-=r7`b5j*1rQenup&Cs7=@dkd+`gwMzsU|1k;%?mg|tzF3BrdTuJd@ zk4x&<36uOdl=dJ?b~Y(}Ke8fw4Deqk;3AClexiAWSg+5U=O5%5k!>UY;Rwb{&NWFF z1nf199&w$tQQ@s&u>I4Xp5_RWmkIoj`jS3Y!2hckd=l)Jn`cW}2Bdt*Hl#N|>vh^D zlLpsoF>-FIZAY-5AUTrwTXPA$N!aQ+hUONkDQT&#I#HR%QDdb?+q`yFCdOOJY@kg| z@nC=QY?ue$A}gYMHG6S^8noS~Yech2as^M?WIdag`c`5?x>RB*C73KTjX!Ay;sRO= zAjv10ky1y}Dpx>gG~_R&JxEs0#__V%BhX?V@CA*6?3*<1L9{{ZE5xA#!fOg(sP%8a zCzN~;o*w5)XQ?Fvy@aPUjfK`jx~^QOcz+TUu(jnuyc2m8iE1=1Btuef(WuGM2MA`o_d#(&7i8r#V;`=3}jZy#@M%W^5AnW|YaA>0P!ilp2BGPSm6w zDvG}8!e832YRBGZ3+8h!{Ig-M>lDAx?^!~V?ZmI$*vxN7ctba8$Tm7rk9P2O;~Q$5 z0w~(Vr>&?@^F!iZm$6Iq;X-TFUpxAvzPI69+WDhCsUE#Sc=X^im7DNgo$9X*Z&ANg zpXQ@9W&~+Bz7O;o3>CF3`yXX?+AaF0713_=tKlTd5u{H1>%iYm z{7Ug(YHN#cA%czx1^Q{DuR~QR@*?6PVsC)s|11E@07HnIdlj5rW#Fvt6M-p zJrQ^--zl7k-ltx-if<)kL=zfif+f%j*?;O=!a?-kq1vNJ0m8o(|D%>Ahs=e8 z!ZzAbhkB*9DU?alo~TB9nv$<1b>xT#IFO)jKraL@;T;%rGrUCkxnmHH2Q*JnTQoXE zk5)m2F3`_~5uujkH}pPn5Ak=sqM&S3ayL;`*OfGsD;YF?+cBDw?y|j5EC{cif@T4# zOF9#T#3$6FUL^^PG4)9>Yj}ufiI=n_1gJt%MvzcXG}iQqdLT(4PHG2D={GHfvJX9u zJ>p&6D!ms>Uo9=Vo_;TyhLAMUeN)>3+=)AgmJ&i5Wl4>*xBK2>_H1jzhX1T9u+0ol z4f&(^Y>nQrDO;O+)MLw&!BctRqy23E)1g%h<}aAvJ%q?D0a2HC|J00o!ehf1Bg6fk zu}Q>cO^*#A8jFIpx>{Oo?c<&?S-DkKD6j=$=1PnF?WxzPrGD@DFxu(!jCf}XD8`Gv zbdOAWZSKSF;SqP=h)0sgZEJLHx4EZkY>JAL{S(9EQF2go;Zpq&63Lh!!8%h@91j#V4nb{ef#y0J4a1bzHaRssIz58uINOYOVq{=uc)(*D@Eis$$45P2 zBDB))9RU$3Xmt3n$F`qXYkb0cz|%i9SsLs?=KLL&gm|aBK~hu@e(N1*a~(5 z^Gpg9{ESJs;43dRJq=DR0I{YAz-k4yQSZR;equU;4SfQaiQ&F!3N<8Ru;BfEQ zAU!b(_zZH7d8cfX2w%1J9i=ZvCp{yF5q@Z+F%z8?0Nnl&^g%C<9mPOQ3?G(cC$vGK ze)kxG(+8m$AwWE%eV%~GEdrI^)q2hmSV<0i4M?p(y z6SSd#m|zwp2>cEhhrBajpa}sip$vE@JR=@=K-dWw8H7oJi^OA!=(61j&!Oqz36J1E zFpwH#3H)G&E z6Kf~eg#(}1s2?Pn0PGapN}M%mo1E?+B8mV{;&90u=un2kiVh3F3d7(irOD)AD6EAH z3NFvm;oSklV8((-CC7bo+|#cZTXt`A@1IiI8ERIAmrqhOEzuR&$oAV2cRoDk9?^Qv z+&a;SR0#A1=>!aR5IIQ$jC;q>8rW{qW)`K$G?cw=(^9A`gt=ES`~mS9h4vvvb`J>Q zn(`K4$VWU=V21)5xL|U+59(-Yn!d0V7HYLYKM7sqg$=>if^nr@HG!=)Z3q!CHb-s! zL+&wVmM4Cw91{CAa3zED+-HVr?i=+lV3eAF=(83=FGYAEl((T*wUtvA1Z{an_KT6RuZ#X}SnPCrep_NDoUm*ZD<9s1 z2o@t7txSl=4O=XRk2nbfDorW826zngy*!r!1r4W8D5)vZYG$oJiHg#=DLpq}Qxqjl zI0X$^=!Qjw)8aWYWmC#;XnNE=RtR@vKzMmWD3E3b+#n|@9+-m(@A$+pIXI&L5&{ya zKI)mmi&JnjhCL$#lfpTm_oxFj(FctN2Tdw=01>d~UI44!Q82^04MTSy9`?*gi%Fe> zV<*J;IKUp>IYSzGRPdsJey-Y<_5+q?(&jlb4*CsG3AvtvdjyFxiJ_7|QZ`ZpPr$}Q z(F*-n?;jFrmXwu24X6R7r^m>Pfi)%RP&xsGgmnT*$R3i#AdNkax1ghl6{JBVw51g- zTPJ)Qs!4z=(GKlg{3K@pQpK6-21^ngJV>(gDbS7R5(7Nyoq}%gj171vKsgMZdjJl| z)G$7fstJ`PR6Ww~85d&h?msx@oq;bkC`s> zt|*t(2|`h+F>)<|MnFvo{XmYa;%zAH5uiLeJt_Pvv(>~{z6 z^@WK80uw>f39b4+?~?^lLXfDNOir7V{4h0-R4M~bC6p)meAD0v8i~W+VR-xdwWg(k z(dtL5YQI|x!57Upv~<53c=ybMq@5b!G=4{(-+uG9BP+)WI!c45I%huj$YuVP(+Ty}@Ep7F! zJq;~wO}09`*Vayx!fh?xXtcXsysDaNapAp28-S^AM$68+me!W;-37MBmhLucvk{Ft zZ5__e?w0zVR%fTJqo=c@9dk=(TLYSHYiVojL@%ywF3da8P8b~Ss0nfdd3=kO z;AC{Uw)fx*)YDyH44Pd6binMy|Lci8B*tyPklN{P?*t7LC_7uaTm?2~XG<3iLStw9 zHZ+c*0F4O89*_`K!DbR(8W#GFeiL(eKSQ7vy{!n>;BvO2LGVS}+`3rWIrp{$(Bt(#7+(EFn(MLzLWJmML2j}#3}jiOc;md9zUg~C#4xxEEn!T;S4O@g8m4bgVo z1eWOaw)!Bx9)U+VM#hmogsI~;*TIJ_v7ti&M*6TTb&W%L;@m09IL}Rg3}g0lIHMBg zKT93HWT<7qx$GDt7AKIYF>=YGD~q@JsIcUmmw?0a^xdO!`bka zxQQ+US;K5bCf4J#jT~f{&c&Irwb=j4$L$COhz%&hSsyxmYez=NGMu}tz*(3ooW88V z8O;sI5m}2&QJckzV7*w^Z4_(HEyfnCD7Ru=k=Cp`um;)*RJ*Yfx&v#SyRbUlYn*Rf zU|eYIG4>k!3^(J(CyXnM4;cSq+-CgNxYD@ZxYqcn@sM#Jv*29wzabOUDP-!2F|K2= z#?{7GjaOKlakufX@pt1b<89+!<5A?~Okg*WldAFm^hLKgNuYV~^z!_CaZXm7*LE zW1sPN*p)wqz0~8zMaBu^N#h>lV&kN7iE*j%rtwGPOKcvCXY*MCOJoa-Glq{XWQ*8h zw#1lal&>*~B{PQma+k4Gww$eCX)K+sWUE*PTg`07e;WT};#O*w!`84|mdDnzbu6Eq z#|l^>E5gOFCB{3(k69_R<09WO+-Y0EDp?h)W;JX*+rTy&zcPN!YS|{XnK@Y_67DN`y%_2@nQC5+~oT&>}mE4dzSqx z`wIIi`x<+WJUTy7TI-h?Ud?NelYaw8o)f-_Z^pg!b-bQ8a2IZ(ZQ{+mg>T_oc`M(>+ju+g;M;j8 z@8aFOhwtD!jn5j7^IgX0jV~BqGoCO$XFP|TMPD(lG9EFW=ev2Y@wD-b@f1IwU%)Tq zd-z_ykGpvv@8<*D!}sG3+95v75AcJ0gpcwu?&ahB5TD?ae2P!wM)w(hgdgR{_;G%M zU&K%Hi}@wShxn!ZGJZL~f`5Qt$*;oQzt`{&@@tVv@D6^RahGwY@h5&gzrncQxY_s! zvOeBm++y6yZ{#=eoB1hz3%`}$#&73$@H_ck#uxdA`A7Ii`Q5k)_2b5~#=r7=_`UoS z{62m^|0I8aKgb{A5A#R(Y5pkx6m9{2jDLoImOsv);Gg54=U?DY@-Ol)@h|hI_`mR{ z`7``k{;&Ki{Hy$H{5k$S|2qE$|0e$y|2F>)|1N)le~*8k|A7CHzsO(WKjJU*AM>B^ zpYng>KjS~gP0g?HSNSjaFZr+dulZ~IH~e+}AN;rc4gNd+d;TW>1OFrc6aO>+3;!$s z8-I)coxjch!T*#0lfT3Ni@(dya37zw7#3#X7K_DdiLu05;wDU4JXh1*isW_MF5bK`QajZ*rh`j^!JKyDhd%nkCjB_b4Jn|Xqk}Z0~ zBcUk(NWx&CJip1`!2CgfQBa`NZdXr7LUZ7agrPv$+T7=!unyr*Y|9juBR#QL8^I&4 zMZu40qaYknz0_W>+G~hwQLqjxl5GjJnQ$Obmh~MK>RFk1a1etuHUhtYxIebl-H(;` z*b(tiRqE8UKDJe&KO!F1R^VnG!JpVR`PP`}t+I0YR#`=Cn|y0b5^c;q?#0a5J3i!z zYgedv%_x<*)SHb9+J~mc2Hg|Wqa*I=sRds1r`S%}=Y*-xa)lH!G*=xD#y}VI=Msg@Y=n6+{w`^=mK6>QfV3m^wr$=KTpRqlXxu(SPjNkJ2&dH$?hHVeFk>q3HkFSC%CWr?&tu{-zt_)u^N;z95}PV1 ztff^7%W8W}JJv(TV!YySkN7)He`Wpp2K7|bsaNkcsCF7k`t-CnAGcgWuCWfCfT zxrEkUuIg8m#tsRk6nj8ECgfvAK8}iq=-OVVnyiy@XRnh4vDZn0*y|N2^{VN51xmeo zuf9HZM7D~ZQmDw-BZ0;pC6bzs5(%H9L{igHBH?zFNNPGtBo%SbgaFD>B0F`I$W9$4 zvQtNi?9@>rfpwHfARVQu-BQ)AqLag}KHF74cGZtv^c-yrLJ;?k5oSRtnjH&_*5u-q%taXRfvJYQ@vlI-mg&fsA!Dc zi8V`@(;4~LDHX$vc*O6-#w!*YhbQA_bV<^;O1&@DLaD1-;ajcxt5$ebt9sJrm%5w^ zKBubhRP~*TK2Ak{r=pKjwc}LuaVq*a6@8qFK2C+7Q{m^-{VMv@Df-l@{_9l#b*le5 z)qkDpzfSdEr~0o`{nx4f>s0?z%1d2R%JEeFOKHbv)qlO}zh3oUullc7{nxAh>s9~t zs{eY`ztk3`E~zc>RQ*eBfzJwmsebWU;V;#1sY|L~JXQZv{o=Fgzd`lip!%2U7r(3i z8x;Nx3jYSxe}kfbgX+IQ;oqS8Z&3KV6#g#Nzf0loQvJJB|1QTL*zr{TyHx)!)xS&i->CX;EREeQ8U3huNN#Ray*H}f8&&U(s`p0Kd!y)`Vn^oh zA0C{>){T2|h?+psFY&6q#32yF(-D8nGof_Yu+U8L`>}|j_&h9}&TT+WKv zacp2rxvc|;*RZ;#C%p0pDWLWeDWG^Nx=O*rXTf;(QfZO!6hmY$l?oltig;|N!1Kk{ z2+;sLUK0cHpn)h%#^Wo2)KH?Ba>(*z0+B(L69xY2g8-_ux+Km$G2xw=9#^03@#6D< zcSg89cDppRcDrH&tOFPHiS&r13GfNZB+>JQvmB={9iAuo6e zj>J=PU`46?y`oh9UQr>*g4DqR!pd^HW&hs&2{aZZWtAmx3}m@Nl;f4>Uo?PPQEI}7l`AbfE zNxG~>Zi^f3x^=&9-LE^SUxZV@Yev6rQ@?5^NUsaGxyX(2fy?ag+ogMSmikK$f2rJG zs`Qtt{iQm8sli|J<5K5uug>3Ioxi<0YEMl>fgj*mV4Cd#+(89yVqmr>`@sAR?aho>Up4C6% zP*L_FOVo#`M}3HTvJX*|eTa%eEs2uo!>juc1?qzest+p4K4gjd5cQ}JQBU?Ein0$; zQS?EjIQLXhKO(9Uu<1MOl|Jlz?1+s@=Qi*)RHyzLs#8EVFy@sM76pQg3JNkRO2}l1 zAQSZnGEq-LCW;a=QBgofC6iL7k7lJzpEYDuR*+FqLI%Vp#Mp}hK}H1y85JdDvP6)H zdIXuMCm|C>37M!UAfu8AGWuwSj6Q3~sH`BP;sWo)zr5?y^Os12A`^a^M~DxzzNV87Hb+Z~D#LFa1_x`prxi zI4&i+O;I-WN1ye3q8##DwQ7@oGt+`TJ50ZsY5f1ScP8LfRo5Qh``nP>5;BR12pB^Q zh%!_W5eFjm;aIg6hdMn6v_4Cf_o`OZ_VdM=XIrFJkvdRCpn{5)DvekXB4|J+Q4n(x zLkKa(7%=8VMECoxb?&+M+;E9Q`}$tLujhRKz4zJkxb`|{t#i)sPQiE@?PvS( zz`xY~4EGK8S3JJ`wRf+vJgJ^yJb7A;o9ETIAMhT)J(d64cs#l0>%Kf|UWEIVNOxm- zn#-TMc?x?p?qedy;O1#8Zl1@g)X$d@dZr7d+@bLgz$_(|AK#BDZ4yMywf0)$9Y5yO zu_kZ)CD&e!94`ZZL(BQrIdQ&9miWzL7hQ76c)mR*)YV*n*=0YOU~U!)WhTk!n91Y+ z?MIiGX+jyybfLs%CIsSYGgo#O^W0A*?E6JigDn5D0 zMlC+2n0p~Fwa8P8G5MxAW*(-e5?3zpz(A(S03d4}Mh_p4G;}P|&MS~FUXSEZB%ITb zTRw@5r4pG+HS=mCa=b?7(M~@Lq?QrMia&ga4A@3$knUnvp4$JIR$ZhOx(UXZa?SS(E)M$%(%TE zZg2AI(6u0L$K!P!!5YXkw;<(s5P9E2D)D=m|7jg(FBZ9)_nL0*DH z$Cu*lN&X`eqa|tOHfdxzNLKnIRXG@m$`GU}hapKh0x8N-tW;}mLB@UvZ?}wz%g6%> zd1vzR@ywH7BhkK>x$?M~f!u2*Qm-eGz%4-v6GR%&OnYj7a8hWB%g01_1uWWbCcbStg{X|X9H5q&ylNrO&J%IrwrNB zK;%k;ktrRDJZU(xq>+(w`k)zIgaK$198E8r!Fm{vRQ)bw{xetyitbqoT5y?UB zb)v@~RU%R3UnhBIWW0{BkyCA={aO(r6 zpO|ZrY_9e;a^-og<~pRDYrJ>4iXdYfjl^>;->lD!WFT+*F4E68y%<+rki8v`By^p( ziK|THaQ}i-^eyi_uCkEHjX^^Cwzrw9Y~*t%AT3?*z0WM4>^*^bAAbz->~&rhtu0h7 zjC|~L+84*8C2=~j%2+XZP?KKJ6OXU5--vmrnkTAxCZ;9MJ@nIDq_IjBphWVOcOf=j zN+^S`-*p#%$r@% zyS(4xx=H<70zW%8;gVYWDV8N%?C|zhP4TY!c~Hz;*`vva9pConl+#r~M|?tBe* zy5e4=#BZ+GQ-Q{f=;PdhwEr&jV)=)N3}-ph&hWVBsQ zL(}C|;MfUHOV<6U$=-b3$W3pyX$(D(QdU5}5^^Y{cEkN+0Rh;D~NuOos^M;7`VUD4&p zM~`DKbU5}we`7y%H}*$wqaQjO{n6K8PQpFpsq8)%N|r{hPmBzu90u*Je69*PBhZlE z_-ks_3iuK#m_}ou)6^EKCGMIOvm8J28FQl1vGYsXVOsZ1;9*Ugf5bY6Jxw!hH!I;kr(_ z1mOqHp|l9A=|Xany|EYj-i6fL?<>)AX=cADM|Ycly0X9c$DjWzJvOYF#CE>!0{#Za-NEFc~3_Q z_oSOce)}@&<5PGe<%{5cChv)xp|qYRC#=<@T;LLN%YhchIVv>d;EROvGmmpcpD50Y z2Hd9V5|JhsS|0Fdaf${Nf-Vpyt1FuvWDnuq&YUB6eyEbl`V&+3@NAI5{hz<1$PVqH z5jjZKhxb6|BbaXW2l_&h&PI2TuJY}jk8nE5l+ZZpjK`CE%%i!-3EyKDv(7lU#}qrb z$K1{5$EeSmUh>MGDgMcifAV9)yTmtM&K;Dbk-MKRDXA^jlHWMsA6d|zo<_cDK9o6C z9xrXAZ+EHj?aa7;cB6ltGuUK8qHInrea{li9eY3?_gfcxOED`L;d9_Ko;M5G*V-fPJbr`_lmSrD5o0ma`9?%KmdM`jq4BRp?4yk6vU2I*`9& zUQM&p(O{g5w&DWx606WbTn*n{1HavX9$~B92|36_E3gO+z`khv4MekVI9hz8;fYU! z-#pK|82!5O=+fPQ-rQ|y$W4Yne+cci+1&fghqvqHJ%)L(nrEwdjGDzE^J;aUE~dF( z-9J+ESoL{O-8ZZGJvGl#^C&gX^Jb9$;p#3?b8j_I3Az0|_fwxtHT_!c>t#~nJ#gjL z_7%6Cs_s1X-{Nh>Ctuxni@%w~|2nPtrJ9<`sK0$d(+*R!N61~OY1`CnQgasT&e}d2 zCri!S)wF7M71L;Z`ulleUZ}OzJQMYl{?wXVzYqP|Y8$B`IiS5Mah}vX{eI|f+wl2! z_4j+vucsf{OJj!oDNB0eU@?tT_aSQb;7-Ka9^MM=4GCQ;dHSXwAI;;|AgvvwIZUGW zJSb!-dfG;J$6oMqcd?qLaUKrmTnTT#i1P^ewPmcAjcD7B6_4^6uF{;CStmq({ za(Jwx&1m>6zBwV@DC9 za1WRQrh-Sn4DckF2c8ED!D8?lSP9mFjbJmV2TfoHXa`?HPBK6g@O;VRd6Or*dIPki$7#bEg(5(Vc)%V?UuMHJ+O2Fmu=K{erSab9ZzP_n}j{@0kJL z`G2xU(5_yt5p$%P7pgfz%`!2~BkI0N&C}KAesym}a`VPf&9o zHTPEY6gBr!bE=w!YG$jsubNqE9;jxKntrXcTr)#_%x7*tYOZn2B=tGn?Tt@=b>FS2 zUQn~2nmyFN!j%!{X))ue8r1(ojWa||zx3PHZ8da@%P0P)>Juu_-l#s>UaR?AzjcSG z{~%5Kg}VE>f#k3>>2Gt@{c@rv9&g-~@}`V|x*o&Kkvo!o%_7djl%5V#8hW_W(BVoq zM=F&(295M5%&|%(N5PpcH04SqkE6UU@%JWpXF|CjD2UuAa1UwVat!wg%ulW5p3IRN zr<@s^cs4`-ZSg9Y$Hj2CmUlRiV{lizle{wY$;6pFX@N_%cS`Q85KM`~O#cPuO!CT; zXF)v47|PmVU*I{0e39rpc-Jf7$gLI1ZSCD+^45U3&r(&pgV$%*jFQqND=uOFoUWaZuy;pq!;)2v)-Dl_Ix>Mjxhp%b*q zt5tJ#!jvaZzu?K!Kli79?oYwqsq;U+n|^(FB4$yu+-KMacnUryazkWFWI^T>&Z(I* zGZ$s9%&f_5%<7#rkl(u2WSs}bXWf`}Th`31xmmT@+1Vx8XJlWLb3;x=&g7hFIrDQG zb9P0eIlDM3aw?+5(X!}>=xFS*(JP`8qLZRiqmMFSbdtZG*(Lc6 z`8&x!c}~-krcv57zZ5AcURp6F6-Osg@}$g}IX5J*GG}sT7&QgCnKhb&=9ASshc+gW zv#X#7?I_L~80E++&nhp-6;shSSbe3QyxurvG^os0~ z=p^aK=+pp`dqHu*z=9D4CupN+z##lcY?=A`#6{Zo&Yn!EHE4Vf%H#; zIbbe$3e1Ctc$T+w=i~kpcpkg}7Jy3dB4sTEFM+>+#gwsxysEHY#a@cN4EuHBE(dRb zRbUOE*UVdBJ$MJa3u53s+Veix0=9xy+We{MX1lr;+YRJ{LU4fl-1Y+px+ZwECVLP# z7z_eKz|pSRjw0T1xJSDU_Pegm@~1jWzuA-UI|Y0XoDRMZe&E{dS%m$NJTJh$2uuf$ zff}}W$*o~Cg1e!q$*a2EW8)ye#GUE*JKnBPJ*&qsXK^`aoMW8$A;hMajpcm*3 z`hsFm0`6xPKS7+CU>2ASm^@U9?@gf*BVw~MeEIIAMJ+8pV2nxn}7hi;QOAKwYY zo9LRE*}2T@V&1qe=FY2t^ifUUNNKI4Z!=xUZ4-59!KaQiuMsChYc>|&71V4VA(IK2 zO#E92D{?Eftnq$Y!@$zW>IlTt+T z$;h$xiriLe-bT$oBK~2-|AP0*3wdumLb?H@JC1b6k!}EUJD;>8p(jPIo!I-Drz!6l zFprX+<(~3G@R8|3tTJs!8+q50H+3Y|M7M#E?xrj0*ZA$GCbXM;+Q>)xtTdEQ8LC3gnP-1aNFtkb!Mdd%pC0&@f^D+^sSuInt0DX!%V^dcf@%JJPaNIj}q@? z!d?Mu34f0??}II1D`;@LpaSK#*u7*+K&jhq%fJ9I5F7#qgQ4y-d#GDv4>K8d74km8p1!;2??jjQvV`iuVC)fGj}SPH$9mf zm5hB)#V^@Kt(EFaC7w8T8f?~Ij zS-z0g&Zf1q?cr{-JpvpFMiYKEIG6C3uwMqR;9dfj6ZZ|`tikV109V4EB>R!^-vY$evS2&&{UiX47-C>ABfF-7IypOqrWw27*JuFfiOz(bDOx?`m2*n=z`U z#V^w03b>Nxa3wLgk{Db`%$!8}@A1u!GjWdv6nVdrBPU>9QdbXAOe6(e88$X7A)(;4~c(6?&nTQ&5p8v0fZ zeXEAPRkH@FnH3exiVAxyd5j{Da{NZSS#UVZ?HK$R1880~G_M+(R}IaphUQhF&ZCYOaD5S&4ju!K6XzwuUk0xbX9;+f^vl5OU^!*4p}e(}_a^o_?6u6H(|ery&3y`>{{$C*mc-jvFow7VK-nmQjaFk3|hbr& zJNSY+eu?ee95|tvXR$r(2zCZ`7wk;zEbMIT9PB7|SL|HuZrFL)`Pc>6h1f;ddtrCS z-rH3}@2jEr)zJHD=zTTxz8ZR8&1$J&wN$WLDp)NQ-V`^>`wh4cFps^d*iVqhOfU<~ z2Fy)3s+h;zgrkbVQN`e>VsKP3II0*NRSb?Q21gZxql&>%#o(x7a8xlksu&zq42~)W zM-_vkiosFE;HYA7R53WJ7#vj$jwW8Gi zjD7Au-EFwKxm8+np|{EuL4*53gZn~*o1npcp~3CmThQpYO*Ztm9s1km)xn)?g+A9) z#y0E*{2P(q3oXuolD9#RTcF4Fa=*nBL%ElTnsIJpoYFTE-b#2IrEK87tc_AyiMtUh z-^AC5#*y03CAf2IBea>&cGHEBruaRb_%`9&oJbSg?KNwz{@q?Ow4QX$l-oimtzws1 zPao%*e0HHiFb?kVNOq-_(Arh(Evw0W4Or_QAw?s#l>5R~_M=*@X%|wo6SIz3lAqjL zGJ>HRHj6KH-a>BvzSPXV)Xu(C!yV)nYO+?TT)JLh_@ zo_$F6r3PyK0sf8LRm&U*@@ywo8!;rbju06=KfUbGL5N7uPi5xvyoIhw3x)QOxh&JUJgj>=WUyig~Vl8nMsdS^9x|-RUxT za{2G!FuvpTBc8KQdLd2cq`_)^sE`mFvg)k?b?y|mBKd;8Kj^DDH|teK3w zKf~N>Gi|1s!grtY`7%`@lF{GsRR6nX8FK$0nm72C(nWm5Xq+9#_mv*CkD7Wk(0jr+nIhzxkBH`Jcb*MJVQ7w{dR zBY8^BX)luZ574dR%>#R}ymMeLMf$MBUWV@UQd@z>(t3L<`pzHPUmCC1N*T%gxqA<% zj}Ju7(B?L{PhGRy3EJEO_l%o|tJ$?P`@Z49S~BjFa7uENT$|lTnqxb&?`s_HUDq0q zFA`!sxb|~ub9IzJKCZ?!iC+*Sot+GYACDiJw%*md8{Jk~T`S(?*+deiX0q<-ufuV7ce8J$J!Fh_KWKlw^sv+f zY;vnPYq0CNi!x5AhSZTBVKhHY){LEl_9U;ls&RKQe$V21l8|fNeVkj}a{6^Ses%6u zDc!MeIp`Ai@$n-$K7kLh_Rxl8jIZm`v1_9R@%~PxgCph$`^$U{g(qfU((l{3I?jop z#o^xbb9Vos{rv{@`ivPV^KK<`a+A9m7h@5wt)$Qxx;i@6jCI7kmlnCrn9Oy}S=WrZ zWW>X*4d&x+t@dX}$NZDmL2G=UV3z4hYK{A~GU9UH;kHrgI=2l=!KN=_2W_tzfWX7`z~tD9A!0#-C2(5!~B&IgasoO*a?4GS6W`+ zr z#HlAm3#U+pWTyA3JEV*#04NCdeu7^SS!fVLrsuION;V1sU@fuw^dJ zcazzVUgty?$5l!xa_9{A$E7*wL-J_Vvmr6B8=y@*eb5v->)a=rJjKvmO4<{rgvpj` zx^FSoDcS2qP{-Xv5M@f8J1j~%vCsoWJss3frO6a-b?HO*gdf`5-IQ{w`Qpc_jDZOya=;Ref@Fh=f@6u zI$ScbIQ{UBrp$YClF@F4PnIKDu3i$-&Pw>Ro2_evbr<*k+LlsOS*?}nlIUvQZ6{0@ zlbXmn6h7;Pj^WTF?uS@`bsa;}U%OSlf6z~iVu!J!)pN)(?$5lSUv%!Y;G3W->2go5 zjMPxS1i!~6WVaHjyUxFF+{3BmkPCbb{nXA*!W@Un3VlqO1*xMLa8a!5G&CxadolAe zJ8>0v>~UrVGp-<ek?5b@)}qg;ORIx*DzlpPP=zVJjDzG59NObTU*QB(kKNm=>D$~> z@to?zInk5xv2yQq$Vd7vz8-=y(b+8tL7D<@S6Iro)XkBXl5`T}aYmAo_tVhXR zdLewR6enIApJPesA(Ege=q=`XN^l(Hj{=vydFs+T@a|ymho(XJkT)};c*tAxa`@j9 z7grSNZ4|i}PuP%#Cf{e(v6cuNJ$a@hbD)oYRlH37N-@hg`*RNAxu^e4@#Gi9!|63a zic!K<-xQzJi}dBS2n~${0pT}Z~Ti&XZvj=kH19VT9eO=Bzw4zV^OlIV_LE6zD zPic*R4#PbRpPmWG8&F|Hd3GXYO3!pe22Z%cklykk@x#XuMnj&em2zg|66BC`;7+EL z{*F?s08(Z*`aVD&qYy?uoQ0r}7NtXX)^rcrC|{31JORnyAYB}QbaE&zX}|Pq|Fn5X z8zoH2m9k{U4&i!;rt%H>>ipmT@MnYYRmBwU_kPf)Vh4VK9rU8uK`#b9C_NQGdQAFD z+8Ul6U(db!Oi7(NnrUK$gOLu~GBO1XrJt8NncqN`^3*Y z!tyA!R|1yMFjCi0>Kc=8xr8Bg@ee68jNVYNVhsw`fgdkvihqD``QlE7^kxkErodxN z1QA-44uy=CyyGI{y?+9Jxstb}k@ib{gX@m@_-*W?T@|6aCV z52<1LBk0rJ?Vu-v9+aL6AU!7i)s;-cv*YWylYJBPQAgXK868LYtFAkaO8D9zVHsr~ zvhw`XAD8gx1oWf_Jj_4FA#y>H49Xa1!KJ1@lPmn&xOVS}EY{TtO7(?D=}P&+$NDnK zOjb)$8aW7_M5K|&5-xJczAA@2K;@7J>Q`&Z_*2YJ*x9e)9L^tMeva(10tw`Zzlj8L z8xqJ5IPX9X*-EbRb&Nm`$u~0Ma>#pC4mm~TkiStmyo?Lw=-k$d6SH*`jjD?J9@dp>oJikVCFAt^6IOf$wsNG_p*k zk^NN~IY6b62dOl2ph_bTR%zrRDvcbZ(#XO5qvSitA^A56@kYki3<|5X#Oe-^TIyHR3h=m+op4ey6;Y^&yAcvt+Z6S$DRkO79!riB>Ov UcB&*=asAauOpJNs%1_7t4;V*Dwg3PC diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-BoldIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-BoldIt.ttf deleted file mode 100644 index 6b3db698bb7e23b99f3e2ccd5ba1c182f38c0aeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123756 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 diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLightIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLightIt.ttf deleted file mode 100644 index a0eb86aca9e59246f2ceac56722abd18c32c6462..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125720 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%0A1^u+OpE*yq{p><`#k_67Du_J`U}w0~w_ zVt<5lxW3HJX+P6m(*8+%Mf<7tbM_T>C;MY|7yA=-H~UleRrY7>9`-eMFZ(*Xk9~vP z&;Fb}z`n^IWZz;BvA^b)L>__Y$*z@ck*$eE)>?iD}>_zr7_7eLi_A>i9dxiZodzJly zy~cit6S@9{y}^FP-emvEe$D=ky~X~Wz0H2Z-eLcTz03ZCy~lpb-edcJ{|@{PQVm-7l<$(`KAt9Ui9;kCSuZ{qcQGjHHq zcq8A+o4A`d^A_I9J-m%? zdj3g%1HX~q#6QJP@tbjS!dd=l?TgwMw14NP`De60(avaJ(*9KYjCPy$d44PZEI-3P z$8Y1G=eP4e;Ai<4aDMP#@;~HX;(x^N;9utFw8ymX@~`ka`5*JU_@D5*`JeKy@;~GE z@UQWE`Pcb<{2Tm!{^$Gw{!RWM{}z9U{{?@T|0REf{}ul>|7-pz{|RG5AZo%)0xh7UAO2_*R{r3|Kot`|30`@%x(9riPqli*CBZ#)5GAin z@XBj)%ix#~vz#O2!$*?`L-$E7LsNe5Al6v?NrS;#YwMsFRa=MTr4?|z{sfN#h}l&F zZ1qThSfK#iBv0_|q~YLgf=8h-EU#9NtZ`UelDCBrNj@05Pudo&An9Q6R&b!w=~P!& za(n2FIgZiA*r2u3JBayx>$te6BF*aBV(paVkBf_?6SP^z@nP+f zZ%vxss;ZW6Rn=I#dm%g-J`RU2fe=8iE;0& zf7z7zo3&TM^qF8*E264vt-TVaPhR?D*%@(3?h7#^c_wr(p;jyC)ot>7jcTwOm$hG3 z=9iaUvT-n%N{zG2pg>-&yQFZqnWfKVyUbK9n>Bw+*rl3qRyE-zA?%Wm znC>q%-5(3xTlY#jkBdvv-k|Iy9S`10s_LY&R@NyhH#wJdW7c(Y$&~oqB|c~AQyw@G#%6c_o_ zqe^*XDQBgu#aSt9aaPLb&Pw&%C80U1Bv#I9iLJ9*m9MF^jtZk>JtQwac{w64$HYZ| zb~dXjo2A}4n&5|L`7KKWSs=7s?(xTpLX|ayWTCpAr6KOpfs@zo}x#_Bq__-=1 zH(eDHZ&!unrmI47(N!Voa#cv6t_lg%RUv`8DkM->g+$g>A(3=ds(LF`y^2pRr~2+x zaGVN`Q^9d6I8I5l%T;OhN-75AWk_D6g|{A*->#IG33-t{gLPVd^UKSuyd0L7L3tUG zm*e6>+^_UVLU0x0h^s&ZS3y{%$0-ezA9B;wW_aL)mJSVrqWZb=#j<;-xWPI zik=!pk2FS=o*L0mxT^PS)cZAxA2n^(OE5Ev?(~SfTp|s_5ph|136^&;ojEqM^oVgM z`CF&nmu8{Tvq{mrNx|Es=-Q;p$v(f*<5u{&Re856?^gVAEB?C`f844bx8jdm@yD(B z<5v7}EBf4uKDPl^@uykwr&+;oR`8n@{ALBeS;22s@S7F5=9aR|Q|1Uwl{aTNV6P1z(z9JXi2r75%M>{#FIQRq?-7!EaUcw<`Fpihhrx-=pAr z6#X6r-=pAr6nu}O-=pAr6nu|@FAaO8M;dlq6?~6^?@{nQ3Vxe{-&Se8R0{eragoy8 zrl7Ye=xqvmn}Xh^ptlL=6rqwdGInql3q;lSP7H`Q!&{M-)ne8K3Fckid7_0&?;Xw zU=GYE_Zc_R#~ujz*aI^LCUhq;K{<&D${Cp8*1!Y>6($2SVVDfegkv%=lS1AmI!uAq zGAwjs$rcW}AL}HR@iCuQvddj#oyIbW-)k8{REWhh>zk4fq=Gstq=MqA_$n0---X~g zD`k&_t7sx;r8MZc)-1)M4Ln~gzz`3xuI3wB3Lc1?nWgwi5H*@2h8*&KCYjiv?o$N) z>We_Ca#KZu*XNr$GCQrlJC};@LsLhD+v9Y~j@Ic^VxSxhXEp2|R*<|0)tlAQ-Z-nJ zeZjR>J|B|xR7?Betd{lySD`Ps3W>y3N?=W;kY{I2rF>pfBiT}`*iu{V)JLuuNv5`_ zsH&}iV<7Kq#Qjp``Iil$lwa>C^Cor(b)Xwz`OCb^IzsLu{VcrKGH-H+(Giq+m#TqA znKz{)=r-bKf?CVkJ}dP%yhWnSHjdc6i*uL0K^1{Xma@R|YFYl5prg7ms@ zo6EdtAGpjx*d7C-yE1s^3f@%*?`ng0n}T=E!MoPrU67XMV13QO`kI6FHB)_RAPV|` z&oa|!59l6L=%$25dlCl5XQ(ex`mP38Cx9&zO(>fURgR;O9CFc(@N~<(RvKCv^|)G$ z*IhyCTtVtwpe}KIW*l~_%xf7zb<$)^PtHyVlOb-%WYCQomeZ{?8S;)yhA2lSLzI&y zL);3*5x+{4Azl%t&~LyHHw1%j6b!nRFytM<5akGlC?{cvTM0uH6lO`>2^dob3~@s+ z=tjYyTM0wn5e!j|V2E-OhPah5L_qPYeRr9j znR#4ef+y}xb<%eOp16;AX27FoW_a}7fG6(hJ<%zFC(2ABp>-KVWZFA8Tt*_2GC2_X zqGW{dt})>)WI(R1vAH>{r7?U-!QZ`@_2yVB)3I{Iuy*wK`1T{LnK12__{XshLYa+! zgMVCm2kSme3*aBes!zVgu%1(Z3I9TN1oubT|I^;NfLB#rd3^74!%c1o36bD~m%NRs zB1Qy_5mRMSq>2pn5fK@!mO3p`zE&;x8pj7xYb{c$RHIqyk`k7@s<#NE>^~eY`VryGBKXQRueusb~0g}#uDav ztZMyKM@X$5sAamQ?}OW)TrRy!DSZ+Ynk(!T#v4(4#@VKL(#2OyMvuqauhB53sOy7=Nryx~l^tGViuOD>;ct`!btZj;$DGbjD)w=XvL2xla;#Fu4MZu7v#hz+db9f&z_? z6%-W=F1ReX=H3Zz3pTp*MCZV-4g6~Z{|V<8mIwaWz<)aMH@h};>>T((x{fEX2IA%h zv>d-c-&e01zx(XJcwe;_iQdl}C7QojF&f9Koc<5Z;}6k2-XH7a-J=?u`y<+#1)}Fr zoy{N9TABOM@67k+p_O?-^)f5b<~)F|<~(#E?Q25Nm!Q#cTAa4@KcX>OmQ!z&LzjbQ zjcN>BlEQCqG4_eJ8Z?pqY=} zs{yUoBWU23p^baqyk*`t@4$<8poiY2wDT$2XNX3%z~4Zhdu2O%S<%JLME^P;J?dlV zP}idQd=0JVMl_zA?G|*M@1p12ju!K;=+!=_jtkB+5ZzJ*dZj_=lq%6D4Mmq!6{}$k zc4CWAjx|9wqcDc`FbS>t40QhUSqDp?_)V;V?ItglK<_ouJBLsq`mfWya|sop1=}g_ z>W_6qBlZ{XLlgH>=*()+V6O6@{h0Cgm}}5xzT&;kne{$0SD@Kk?QP`D^Y)r6(Q>Zw z-ry{Tj_p)5o@+f;RV)vE+i7S&*LiPp)&bqy2sEMVz0I7((Zl@{TG3a%w>Zm3Cs&Jx z^fhk_X9eizzJ|7RgZDO6KGS;$ceb|}_e!sc-j=ErMhSi{>x&UsNt{KhfvlKfxJfto z311zuSL0TyJ5t@TxRx}xGft18ja9AyCz7wb3A6FCVwrqFMAGaIVl8tMgQpF}Vxt58LB#hm{bM!s@48qe?lrN&xHrTG;ZBVm zg*%OQ7Q#snHa%ihnnKq94Y8q`Vo0kL6?(NC_omoDiHr5e6^;|blHfY~Z-iD++CXej zs^FocX^Ffu_bS$s=zklqZCHeET1IC%Ii+8D@X;XT{hZJ>dTm#D&7PeONvmCs=hGo} zczcuPctfx8bp%r+do<;+x95b{tnB()hCL>{<}D#4c{{Uzlw)0U z6l>rFdL;h?9mTB3|L(Aifp%h~8V%fD?B=9L`)jz}754%)esQ~=8?m?%dz|TL`)6Pu za~t+Jx0|1&xzQ~1Gts<5k$0Op>}2;c8~0(6GZ*WbrOe23wZ2)&?5$>JTaUF(GxM^^ zY{rr!i3GKkRUYyzvEcbn^H=1j6jm}Z+rj2zOH+*f%t6@A9E`_oP+1|D<($qk# zV=AzW8Ds}z4xf~~k&it`M{GGtu;b{04aXtaZ*<3Y<8bUY`eCzi z1oj%xB+^5%>h6o+WI6Quq{vgwVUR;gIOCfb&_x$4w(?wVwF>wQE||k&pxxYj5jiIO zLg-53>5-Mj#fg+eE3qlztA5yVOeM!|kJW(nK^asID~4By z#8gH~$6GQvkug<9`8zs+;xj;T+0OEC{5$$77{!+2&B*Va)oZEZIoqBBY<0ZAmlKcBn~2 zt$I`nTt;aLcyS<6VIhZHB%B{QE)sj9Ko$+9O|>N=PZ7L4l+gl?1{Z=a5GSjvfD&X6 z;oi=iCwG3BlFIrMSN3rE4o@EUe{M&S9ooYp@@QEf-reobV6N34+6%?no86;zmG5qU zhI4VIw8c?-GM?OHR&$RNy~pg$I^)MZrugAK=6+Yci}|eSCVvbxy)Xan<=-{@WBKZD zaR()N_Z({E&FO=oshXg+D(81t>HPR$=NGJSexlgKVNo{m zG-D4hDyle~d;HiK?AsiS_9xOlBOr&x6>fda*xM zurCc|KRT6tXf*rJIC~K`l#{TOoQhTC%~(Lr#M-eQOU8$hxEI<*SS2pU0&y*J_h#hn z9as_i_EYQx3$O_+!~U-~wth!p*LMOod?T>e8v{ogkDc9R*wkHt{oD;$%H7UWg*jNd z%}1`Q^B%#iRrfA+zpw6h)SVo;ezSzl3cb>x?v0Tv^YzLd>bi2Sii9U=_#$=3s(YKd zuHKazK2_bp>V8w*D(h3DNaU6soUq-b;ei?+;xX=6wx-iyXV^e`=dP8MW|gL2sp)If z9j@-EOxUzY*z8kxsdqJH4$;^`b!X`HPwl=i4f98OEH0lSrR%Ad8MM=lr?$$vG1S(& zaWf5?cZBxNwaSfytMM7V9x2n_u2)=a%;{JOk2j;R6P{qcj%Dy=<_v6szh}r*>$cZq9@G`vUM9qOK{*L$g3s8@!klBB<0 zTpQOb8#VSQy^^PHaU|tlO}}2<6?%Q2x{EYrmAXb_A5nL;x?40&Qr%{CH>>MfTdU!D zn7>=INy9bbrq-uKK3c6;s>QVzX;@om7HhaH#XW>QLtLY|OoLvZt*(xPyJ83Fl{xCx zrI<4_U&F3dZe+U473=!z%KuE$xN@}3_FS#&Qtj7LjlEynDJ}GPzT2OF!Wg*e$xw>i zaU5ora2%)nbBOZHH-9;7ug!oQu zO6WLhb z?~Xf)lf`=}KXdp}lRJW1q$aJ+rAo{z*qWFZzrJ8g8Vv<4@hBFS6vh{Zr4;yaN{=E@ zQBp?P^qRg5q355L^d$$r^h^$NZw*o4=a(mH)2NKs6f;amS@_YZmG07Y-!j^ zX-x=e6>Un?l}t>JWOP*931`OEg~GAQ6p?9rBh08E1h4u zqI46__P@ncN&2G4*$fu)qa48IBg&-lynpT~a@yaZkb zuYfgR9e5RN0I!2Lz?<`#z7Ea=XMukP-vH-;^C@o}b&V%H0n7u8m1Uf`BPz2^ z;1#fj^44-~9sYX!SMguN-+m;Z_pRq z1)u>B8t|Y24;t{G0S_AR9tF^Vw*Wj2eghi8Z^0AbcL3V(pbhUS0Bv~ChW7^meR$A^ zw;0NP2K)&;3zmTAz*4X*p!P&BT>y?H5sdGqu-Kd%dfH7GX0%?I%&z1(Z1@C`Ur&+OlL&j;|@nONwc! zCQ221frBWq18!5KHS~&>^95|_r>WF4>4%hA9ki%Yb2TEbmIWnBJ1f(@m-2h@kMv=* z^aRQ|ks7M-tLgih$g}6u-f@&Tp8T_rweKaa9^41+2XjgHEOF0)wZub{%*&;=cdFj@ z1@Iv|5R`)oa11_NfyR;C*5am?co{2H!}1f#$iU^Ey5>L_O%WnPd<+UE!_1ApfF za`Hcq{{sGt_$%;VqMViJ2f8vJhk(OCchD0Y4*Gz8sYb6qX$IgA#6JSR9REoC3jD>U z+lev}nPK>vs*lLXruSg4A4r!Cj zX-E-5FEOXBvE?cB)&kk%-lq*i z*~4(bFh)jNC2Oae{+tYCP2LD@0yl$Oz;tjcm`nUp{3fs*9tc0P@G}cPv+y%$vkBU4 zg7%u}O|v~73EQ;9zp)Dh2KWuFDl5ncvfBK~E-o&-M^UM_rGc)0Ly;oZWwg=Y)D z7G5oUx`mNxW@MTfnPx_&nWuOC>GeQbR{<))5a4>+$SO?I+h*n<8T7b`UEF6E_u0jL zc5&aFPW&kRGr9L1i+?t_k@Po#o53w$I=B`5h_YvcpM$%=-Cz#52i!}1J-83t59Tt` zzoe`O!F=!#XaK(g4})KWN5G@tF|YtE1W$se!0*A+U=dhKdBU}u@SzoEBFPT#n-{1T znlUTzU&3FB|1$n6{8#YT04RkW-)G17+3|gLe4icPH|&h;`o3XjWasxy68|0ick!Vc z=(N_dvmpWaJOdIbz~`BUNCLiPmqQxxb5KJg)X)g0O2VmN67aLQnX!>N)`N)k!Ix3yejUf^6wI9C$Rm4tI8;ao{Ombh;acQ*bx_>Qs~SwFQ% z4nC5DkL2JZIr#QL(lF)`s%wPm8d+ya)>)EumV^SEpuQv$g%1TLktlqqFo{IrLy1Ww z3Lk1rB2oBIWD<$Ohbogu6h4%hM56Ga&Lk3r4~1gGg#RA?R{U-F+wpgR7O)fS0(-z- z;DdeOZ?y9>{1lXJSgRJ_!;j(T;dj7~BINB;FsZdg7bQ#+^+QaCC&*?^H>Gy zvM=fgz?<1;^v;Q%UrJ~VW3dhpgOny$;5O_{E$mAz;aygc_7%O7l>07C+Y+Q@WXS_( z(wG8DXL>oc2sy^aDN!YXxXgtNC_?`kAS*P8Pp`P?06o|j#k z(D)gQ8qa%>b@HL&&@M-;Xyh$QtPGBPo?{-tQ%HG#QV~y1kKuV_r9LS>1={Yx^Ws`k zk3MIx)nXek2r>7?>37vW@Bwt zgZ^OwcBH>UBYi$Py|uhU=~a%YW&_7G-jwsYxf;#h8`!(NiPhS*W*hH6x<#K*&rn;d zA7O3vSFE|PxH5NOb7jq)yj>~J%t8|y=S@omw#3Y~rRe|ad6s>ec>$}c^UW&W5H!Ig zc`MMRW-B&Tb9oEU1NH&4UEaxK-shb>4dw%RD-ZhDNA06#Cze(V%!j;}r_t=<%{)(- z-RQd)nmxRoXS?|bP4^D0xwy0AjYm5<%F%r9;>|~UI4XFD&R*Vt1V_f!Yahqa_HSN= z9mG3s2HWwx~J>N zo3Y~kfT!%pfYW~U!k3G4(ZBn0tIVTyf3kH%C}3Vx`^C&V1^N6O|f5fmNy zN$#K|%8Nwo7o-hxq|;&ppeM$VO=-3rv7mW4XvgW_mduk;i%6}D)c8~ z*o;g6B{o`iYLAWxZE)$Lxx;Xf-<6Z5<7m6dn{G>(tF<3Z-#SjtsU_V9tx=wy1wVM>Ncjs^)e6gbM=Tzt8$JlF>V|*O(u_K|H4jNb!fR+G|9M&CM)=bv!E0w zYhPwa=15i}KCKM;pIrlIky6s71wC?ocKO{{WO8RhVXn}R#z?!UnL1iul`Gj}8ur1J zqpM8X-k`k@F1ndeGqWXb6M2`Br*-Z&&&RYG(@sS0wgedpnH8CPxRV=s;a#~3i>xFaah**@HCNiU zud%jdrO6n>75SCvx!hCBYHht^{Za zmwPO-(qS*e-e1W*f`sH(u7?W;Zb*^ZdhR;Yk<~7gsXqwyN~e%O2kws|KiAX9g{;`f zb@nA_z25a->W;>>6_%N1jA>)YE!s-i_H|aLl%hRtYjjDI8HYBC%A|0iz||c*orNbD zu5Y-0_DH4Ev=PWXBAHsF*(7aHzgqzs8SW9$l2na0H5>5c>~vqKluvYARSs^yl(61xU-CF)=MGbSk+w*lHhLsGhK_|Bm#}n6 z9|;Ha0iA5iT-6ZvQfMd!rmqgU4P6CO-5`M z%F#m8GaSxz)ORVe-Eekg##+P8u*|Z9tUPzfo6k+w?1cQJw`pqyX4m_VKkKPYaC7Wt zBv+db=Kr~$|LDc@&FCQ|_JgiFcrQX3;ZH)s1!X+>_pgTbcY5>WGxHO!Y=cwhXLeUP z7sx;RqHngB8~<-BOqIL~?{{TJp;G5&jWB*A8i6?q4{j`}^TYh9f8= z6+%W##!B8@5~YsM6V8lHI7Y2~*V1rQKd;|yM9JHb#$Pe8cw|E zrFyAes*mcW2B4RkfRueX$MJj(<9q0$uHzWSKVWX7>#CQkQ@zv# z)l2KgP?+jz^s`+;_9FK-)=Hv!C0?bPk6o%)Gtr)H{l>Q2>8 z%~I{u&r~~gudP8l^}K4QUQ+GUTk_2czJ?*%srOVnwNOTV2XnO0skd8PO-U-t3j{{lO% BAN>FT diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-It.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-It.ttf deleted file mode 100644 index fcc95fc7cd454174de4202d9d802abae865a2f9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124668 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 RN}?Aooce;`)ssG%`rneY&pZGC diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Light.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Light.ttf deleted file mode 100644 index 9cae13c97b8d31c42f812b79c6ca4e89e3b51945..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121124 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

e 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 diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-LightIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-LightIt.ttf deleted file mode 100644 index 2ed7842840589bf89ff944fc1ced2c68dd7e8d95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125480 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

pos;RqvVr!kfWW$`I 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

(TVgOyhWEB^(nD>H*C#)f8O%zgWrp{ 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

Le$ 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 SCDW4eW0whi@2b!K?SB9b?+04| diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-SemiboldIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-SemiboldIt.ttf deleted file mode 100644 index 6ceaa885f3145d26e07141d6d4ad3c18c3b9d80c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123840 zcmdqK34D~*)jxjkGm}jAZDulAC$l6o*|$kDStrS4Ur9m|5)wjy5JD2dzKDRx4k93; zQcEpWt5(sv;7%!0^tD#4wU)Y2%c9n*ueH9`y1>l;d!J=8NhU}?|KI!heLg?*=1FFr z=iYP9J?GqW&pG!zgc3qR@Iy|By?kcXO$mpx2))#fPg|<1+na_TQvVr$-;2LvYAUO$ z%f78RN9f^0`1@>4%Z!<4Z!4@P^!_&pDcVvqv%}7vIB*-GKN=+@Xkf<7jO?B}Zh4## zx(oOBFIX~f*(bfP?7??m5aM-q(Y%$*oK7M`e|z!0&!W-m2Jc>3_5vZ%EriCW4lSHF zAb))31w0>s@AHQ6fnvAUFY$LJ{*E77vTEI(|J`N8-yaha=smi0!Mq#aDY%;u)ysr< z?^rT#-7?utq!Zr{;eOrNyd?{tus!`ZLQ6LgQgZLIr7Kq%t9*gaMjggnOc*VwU&+Te zZTYXc!Nva~{xbAS$Q$2n4U?|U6vtoW%VZ}3wGZLgr}&5GWN$nE0V3Xx@3+gBkpZF< zz7l@Q%K3ZjWF}GYpRgw>KVF$|2a(awxh~>G2)Bppa{iMvuq&ygeI%Re@TtGIOeUB4 za&r8^`e3l~|H>=vRYXs8-*epOPHzSY4b>5PEBlgu%I(8NM|`*)_{lzL!jIqJY9Xog zRkDHpH&N5ifoU=+;QC20^~Yy<#vX9j$yq0P?c@L3{SIQ`uD zmC%R}uHWG^3)&*Ic(fq?e)jC=Bpof2Zx4}PSuIKBLY*&hZA8aqVBB6@Wkg5+j%yeG z-h|&n(cX1_&sF1k0iXX7Z7tePQpj1wYZWPk~Did67E;ScXVGeUhhhCTMS@zu@tElQxj~ zxIdE)k~TU39D^v~A^=Y@#`Wj#nN7#YBXl0I;`vDKJF-j`Nrq%TBpL8Hc)By%PinGU z=llFzU>?|9NR6KdHWy;!#z?Yj9@t#CHNaKI?R0*}&jp(gvGH?Jfj(GLt8_t1OT#;pdall+CN#RaQU>WeNBkGROE{xH{i; z{S7%}vcTlg@%0@dlfxYrOJu&14I5&C8Y~-;gn0&fTw!o_k3dbkbQK zj}XAU3*)6=JaOJ7I=b+@MmSvaDA7m4SHLTqpOY~X%Ax|n2=W6s|ZCbyrF z7HW4oAghbemXJG0KRHU;A@^s{E|LwTgNBn<@-9Aqmo$?N&PVb2`;c=Lu3w`qMmvG_ zE;&YQxHpm(Vl~2|hh`$g`3c%Zv~Tb?R&`Q{-#^2(5iJIdqWR#n6S(3#Qi0ZjzkiIz zu3OPIqwPl0i5;Jp(h5>XO~gw6 zK#HiIMDY3@I@WcSWI^J6@hbA|KPFutWxAi&zmxdY#lJjHI=|#5UZ0r4ixThol05LB zzr<6MuM&?*e8uzYUdYO1o$-JA?`zd5)7&TVG!1oLhOYS1#oH3E{wG%^GwlAWT_?+o zBx65tmFPR|^>Z-k=UDT8PmD57Xp+3Z7P$<&Wf9sE+JoO;Cp~CEv;b@L%cN0$JM=h{ zEp`vnh2A8RbURb%QZf(nl1UfA7Qnhm7m^{Yp|_&-p>>jflIzJAq>v8do~6#e(=qVK zAZ(xkv_;PM`RhXG7q~YXpMQk*KAw@0FPx`o70Cg-MQCh2_d;VfRV-SV_bd)z-^z5vE{n!GokTKa5oA=RC-G>>G9{VAwGt&-4A&xFwIqsb z#{3?JuKge9>*zC+$C0i7W|Gf2h>7;{c2_d{jvtd<^GG(C>>XVE?v+oRMM>tq^m^aoyxz%PG=t^1zyzv(xa)AyYJ z1DaasTd?aSTbJ?cxJ~@AU=M?j1e>^9yiefkMWl-UnYW!M-uD*lQ=va1%O<_#8LR`( zkSy|y^BuHj!NY;z%h}*P2l&wexH$g0kf^|yrD%R=9Qe`_wqrZY(#27(L*%kYas8NV23|vC6V0M^ zbRpeDH`D#}ApIGAl%Au1!=5UdvvL(&E7#4<;~wRn;GW@5aKGkW<^IB5!X7O^7A#ZB zqGj>2L|M8lOLi)@BDOBJDYhlHEw(GRC-z9}(b(s;!CJjGL7Sp2($;AgXqRfYYxiq! z)!w1KOZ%-(p;POkbXuK3XVPWrEV@EnrEa)~=nc9o25u?$aLRF+B=Q!*mh47@dyCG+S2y zOqc0a={D+a7BRg~_mJ)}VEXI?OlRtQ^an&tLxE|e3)2B$`gp=q2`3Ux0n^`_LPSi7 z)9JkAJPj^5={(_l-ubZeA?IDrTb!$%qt0Qc&1rN-IQ^Y+#}&sf9gjF3a{R*afa7k* z9gaheb&j=;)sB^pQO82ZfMc#>&XwPP(DXt52Q?p5e^B*-{e!X($fYZnE?v6y($-5i zUfOtR<)tN;=3MHyRCTH3QqiUSOWBvQF2-Msx)^a$b20p)@}l2G-;44K-(Ps+!s{1) zcj4s=zq#=Ag(oi@zwp?Fhc7&I;eiV+7n&|qU8uZJexdL}_=S-3e?7na{Mh-y^9#=} zINyJM&iU5!x#zX#qt9J9_r|%`&%JW)<#T7woj$kmT*7-B-z!xd6u26*`v3kvZ_bY) z3E|}>*$rXp^35<$%hmn~Ps(5^dqL_Iu#A0)AMqyvB#;D=U}&>YXgnpXYwRkpPmh2- z5k;b*Engk63LNhN6{9eOkq`a7Fgpj~rG9&F-#f}Ip8 zg4Qe{Hd0E;NI9{?2CpPl(3Ul%mei4Y(g16{i8PZLu*_RY8~jG?qytvUEYbxXJ)87k zb(ll?$XwD7yM~Y*&~dxTP2^T`nA}C~A$OB|$$jMKot1@L4Uy-Xfo@BR?a{$Otz`){tTNVs?=`x$DVF?gnl% zSwz-yE4ek?YPz4>Kt{1!A>;w_9J!G!AYr<(=u>=-unR%li@Ux4genBq|yen-zx?#}#k*c>84fH2Vzttn=C7bJ*t*pA$Z> z_d&sts zgCWm^ycP0EC>I(YS{T|Dx-axhm@2G3Y(?1Nurpzom4(Xn%KMb(l$TX8sxs9&)n3(6 z)pM$k)FJ9d^?LOK>UYBHc}Tk9C;%0 zi>UahuBZc1=c2xdmPc!&>!Wu>pNjr0CL*RjW>?IsF<-@|$Ig!35&Kl^ciL2KpY}fO zt6E1~dfaf_U2*4i0lFOBpzfgVW!-oBRQ+uIHvMz@4-7GeV#6}SorbrK#8_+`Ha=*4 zJ>DnY7QZe2R6;;PZNfpUPAXHOY1nkT=_S)=<}kC#TxjkxuQA_ge%1Vm`I|&-VrAl3 z;_Zo#Ccd2bS(0B;PEupivZMn^Cz9Sx=91HsyOQ@NpG^KDMVB%=Wmn4al+RKPshz32 zQje#RwA8fbw9RP`roEfarQ6asq@Tzj8PypFGTz8kW#(rt%RG>ID)XDHoUGogU0Kg% zeUY7+y(;_e?6)id7Q1De>Xj9RdqK}HBigSvW z6(1>nxr8e*m9&(MmK-d3s^qPbFKq!flP%xYXq#;tvaPXgvmLZOXgh8DxKv(hD9tNv zE8SLlZ|UQur%K-}{i4)S7G9QG)>bxDwy*5&vZu;kDf^(zQ665NTHaPZSiY(JNcr*d z)8!xARd&05nf-|UE&Jycx{At*6%~goPE@>E@pWZXWoBhx<&nzMm0wpSRt;Ajs(QKV ztLo(H`sy{+cU8Yx{YgzwO?}P2nlm-u)TY+<)$XZ1Ui)#Ks;;GOTiqjdZ`7;md+U$Z zf7Ia9U~A}V*wJvh!O>XQxTf)yCT&w=(~hP`n%-)TYHn%X)cjoYCo@blx@O!ym4A8&uRBch|WV{gYZ9p7}u zcMf#k-g$ABcGikn_s#me%dac3tGa7d*MnW>yH(xw-P^iPbbmcNefHSwd3)U~#wcx%5XBJ!>h!|)b*gSCO!0Cav7X~d{ zwQ$?QBMTo{cxvJ63%?u;8O$7VGsBLu5=yRhVEzvHSzvTE> z(Abu-FP1hgoxgPb(t}GMTzY;PSr)!5XPJFj%d){`o0pwl_T}=_<&DdSmTy~rVENt4 zpIiRw@(-4OwIX0e%!-^9_7$Tm_N{ne#oH_8D-A32SFT$5=*mx4rLNkv>gcNTtG-zs zu{wWs@9Mp)&#eAnO~9JWHJxiVtvR;l{MwkcU26}o{a{`Gx>f6*yDsRu=Iah#cXqvY z{owlNu2)?@aQ*QO@(q0(PHt3f?A!RvChev@o4&fC?}js*O`8vIzHjq$o8Q>{`Hg-z zCf?Y5-B!PC^R_#; zy}wNT;_VwG3ZGUSA*^#%SWyhf%uk1AJ%-`9*b9m>Doe%Cjx%2&90lQLnb?(}= z>#kkz?+)4>zq@dE%kI(L2X^1P`=#Aq?+M>iwr9njU3*^HbNQyQn-Xub-8B2AJvTjb z(cIH}j$0CMX})FiEsx%E z@|L&w|GqjHj#bDD76IY5a)+?1@P;iB%=RG`rQV;KWeFN3Rai2pv6M5$QQa1LVauiR z4k|C}a$IbFO&=+bE~_{h8^s;EGD_ReI@-^krN9^Bd?M z`a1u-KOxFeY6+$m{^y49(BX)z>)6k1y666}vHMvAJ{*Ieeh>e2G^`zBu^O#HvnVVW z-l8z_&1f|$l=vdv))d;7)EqW5zaoDbT2mPQ3T?O9ZOd&P%afL$fy#Ik|8O~T<_rzo zh9O|R`8yBN3)~lMuSgXpqrqFP(#n8PFg03DW^1@5J1;jUT?Rw}tpc9zs;9iiD3 zowfDzQ;IEZ%gXcOZB}DcM{OOOC&oX4JpYK?Bk+yDG5EgN*-RI5=U_n-4d4p1YPe99 zW=-L$HKl(@eEg?(+)tx#*E{~{`2GFEY~G#k;(kuJUkL{06y~td9P`V#-}Z)?J9qde z4>&%&-9UqA_I)F4{N;2jJShZnribn;}=3k;@9 z@Pa=As~2M^%z0L~Ne>BJsESQUG3pbB9xXA<&_~B*q?p?`qHhEF6IIiA=2u`0Y6!U$ z`llH)1m4y-zk)Tsi;b&s>#QwWmuZaBWdtzsG{zV#Z0zTp{q%P3CDxCET4*&rSnn7; zDjU3fC+mwNiID%lB9?(j?8M$=h9JsVm2t@*ntJaYZS1)_Ah{{M0WDzN;K^^UTlA}c zbLB%1^lVvl|LpCIme5x8Hdyh13zDofTJx+H8H6ir=d6`M-L}@H*N4uck5mRFTzPL6 zgY7H)coSpC62k7qe>_8iM!fO~@`fS^2>4CfNC20fnpc`TXLkF1pGc)8wlN{=t5Dm$ zDT9pxfr;4#Wiw{iN2X;b6zHlADLp)moL>R2KcjC0+(n|a8?8*{!ST`n3bhs}GOiD( zENm&RdnjaKcX~=*QEvOfwt4$3c{_$nmJH;#mShh$+p`i<)2d5aD{oAZD{InwM~Xo^ z#60L*z}FA5Mf66i-U^Y1{xVyvHfl9`D`>|8z2jd&w0vW8b4c@-KaKO!$mCYl&+F;U zj*ac@cSOt$ZjTb+{SNScg1+#l1TPP%QV)G7Dr3lMm9;s)H8(S*AbAEY5Bng+U}~6i zXyEz<`7JHwIk|BLnlt-I$gI|-H?g_3pwI6?g8=L%i3@ospm0GYDr{8H@`Bu3vcJkG zO-U*#0H0)48FDIyRI!b5H60szItCxvF{f&FUS?i(khZv%{-Ypo(^#Cbvt{nS^$Sk_ z3uM4Pj&Pyk+~@6ghd;T$f5xsM)dvfG_kGq-9iwCK(EvQWDJ8j1OB%^HutX%(R8LUM#rzXj-R=No8$Eg>nn(H%_PmD ztV4%wsya4mvFcb_P-ACa8m{I*zK->4VSTaKrO7zUiUv z>P&e?H4`!p`tLY>o1Vu^D!>BzTzx1SecRDRA7G8%+T?hv34Law&v%7Bt+}N%H-qMS zsWbT=AH1%oIzygW-Te?tBSD|Nn2V>l2SFe3th;tI+vF33H%O+qgOLX+GfAG5mm8mG z%t*3CX^lAK?Fb2!baT5=-QTPaws9{!$w;8IjltM(kxmj85*WXaSWl`Cok;)=%Tl=18Hod;; zmixENjkoy7vdSz~Yg;lRxZsLx&3_e{O$Mbdt9seSp|L$>qenV!*l#ROIrgJnA8dYb z+rfLy@%F~DIk#mcy*Ib3*?OC4gr|w~B~bShZXc)|j9IamO}Wr5O0!V`6GD0Feno)1 zD1LX~pL*8PzRlItZ^0SGwi?H+&pgBJyRw4GnGS@_!t+7U&{}3Y3Q`|Td2W{RB9}sO z1%XpwMV?r&tj$JO{b)mCOLOz}_45}zY%f{J?Q5tl>I#v^42&$M8;UF~j;QO?vBY40 zVe`PNdneQXN}gyiCO{ZBS{BUu>AWR{^@&COTkD%(NOdhKUL=lr~? z=397Nd06d$)rZ-m5~R?m{0uSRw(mZ8`tI`5WxIOY6S;lcHaz>MS$FU2oXy~1ct+w` zfA*waq37*Ly#i+O+Azmg#!F!rlc_3<+t>4G&ueV`mhK0yyY82Xcbjl`K5l)X$MJUw z#~R=WNt=RWDQrrMj4?>Tta}Gn0?+cnosDg|Cf#+R?-aEyU$c$UCC@QjPps=)5O-&n z<7~wNar_MuycU^WX^|O~dO$FmM`gLATSto>R|>g(j(=0%D=Vnk@s98e4Z<^6&p{n_ z?-pU2v7UYp+4&2;3j{~=DvMu9tV#>LF>J}~f}Y4qUEQpxuF=zTmgi=aR&SxtGnxx@ z7{znQbYXp3u!<>-vS1K|1)s@fx)px+mEINf6;(gMP8<3jNwRzGtb+;msyF=jW#=8rr(}29rE2 zun664zd2-Ky^bcK$MyT~E^@rZaOX%Nco+UVK_7d$SyM8RftkrbO=FvWy>o2S$()W2 z_VSL66#<8Cxc48dadpqG?q0|m`qH7p62RpL|1N`!SHUS1+Ze{ZjCs!tto+&bo=kh& zte(xC+`iV%_3Qpc8)~ciMObEuu%IXEHolT6By&0}G0_rGV4bAvMPTN7$0wXBYU*GR z{`~rcC0edT0_w{8nSu9f_6#v#@Az9-Ert={EC8Ge_@JRr1mGZISXdR9c>MQ=nQdL0 z+h)ITc3#^kwu+Wf+ErWH-FdWYdAQ@Blyf-H4<$aJogZii8>^HGE4L|w3d@*F1;oK^ z%CFcy&9=EY<));n1si);HdPf>r&-OZ)miD=7vDTmJS#6PCMhzxWd4lh{iXJt_*heP za%_#Y88@jP->xVd(`feI>e7B49mIq}02t7aQb9b@ zlND<-{ljEQF-vG0Ej}Dru2R?d-0nE(IDU_@vLx*&;BP~p&@*g*VzG*SvTZR{?8#cZ zG{HMeF0Tw7S>^cetgq?eV=?oTt79H=41LYRa|O@F<5}oXqm?qVkLnd5!4AhKVf2nb z$3~j1ET>=glskf8G$4xN9HNW3Gt6Spz*JVE&0QS$?6GJ4hUXN?dW(2^I{S%3*t2Lb z4^Q>i%oBGk)cFpcFBP6wFlKeP6-pswm zzN2P~hL+Dx^sS) zm#nFyykY6V{KUAN(*FDRyp*6TaHuO=`n+eJDZZ%>L!#es=D=>D6&*}4yivTj zFNfK7dh~q)Fhg(h5KA%&DbaWvO#1s)HCu`e$@T>c(lgSV?;AR?^_k*w)ApX#rpkg5 z5$9YUwrEg<@tlY)ua`7331=0(GsrNqPel0WP@VBaO(BmoeX8$~D>k6qvFD|7$L&1c zY~RlDu>F>YEk>fJTBXo?16RQuvs#4Bo45YH!PW+~<4-HqllmpdN21nukA`XX4UbSgR;;hMrC10xqnD!O?F0n zRAg~Tz?{&&mXTI^dy7}WjGoBG;MU>}$1uGeocpcQ#K{0-6#O~_*t0d3Ut(bZut^ux zv&J$`h;Vvr)_{7`{5kEJ73CxP2w7uGdGnFM_@WTm$-2A*eOB=t6aCZ?v}m-lHg7{u zU3dG|UnS@qkJUd_ymeM)Hs%aA74id43qC)Q89*3-4RT;BD+}K@lA@G%)vxlgjTHOX zvKs8%={IT`HyDhLS7>6ocWI;JF~(QuCxkl%UWN_HR(bcmNBDw~`PGr}$yzjkqvq_| zsMsWJlopf&-kY7-Gz`xMAXZ6~%+L|GsBjlbNJGPaI2?atdZIxU5vBDTZi!4lZwct_ z%0C`ZH3uZ7a>294JLU1>{DGHbbHJvC0t0XF8|jw6v+kwUqwW0>+-XPUhi^Lm_U^pv z06y=l2*xwOfT?vszbgPvZcfJPku_YXuP+xFKXV;df8{YhU$v~ouLWvS7|Vfq)AN`s zm^^9FCXjKQp7UpU$$Km3h4wR&ju!hAr`1-B6!{coRNLvNRjoZe8={jLX%m7OX{D<; z4*eA4U{wW$`Ee$U5ze~quN$8!*5Aa5;$^`AIsF*@c<{*xMm3X!cV-U!d~y50&$Y!p zY01U2Qv;Ut?0RCfcjs|>Y+G-B$+kK9#cb~W;k41q=!@4UR(L-}z=Vyg*Z@?M6$2W${o$ zm%TVWQ=jJJqYjAmF34HZnK8dD$DR-!u8S#bw$G|ANRN;54e<|FgvhjIsWqLs7!LfE zi}99lOPO>)6O?j-6I)sap+kFY+nLss&Rz)YWYpViRee<88*2 zbO!oi3+ZL_Guf8eR521IQ^*6-{cjj{Vj#!&ksBfxL{cw@n#ZLElX?ly=|FR419_`0 zc^F;^YVp6wjOHBdKZCenIuJYTLpgb-?~3_>l*-e5mkhkU*_X-{YNgLY^!#n~{E+KZ zRN?qGVotwiBIA+N3 znmQ;{8CR$d?ih*lmC1cF1J@5ZKFeNMrHdQ(%SzVLkG^TC2w5EU&6V%Fx?sPfPgpqg zB>EI=8)kT7#qbND@h^wc83B&>{uWw7yE|--2Rd*&XdVmOWE8duw5BEpGHQlP6NaFT z7EuNE!wMLNK~&gvV{goVXiCqm4r&kb21}KcS_8ukI$!TFFaMMTnw_PNQ3d2?rBo*U zIwGGd{0N_I$7nlT?-e)pk+_I!o5mp|ul?gM7 zicAc$JRUORsh9``8AayG75Wza5wppa%&)7(>dP>N=#8>tUunU7B?WeOt}9XHq3%LRx}bu@{NAR6Jgdu)vM{T0r$Ji!Cb`e;Cw z?U#tjcrhJiRWiReKwyy|eoF-g5#k@Ryst~FweK71YE`AGnzq{pa4EKw#p!KXk0G!% zuX2G`O@`0Fpx@%owMPOL4EPlm8+;sRu>Ga@k8qr@2aw`T%)Z4a7KNU72MYwYWOH0i zd}el;{Py6j@>=@u5XW$!y`J_5H+pTH+rt$Wu;Q(}MQeu*^^e3gb96*>0=vd&qOnpza`iZQawm95jU9D5 zsNud~L8l3Ju!i+3c_!T_`mr6Y#fh2G#`KnqB%?)FR$bM0-KyJq9~@qF+aHRzJ+X2j z8r3Y?mXj9OYtOJ4va?&?IkJB6(a|5T|H(((;D2pfxRo{Flus_x%{WUJB6zzPXSr={ ztS&P@f3zwiLLOu*E0xPZ-|P(;CXG^OE~Tq_wx*jL&!y$sxV-hI?jpOuzlk_qayNYj zQEYgqthi63h@<>Pvwu<0kBz%qw+sc}Y24jryR+qh>CT_T3Ku*q#@djd1z}Ud(QM4k zqz|;fA?^6`1^#;@;$`9E@iJrRMJZk;Cr#8wU*KNGTByRhmWm#jhGT+agcFsiK<1s1 zNfV|~dArl~;iUT5_^hZ5l{QGNRBNAc0YMNO!9x-PairO5GdXZ`ZkE`sKJU0n$HJi7H|(w z$S5nh=w~8taP*tPq!Ema+{S7xv>6c5XFqH^G*` z4n^|(2>VlPD~!quu$D6F?Zf?DUh>MKf)M|hk)1G7n8nlpcZ<5Z$y|Go`#Gau4Ngd9 zLJnojdh$|Q{3*{GMN~#D2S*NW?A>(l+Vrj#?)@tUn$X{V!wv_VL-?PFgS<-*Vh)M> z#%Pxq#c{AzDLzIIr#U6ForzQ-jGzH7Jekel!)y96GRrG} z1oJZ_voXI(G!`xvS$(Cr%g>%^Ys5Fn7QZ;hdIq}{vO5gfW%&mapx{}WXZ7RxRZDBF zRb%R;!n~xy%Qd#%)it)BHB{44REPf=tvTc_*yyd2tSU9Zln;*cmraX!Aw4IEEPZB@ zu*%6Y*syPMM**up)_ttG62!2?j0s2&F(ST>=!MnDmfpP*8rRz$dOKY{6c{BhI}(tu ztWh2JeRXaIj5h&2dhkm7y|xwYz1Dg2Qoj3~!6_p{80#Z(EbyH;l0RkH6(0C_mpE7^ z%c^+Ccg0ITw9JGu}N7-aza88HQPG{jf z2_HM7ZdQ^eNbVMl!SW%q(io8|rQlh5niavb*(`V_r{4%sMtzRQ=o#oP#H3`|m;ryL zGblndvPqFCdbq7;>7A3pQ{1T)SKgi!p%VM!*clb6KX8YuKe+H%u!|$xyN6y8`m=1V zUdAF`vg{R7e^h^E#WT-Hu>Avlv3MEm78u`F3sn8&{^(fEtQCu@Thbq!)F)?OvBK`~ z;h~gzm0%2z6@aHBnJ(P4#wCG3|NCz&*u zHMiW7h31e?8c)vC_=+qK6xM*}%otHxqJ*8Ru+PTtQ!x8=cyxS}Iwt-#HLj|d_`!*T za%ZA6k%>Zs9TFay=%}7Bx-j-9vQ_S5L#x6HVOs=+8yv2&*%ZOsN>{65)nRDbq@2=J zb6)A6gt1)#N?DCQT&dA%l$w1>Nh!9J#FP?8>m-iga2Afp>Y;;inhJO;jcnrt&oVPO z;ig3d$w>8df2mB_9Z|;>I-JIL!ro4%eqoNAjL$4x50!Wv+PWxqXTl1a$-;e)Jc7=k zM+=-dX(q%hBs*O&t%Q9UqUdbj#`XnlPC4s%%yPy+L|T8nyf-U-_5cfKa(Pnhver96 zP}Kn`F@Y5!dzT=v$#kd=KO(`0{({eKJR&K>W><_eN>NFO3W8pIWD+96;tE%L9xKMA z=hqCa-7)?1kWg2I6ZDhu@?f0Y$IHAl$ZFjBvD+b$0v-Y%8YlJS#tH5g?O_-N>X$|3j@i6WVX;#Xx-#CRq>OB)FQX0xB#**bAtYF86jZ)1Z=du(Ro|9(+o8Ne`2RLY z9Q?O`;f{01`Slz6##an@dGYBsYIqbyb4zf3u#4*5)@y<-FCKd3#q zYf))?cE9e|JBLeq=nIb1+0U+ye~*^tJ-gaO?;0uTy7wRU?zDlj?tA}HHJ8Z|A3p{^ zhcerFY6O|Z04GI}lcA8NhLY){*))#x@w?M^%L{KAj|y{<$Vt||;J zFtA^y!mu~bmX(ob%ZBb1=I&`81{2O{UKNUI#A;et21NhiVevW@l6{gxQF1V{^+15> z{C^CSyX$FMm`)~HO45?DOLWRuRT$b-n1<7kd&%0N_y}brYnZEO$k|!=_2Y4>)yk;E ze7e|5F`pCjWwTwiTlAkln~)%-03eJa>}O5U)GBMpYmS;bYe7WyES48=!Pi!R%%Ymv zmJZeY{`@+6;5B3iB-X8)vmjnuY*#FK-cJ?KlGu>l+RCy8DqD~(kZtNJ|9f;uqNQ#L zm!B0ASDOZYV)+t@e7=N^tzFpX32r48IbaKr+g1Va(i5)CiFzcXGY?L7W@$ZAD(LfK z4n?k9+$O-I6Id0zuz4$XtBh}1UdC@B?@IVeFqXi#6Y+OtKUg90(`G>IpSiHWLl(q& zCi3DqZ(ZX!%ri6XIL&ap{lGX9KJh<*560mat!c*!h2&Q!%Nsq92ho@F^m`XRct*cO z{*()!k24(wr;)m8A*h-pbsix3SQ0ns3VQQ77sz8``9p5|7?x|1g?VCOTi$soKd%&J{O)-+Xmbtw7}iVVBwYF4CPXV()B?Df zAirAfugG=8o&#qKtb%+X$_v@x{USoV-Nc8e;2G0cKPqYUNi4F@$fg4~Ru!&qYaY5` zQJqLWU5HoeRGbQh0m!!&7l5(GtiNV<=oh~DMJ_hK{{4m((@DUh6MNJ44 zuzk+ttc)O}jCsh+I0A{h=6=~8XL7$Yz!}%nFZMUn!7J@=Cii{Q`nK|#WO;+<{zblG zH2Dtmz-R)SaoRDaEVPqH>z*%>}nheO5oSzRV=4NCk?4})k8d0ANLzl?)Qhd$> z1oujk&8~dJPKG#3C*mw6$PZ95KO^BsV=EWu`pwEtM8xGKBuM`s;!j4r5FZ_7G)6@` zmK&p)jTnvN4~PmmKL&4e(!K|x#Jk%RqHKBG_uOzkBDt#fn~RYtm2>FMvZ$XA*IV-A zZ81Mz++-=BO&@9Z%nG~bWBuMvHO;lBm+yKaz0gpaS+VPhOo$WYiO)9yZ>w1LipPu- z#@17_PP)O^OgT)-JZa^ZnrrHpvGvq`?-W(u5BH0>f=75Iww~JepV!ai8QU}5jIm`R zJ)Q05hg1!x$YBm3q1%`z<%RhM^o06?P z)Pnp5lhxvlX>obprD((PlK8Pai&qgB9c}r`B>1yelxIci9HA3X02PG20n0azVk_#^ z_DuY^NJC&wL@9}Ha#r)xMcIBuih@FoEx36qPP?1(YHIQupm&@v!L}C8G+~93&NM|M z0tdrh%yfVOVdVoqR6OJKM71Sbr40>F&NO8fnpDDxC-J-!i_=6D#)K&StWhRIazivb z{scW_bY}ATiFy|Icf(HFL5TTz$QR>Ncr`3@OfY2_jwK;1bK6p&3JwcZrKZQHm73*z z65}&*)iF{Uw@Fv%P^^&QF8xi>g}Extb}w^Du&&Y%&D?xpcL;kOr8F!)Z^G z!HwN=OGgKrXCY=}2mI_DAH0?D#tHFg*Gawv5%`HG`l!hjj&U9B`(6N8&{dCeSI}cL zAD_YAaoQ6I2>B|eKZbBVE3qcf<6#8)_B*AFHvb!O8m4O(W4-ldXIm3Qs}8P%V9Cl5 zbCg+z1k&k%KyQ4krDR@R4Xp{NTp^vOSX8Hz1^M0Pe_QBC=uaOl-rh3I=`CJYe#eeg zZ2Wb3Uv54>2~zwp1}h!%fF{NNCdd9B$C@Wa<=(2T<>!$3C0;?k(zW;{uIew)1%4ao zVb}bvnERvy!G$;}tmp}FN=qFUyh#zog4`Toq0^M$_>mYlWlLNEi=7HSm9wC=;1duv z|MVUK3?Qs*(|Q387iIbKD_d!>r;{d^8m+?82Hp|yso?iUlksuI>?h%q85N%rivtr9 zE-z}MVv>1{Bl(AzzG422AH>Bq#I(5lRMbEo=Hw%n8p63y#LC%uT4-wbS(&^>Pr@Xn zR9d4;3?eq(b#ckbixs! z11guR7|qdcy4yz*d&blCFGFQwC+ zNybgcw_k$EM)wg4tKiHO@VkMfTT=hA`MRSG|0MU8n~Iu*Fc9oZt4ZQ z#A#`9&P~s-bN4l}3c&S)^pHerdU}kB3dj>J%3aEc=~j^*r~YGlxPZ6@dfXzJVppNX zUtPM2$wV?IoX>|8UWGR_Ru)-cSw7Qo#`7_q_sQpYAj6-NLh^e2)BF=PE*iYb(*Pc* zYm^HGOV-yQj&KbWI28*xdauR{A0~wg0Es%4tvef_7et*lUQs}jM}$A!Dhn(TEkvYw zxGD^=NGkN2;FJDTHh@StJBKPALv?qwy0U1doEQ8nE@ICxh+zD8XH z`e}}AbYx@%F&mJA{tfFspjNVje(n&Xf7j`(*Z3oog(Law$fRv_MYUf|=t$Tv0v^Dr zW&ZHw`&7jro_vwZwRm-O5L#~aCXPOmLNkX_y;n+(FIv#o!v^{Tf27fsY|zzPF_Fh8@Oc zR-G_rJ)eW_b{`wX1{;mYku2j@&)cGF#0<69TBKR7ItBrw zJ`X$UcyKwOeIVnpiIqGg=jNn}9xsamH(uF8uup`uyJc9v`J9LeXLqHpCY;-?!E(&v z?C$4w;nQWlQSbzGtWYNeQpTWmRSFr`szBSVW=IRKOQB%gDu>J*SEGy{(Wh_@Sn3mk z&z}Sy?{mVLU?Z;<-A)F(_s7$f^9Nm#xeo~Wih{zq;`t+Ku5-oo(+^$8ibY<(2lV!0 zC;b>+e1;@;NPIPu&xB;c*LqxenXG2oHrWt%Rj?h$&t?iIk)dl9?x&GA4z1lj;Y2d` zV9syh2NiH++gZjp2X2V5zu87RooEeoPTyEQ{gN$%Oe!{8v-W4pm6o#4oMW> z)dW}`nJ^bjhkVNY8FcWI=)fv0NQ8*Z#-;yv4 z`0T{mzzM_C-}3#iao>c@^Jn}7`kTjh1K9cT^AIW)q2wWOJ4+$JaSQYfpQ$++js&-! z+^In|;-SF_5Irz{auDZ;0T-)p!%i!)q+>-X1)*_>`Ysf?aqLfR3u~(!EqEd9bWhKF ziM@$*mg9VXZ$CsB>k#UE(R9Fs)lI1o5(k92DW!Zj3ajGHY%a`)omg-4HdQGrOGdKm zL+IG|;>mTD?xbn9iDrMF+Re)zeyjnH^1eRMXiAPJKTlJ$I)Be|@6_ry0y7J``fKP1 zKK{c?%;ZIrG4zxO>OnqCGwJlYR2xI*G@zn4tIs3Y4wGRWmuydYs9hq*PldV1jawN_ zpgY9#_V8DFgnfLZDHxd8FmtBFecgl%^C;{S1-kRQ;3;&M_H>>wp--$Bf)7qs?J1E~ z+(Ghq;D?N#1H`mE;vtPP1q*tkOJPr*jMrTI#U<$f0{0xw^TFy;nptf^H=)3x>nUcE zWwSCfpL#_b%yF@X&MWf%TJgMjc7uInUKc%_rLK&PiHc23F*lC-wN9*v@G0}Z2sxr*#6#5q8@kgY-r;Yxi@5zzgjW~1XA-ek{Y#s?_WLZrjT#up8aBl^$@|D(xy6jRZVSOXE$8hucnaGCp3sB~_RoX$zj=0k5Bmc9oD5 zyiR5jX$HUbv>C~un#I$s+|k)L+==E1tCjf2^d29ZM^*mU$H$o#D{-937_A=cxvmw> z12#tv;vZzP5X5VSehFcoWp+wdk5eHCu(6XN1{2&9%+@QSg{SYKzYM!<_+!`~lbOQ4 zardqCNG>ZJr={fCKk{#wD3t;SVUCx$BJp7F1Hk<#~egaI)gVU z*?}0y5Po9dKeo)fdvGjXKPRKLG2C&{+m?%5wA%jMrV!&oO@4P;a>1Krf)LNBCzStp~c&`-K$hS&nBWLyl$CZl6kBfwsqa+6s29P<4i7 z5h`SE+T0ytn(fl%E+UIcoSlD1tu>rSF)&}xHB?(;^LLesYcIkqxJuPE?hVmK{mJjdtW1K#HH5E4Q)hntz1~$5SRTWOj0+Q}H!$*8=IP?C_tKhv-bb0;&?sf#o zI3D*qc--Onyf)nV@vn~mYB9a)hiSleUCfsBfghgL*+Wh`70T93$Ut?KGoM;~k6KV* zZ^fL*RF;pLmA0nNLk&KDldq&bS40W z@(kh;aEV#yfeFQRy6Z%!(vuoBZY6l=V-u_Fl(zer#{skZWE$Nn@-X`R=X@f`-&Od8 z{z5d}uEHoXc1#q$GM-PK{15m<8vp8iLXV2-;0GAxUeV5@WG488)gi=gjFpX+8OM*6 zo8dk&4)YZg)p{X2IY+hZNp2sCCuWV4w}E3d$8s>otez2UAZhP1Dd`ytBi!vmrK1mo zf<~F?I3CGoJvVy0iXGA0h2lmk&Mo!1S~EK=Q7C;R%wHEKu}sv((CBiMe!1(#9Wc8Lxoen0B53=_@9#x`I|F(!H+iv%NI3f&CjJuT;bhF8TnD(MoIEkdRf-Kyr~+l4GUU|UvwKBv zA@4S1{zKkvI4Q4g)_7v2gl7!!gx|>no>1)*G5c-s~(h&jV1!8*)`i(T`<&S_!3r^4wT{+S3btq`4-Ici(H2f*KytaAzW(|}zEP3Nf+ z7hDvssPR-BS_H$qK!b3x2VB}+VI0^Z0)MUI@$q>6$~~XN{ZPgv?3(x!*SR*GI##X3 z32YA-{!Th_y-zxXjq!yX(DOX5$dZ~4TbFCo9fYZv*WoZoDh`F{#RDN8u+N=(B81sw z0v#+o|G~1KIE43TQ?)TuicWP(uRa5WtlQ^495bb z8ntj3tY5b-F4UFKme3Fpc>>ijTt#cycp1oTW3}S=@z`c$d@Lb0J8?WRZ&Zqu+sspI z$fcBvj&3Bd*(cSLQ*TjA_rD-uNHh8wkA@=VA16c8|!N@{7KBc^t@P&4XhOeNSPOGtq0G*2U;9}zC8p9wI{6}iO)ljJUhoUt0j-@te6 z&-)9-QwYqvVRkP?jN;9%XzFiFT8pjEY}8f-^7V+1uzJMmZXv1~`ar<_{clvhRW&{ zUuAT!S+?fIn-{NB(kJN72CC^9T|(>YT5h@F@lSTI$f@*Go`Oooe&ww5r+DY=PuVKY z>RL&ex4}5xW`u&4PV_RXk$$L-o!5|@Vu*>*We2OrLe|vAcGuUIQ%!uL{A=UIp zRrC5a&B3;eiWz^OvoNA5xT5(?gPiFm=I?v}@3!V^??~^HU^rQZY5hZtiBda zMIHHalyIm0tpWDJvXi@5jrr>A#H`k5#gg*e9Z@k+X?FjH%|fwxtvoR{7-PY2$mMa1 zgt4Uex?F9n4^baB8FgZ*wlx56wEFols~u}$)&E$TSXM5UqtTJEspSDV9XpS+LbBmr zi7{Xzwx)f>eJxY*YbNvU;J7niPTg%G!!nSY!~Li=prW!GrPW=FSb;g4`xf1%R|Gij zXC>C%mM_#JNB8_1_7ykGEoYguBBea7%)$^st^Oss-IL0nrp9M*ozYP-sii><+a!w- zNQ4ME^qeLvU5@7_CeQOu9zBhLaS)L_hddJjGTqQ*Me6e4Du5dGHkfi{CN>8s_`{2jF79c8nqU zS{aAo*on)rDq%R;ODye;J$Q*}nm{mVKg0G39<51fQYKl^pNMwJRCAK66rgAFK7MX$ zx^qYpd8S&E9phHVL{*1lsM& zNCS>v>;L3`C15Ig^lXG$6Ca_{Bt)t-@sUbR!V#;L`Sf{QWhQH42z7{D5K(~D}za(&q;o-pl6wh zQ|W^v71IJVkv`Nsv}*evkvMmNP>~?gR045*D^~1cG-9-ot}gnN{s4V2Ez^QCl|I7@ z7Oda?!}R%d@#2FLS)?oUsylsHO^+;3^l{ICai1)9;BV?K>#IrRxw*PMRaV=M@>=7Y z65&l60w1~4XczosEG>Hit;Dn19(S7}2>$`S`bw+QLj zQ#f$pUj59SZj*SbZuW}OW0QzBm017(c#6?!I&h})RB14a_TW(lfet~}>_V>cOg3MS| z-Bu}7jGeOC=SxfD(2MIeJ&$d>F2^Em_H%XfM%ep$#$VO*)ULPE)djI)p1iqU9k725 z%sxhU19I8e`vCa5&l=>eNqsYO%sm_5JtVm}Kf1Q<=ZjkxE$z#&Nc;X1;>!Z|B-Vxc zE$rC!#K@eLhZ9wWQNq@rYZ!lZ0LJw}Y)^Q<54=Lx5PumD{$0hh-pI%0uHsgo;TEW4 zzV&3WmOrv=Cx;ZI<8E%%{KsLqx_7;o2jl9l^$l*2uzBc0uA1;3BG|5ypIYIHc)C2* ztNFf#Hxo_HC&>mr!n*=sF;3^J9!J8X!`jUEKgD7Fhw=0n%HG*QJ{0ocCS?6h$o6y3 z@`Fu=EHthH@dK7C2o9f6olc2jN^B3tR~Sc;I##Pj(8N&@fr#U=KUXa!7oz!IZ zLP4n%Jn`nz>a32isMmfIsYuFx7qoW%j;tf^ac^UeS!NnLCL#zG|1KA?Y>M~E>hKiL5ev;0o zupwL_OKEL*Dy||kHZmgQ$^1~-_~5*G4?6BCC=RqLcw83YeZ)%c7;;MxYh^x8;n*T? zYEvR+MVaDajh);vDG4go)HurUSwaufNIuVMYL?Z6gsO@8Q~bF7oR0jByTI~R#roUU zJhmC?_cg?4`(vE6B0{HaqsKCP&A-Zft9ymh?RIVJt*U#MflKi3bJo#3iNpUqq``EP!|3L088 zKXbiu3v>La<1*^boM7Xjezeu3?MkcUhr@I4bEWhH-e*OG_>YinPV3zgq+Ds{gi;k} zr+4BEFLu)In-8kuP9lJ^;{|FTeg~8*mhTR-7hYRx3@~G^`4}L$iiG7C6l!*n)+)fB^m4_E`2=!>io!4kTO{g^TTpjg$9MsW_MWmts7CODMW&{j zBVr=-Rh5>4+yt{h9TgU;uBj`kp*hLPny>(sGBG=?C@sUN3H4R_`6pO23V5E9LG;%` z#u@&ogC(d66!Fhs?{||OEN%{0%JgZSJIb0P)v|;fDu4J##d(?bU;Ma!`D)815 zMU@jQdtGySjgGQDS@xu z_jl_e6NKZXa6QK)^KbUzoS)&{6~RCB?h5UsLL0)nD_EftS5*x*|BYNS`H(x$GRHCh z?1&Zf3O1^@?edP(au4LotGd+bKB`bHWGRNzk_(b7xkKqLOY5Y%auB63vUx=T(9xj6DHbRX6{yq(j1nfRq&VUQvuGENg7&3$0jm?FX=wYsPQ(5M2>oED$K zd*I!YaGU*$0`ZJa6CTCInZwP(GYj!d3w;#tJz&0GfvzY!#|V2*Ye07=g@d&*IyN$= z)+rE%umxJ2S!9Lt9zmzM-|fDu-K>r_Myq0s zhfz*ES`{1rdsZ&oy+JfF?pBPO=6oG75i)KOSM!GIcy=G|+w4q49uxm&1qFDWDFpsB zUPqqYz?au{z4rjcv~mA_XD0GJWo$iWF9PRvB~&|~)UmuMp}a*E9HLaEr^cr-ZCQ}V zYfBsfWH1dllgP01m`Dqk>}0sf&YxYPgZq1(O=N-d5Jm$I7R9}g!zYBC1O6Rfkd{xF ztpdxxl)4O1XSR^vvbFH5gQ z@7ASN1=%4l%2N|#5+ba5C3USgahB*Dy0ddNUXq|o&Cpol>Nom^6vB4{m}ALO{yjF4 zEN^GJ6Pg-}8|-$QJ*cz1qCjs+vE!u)*?Fni!_|1l%?%kSTd6abzy^M*x*;tmzRi+Y zl-IR6{ao^TQ%6BD&u_dPybbh+4ae3_w!%Vr@TPg8d{4)=mZtoY5Jq9g#e;jF+gIEM z`Obn3Y!cQ@m+kCs+GEaKCVo~~sZ3sIDGae^G?uQ~hO(@}!S4?6sxdM8LY*$Dn>6ZwlT7KN9>Nfxr%jlVW}tD1UB<+)h`e{Epw zrA;i4q)F9-^fgnu#9yZFVxGS!v4aO9xug891bfRV@6gN5X^l${$c`-g|JZvEz_^ZT zfB4Sam1L{;URJ$WeI>1WueO@i+#Sm*mTa}CxTW_(dT)e4LP!Hb67oVIAtba1ApssG zp+g`fp@onN_UikcnR|EdHd)Ezz5mw;vaWXL&YXVE%$zwBwl!cNSxxni3d%^?&W_wz zZ5kP=za`K=)2}jc2v!d?Z9rc%7eF4IV|5WCD-*&R7(27EftzY9y}miU**@uMMVr9a zCoxA2G=J~882=oaDN#RNpz0au2R04!6K!U4xS%J*&s4az`vIc)1N-+sV0#j6iN?L4 z4b5d}8l^8yIAnOXzbvaD3j0)HhtRX%;G%L`rA+WK$r##QUz%O=RI{$$+pfbJQ_CDKC<&&{2VUI;W zTQu0Q%s^|;7QfgHPn{d^%7&+I3}B{BzpO9#MI9Pb4tE~c?_5Vl6?T?fYPG0_od)N6 zEdhF5;kb$Y#6RpI2Kr7%-};@g*}%!oayTxCG)4kmOSe?$M>9R$Bx^IcH-Xo%9WP_ zB?v0dlAejRCNZC)z06enq(`Kx#+^XyYZ}h0AF|7u|~;a=$?rSCy3KkNRuwSkP$MW)xr(^w-XwinUB}_S8ws#hJ_R>a$@w z^=YI5Y6t4)PZ19|k^!_cu!f$DXD&?|eVvY6+Fo?fR@fqTx0)!<;!2&xXq}>!%{p-JeD&V>8*JZWmK*NQvwah$Rhu}%X9!*6@=j&MS{PTZ`oTrH6kHI2 zn==IB5TlnHmY>(4SmUN;gUS=#0nA~wMRHf-?{xQxk+~kvXhzx3=(`^{bvm;zb1D9W zxwXg%)^T>i*XY9B&T9T%lT^1er><*Fj`OqdG#+qrW~cj^-y?RFa7W4EAvJr6^>Od` z7)Nr$r_I1Cr(3KY93uJb(ar*6-OK|n2rgJfk(Jd8k~xm+(E`|s9~(@pi0695 zSwqTY0@vx@M2{FPLUwL*ieXq-$WGGAZ9<9ebrlIM&`RWvV70 zYj2qHI0M6s`^W2}i_zMwL6?J?9;`u@9~$8>>>;m@E=D-krps{+l(osSYKO+ShYY`O z-$OR2hkX}$o7T77M|P+>op;jrkfGz=_K=OP$m1?@o7TVEKCc-D{TXWTNGcEomvNI^HAJpj#5dG-JU zuX*m^DOo-JgM|H|$8evO?St4ou}5%sf-UOL(fi}VYKtTPEOsA^=PuTPFG#vJzE8?( zApdrJG4PuBo+*xwpYn_aY`o-e1^An%RGgZ_2E{QhTCYuod-U7Pv{MY2kgZ7(!!3pK zK0m-oll51ycS2R-E7u_rUI1N_YD?I9p{nuvbw9|DTvK9jPlqfaZ{L~G&#SbE^B%6} zRg5OW^@PWO=6jq^b{LL9AdZo>-Jg+j4{zsIj84Yu*%daT#gd*5ul&<7^T1gN#Aqn^ zYCn6Cipo3;b(0MAbvZAws<|%xyo4hH1`Ai;g)My=c{2Lh5P4?8sXwQ46F<-Z)z3{h zVqI07L%m#WLTn(LsH7`ER?7Thc&@7KAlb070FhFI`zKF;rwD!C*NLWAn!psG` z_FfRby>e)Apt-JYQ)Y8y)5Sx(hiy|Bit_70L#pLYaWhr}jB&GG*WV0enQb}o_(#xKDRV`+p%39VN zv0qAfp(@WBX9o=1sb0~#PVTe1Va47uY`kJzaj!2wM_tm+LV#O#4#Bxgl(1(3)H1Q| ztkvDuFI#38?rH1IH?{P!-r*^1OB?PIQ1fSMY93u8d64&wjq`T|ZlYern%K#+f>=-W zenUd-^k79(rm5i*JBQ}oalH79GuqnPmTBQz;#a*c{D7uc{3>$l>pkH|2ul3&H2lPQ z$Tjd|7zQ&@NmFmPCa{_O`lerMNV*}&8TW?tY zD|~U;RP2uCokePGZ&+4fO1y?^s~RhKnN4@?tc9yQAS5=Zv#|Pg3ZyqhEZ0}7anbR% zH@%`>TI^d>kROn}AtEd!VtSag7F8!S+UjO#QxF`wiXRXu*O?f~+aA)xk-j z7J8@+j&~=_JH^(5{9-F6GuoYcYN00M**n3}sM z<4c3flj5yGfpNYi@+sa;K-k}=kSUb){5nW)fk!L}6P0WYakQb~B2+A0jcD)irzX7tzn+2zv zEk{O9{MBg3&VD z@{m4v8F+hX=}@oL1@KKGVxIq<=*f$aK7) zhTo3H90IkH9G=@xu-6;*BR(Z{5vK>Qg}<3>qNzx&>0_s$!-(L27F7{jQ~qgbPT1%y ztoyA)4n7^eP+h6!$A%i|;wB4xzQhEp8JHWC6cY41T__xOlOmc_QBBCrKH8%jkDBqi zn~}7=;VdIAiteOmtq6cCro9w5Clp-pcfX7rQENXFBnDZ-!O3 ztNJ}nrEAg&6AU3sv`4ru+iJYE=|8;MSMBzu6Mu48SX$rD6L&;t`?#pUCoAze&7fRv zi1?m1gmycGV+sW;oeDbBy%6iU>%usZ@_N@rv^M?oaM#7j7wijNuwim9DGo7z0A-FC zZ@f^oGah9wh|ES`aG7tNhK6dPSUQV&;UkFe3BQa}-nfF9i-=-q2ICdCr0Ic*#w=6AT|0*6JYe-3#}o## zLwGfN!3#s_(+L;6j^{Si|IP(1l)rgYLkm8d@JiC~5;auT> zh_PGka~Fx%e#~7c5_6SIEfjRjT3oREiiX)k5vMQtl;~3V3?b(O%$ty)B+o4%Ov521FEl6% zvYKOSg5x7fgS9z}6FsiR6s3S1FZoxx!|5-Wr$|}GO68jLh!B#T?rEmt>y<3OsBJAY zHT4{bw}g~osuCO+<5wDjNlQg=V6-RtbUDpdqM>pm^W;acu21w4yWS36#!i6%%jn8n zDD!RYKN;@Pb?YIr6v z+O>e^ag8Pd9((zl6R#N@Fx8!)`vq=;46Ipy*~kpH+7nM}1A3@EapEub(Ww4Jo;Xvh zjb+^OGuEFlj^$c|;vr4gJk+2#dAVKWKq*-Zo8pQXvh6+w8X3pJx~y2SDRV<=n~(wz zD81_lIWUf_C;b~S4t9&Y;v~l*NpVFfH}b+ueNvJ(9z2Rsa)0K@67uc5*8$IC2hIOYbalAqJ zWTGk7(!BA}K~sHQ(GAmkoqV(hTrY5O*BVdT;IE0N8FWXhSA0FWYFES;3=Uc>8GA&( z)7?SC2T5AY2p>(fK(4^4XyNX$z0$8HtKOWz&sNnU(hJvPw_wp#dWq7~M;PDLxDC3U0HBbxsn^KQK_pt=y`%Jn>4 zvInr?@a2*=fWaGWblEk+;7Swy*84f{R{aj$d)pHsrER}Y)MN?~s{$h93eFqh8y)NP zR{e|Tqg4B4-YS4m{ic&CYnK6&_8xV>sJ7FG8k_y->cQpnyp;r_!*D0hK1E$Hcf7H> zsER|MYvawnKDcXshc~~p#YC-!;8yY|#*V{BRHZ3g$+Mv}F{>SCGj z+v`GpQfw7I=N0|Ov3MYM3{PIPHuHtA2k+^;Wwcny6PqsUha?AHz9aI&?|P+1o;a-O zLr&iocnWEt_+8S4Y9uEq*bQNBD~szQ&`G!Thp&1gmTJ{1CZF80K3dV)-2V=2kGLJ; z{gPMeJyua)T8x#7liysMbVRp2t!`ip?XLM4vNhLJ*^l{X7PHM8o$Nd7_pePRp;vj3 zDLQK^U@`9FuLqU~WsJXRn>Vs(pd{wqy*5>7e$xZG97Rrnmm1H;r9bDoOLyxt4Y#^f zwpzRMp!#iDqIRzL`p!mY;a*GWYZ~1>)GRw$lO&x~w!nkxxXl0$|`>@F#2EsE%}P5uaT4DYabCCiiALU~MtUgCe!8-;X7RJ0~}GRUIS>o+i3aq zs;nL<^DoWhvoCw1huz+*Th}6pX2Y^X9oPVxOL!XJ8#R8d8{!@>G}wbpwQRD;{LwXu zpyx`KigOHZxsuRO*Br@WWDh&%N8MxsWL24RV2B z1IUA{hJU0w-Y&2@ZN0g|Jgkw+32tLbq<}w-ts*Bom^yyyG#d&89rylI2(; zBYc2VHT!cU1D^imC@p)P2r= zQsPntT;NAsE3CWihq>Zpw=sB-R>uiH=R1To{2m8>SiA9tpL?|+uW0_$Ez0$PF#o50 z7Y+stD{(Ke=b0IP6WRW$e(AyN_RyEaS!4O#Lr&kF5n}j`|Hk+o|NOeX`#)5p3+v_w zl>3y+s1`{KyqK|oi*IOTaTW88Ps>hDN*lhFDuX4(CFaughzkD46@vLkqOMpfNak8u zEYtM^=Tc+Lemnf`y%+zSe3@i2SbGO&h#Oc8E?w1M!xg)J*@#_(!>)lvuaX z56y+USKn4gl}p7u%4L;0)$p$I`4a6iT9)ei5SX5jTArSmW^w&Za^*)gSxpQ4lNdDw zSv{GUL)Iv5pi?@tIOW9CYLuwT<@rxnABRKPUK9%7$Rw}97>G|yE0y)*qD@_;+1+A*Roqu9@*c_RAK%P|%=^)%*bRT!!0 zi0w&srlSBO&Iqw5*bQnu&dkFyMWBjex*zJ}LB>(1$l~|VbYOz1@s7Z%i1vs_H#~n@ z5$~^G9NKLi9o_WLzY4k!0EgT0J|YRYTEThRea5OOda2Osy9`t$Ta$~@5>nEW%3lh) zB{n*?xNdjDUUnj@ydW((H8$z#)~x~cWlh6^E>nUoo3TD+Mz7k+pkGvE1RZnrb@VFh z2fY=Sofwys`lo`#?EHp+tkROIk?N|=$A%l(UkcLWld}AF;*ze!)`qN_qNd@I)?*(N za9V$y@2Nmb+h0TBFqT7 z3?9q0xTemRDrm~(T2z?AkqG@1fnQX#s2Tb|YHV^&bYy(Zq2h$7IP=-%**v=sMJ6|w zY-^}$=Sgwq^n~!lz@VhQwDg#`#Msat0e` z9qKhi6BYxV$5Ga@3Km{|ZbI#*HuakLPv1Y$9=G@TPg2`zwDm<>s@Y~g-{3nh+p=-A z9dD1{J9*%fXiGId=TYA#LTH{i?H?7X)h0rXqT(i$CaNhH#Yau;qV^~ieGN|j-g6N_ zqVy=@%GXynvux#csVi=4^@1NWPP+2A2UP(q6{{o4o60X>{ooH!9m#4@2Wq$bHy78V zC{LcnKgD*OXn}h}M_7pR8o}&`yFZBBNVb&nj4ZXR4TmQylXDB28>^bPZoeYvfujED zqVnA0hMH3AWNWLSC;HgTLeU3SRwSFyi@q49ccx$NQITv(&D|GJS(+G|k)2l6W@#L5 z7-~3eGOOI2SZB#jii}IF$SU8|o19o()dG6_3h*TY523d)u6kSMs<+`zYAf*D%+m2b z^j3$>gWhI&)>}a3rnZ3TO~Iqrq>RR#N^g&Q)7urVY771)0B?WBojuo^&YC@|ECYsId65+g z8)nzn+cXs{G^i{1{VdvEg|^UFku)q;^?WzV#x{ex!q$|b9@QYUHF;__mu%ApD$Q_B-A>|5KGTgo#sc1D#Zcbu(8_*PL(HC3ru zy$<*3ya}HgDE2?p=$MGCbTxv?kfUH#wpxLbZDbd+D99pPNVzy{Dc5QgfP2q80 zIKO$29o`ZUa&<|mWpHmwUP??>@3oCOrgo-r6%jyW+_Fy!5&Nf&v{2iacSdSfmf^N1Rf2kWbcLA4hAj6P6uxH=X@ZriJf)YE?!+# z(bpMNoe<|!-Cbka)l_zRnQv}rxoKnA5uc9JnROd`wwP0b}{j6M#3QG&RwMJD7{L<8j43^ju(CXh>JZ|1x zG*Hsv-yYbpv7>Y>t)qCLw2h@!g=ar^!wt{HnJbjl+Y76T-opR#e5!JN{)ztqCY2%* z9t47}M60;=A|m-P<-e@+P~r(e&w_UT7}*N1uEXzZ*|M;#N2~;B2e(q$pK}lB{yg zMiLq^I1Zpd43Yxb!NAQ4@mZU?Y6@6NK-ab{oLALXHk`YqJT+*;C4rX&?Fg!>dhL?z zfw~@cf4PrsYhGDb!}taHJ-OA5jo@-PawMX`XT;W->B&qh5=cB1?5$^7^)<>wMrlsA z@I|#|s=RD?&+db~KCn#nEeW(_-uh&DZ*ob+NbDa1U-x5QeQnD?d1LoED`h@uNoA&m zi$^VWBb`;LK+z=V7%6zW5xj+TMOZKpYJN&;X2sAbMv4+&OJgiA+~&(~PEFjFb9Gxn zz@=edu%evw#+sCK`Z9_pH#cu=4rtoY9Dn&I!sDj~6`x#e{>muITX zGo5=5$re-cp>uxFIa=L^uM_Get^km#B_b+uV-8B&#fN{v+R+!eIcoFPPaliyis*#9 zDcNzXsysg-MOoc$d%bDn_+-dAULiro0eP(oZ~dpP-BK)z-ke!2aq3iz5M1 zZDD0CyMvz(Xg_D;d_y=tzuMefT{j$KJNXwjQdwH=(}uYhQwmrA!QSF$2@L8{r7b#` zXGi!oaQq*$#t?1|Vc#E|=X+Sok?Te(cLvdayV4IOekSO?zz^%X4{>S$Mc(82eS>Hc zxr*=d+aTxuuqPtN0y{cle-N50i}P=i`Tg2xPB$k#)p0}vn+S!^G_ zA9I})I?JNZ4vIA6sTVm+p|gevUjbi=R==GlA+U2HEUP#rGbSlHJHM^0q+nA@d{lf& zW>Hsp`|EYX(Hl(}joa!vVlzzh*%_vdvFw)Ytmx2)u;{qb{Mt?VDbYbup^> z-R9N*L~+*u%(^o*^IRTUw#92?K7ccGzpQ~D?w zfcY)JO!<%{So_)P&{A*nlnA2phr%Vp%gp9%qW&jNh1-Bfp|HILd08)}K1!a3C)LHw zM`e(12cD!SE^8GZ9>qM*v!tWz#n5>!^-+|RH1F+>K}0bKq$4v%A{X*SbCUWHp}v18>`Twnuprnw>)T@V7EUAKjYkY zW)zm?Qp;1btsF&eEf3fx*=-M4PWss16R)DVbN@c+%o-DB3A4uFLKoY+0)hlU^#Hrg zHu(T`4?7&c`VKeoJK$RpMZy@#xHXw!Aw>9CVUxv5P>ft2`hMw1QchP*H_I^!X=Jmuzq0V8OR^6Gw+*Y8 z@@x5-a=jx}R7u@%GkfdCnTu?%Ty&JbeKL^Wbn>8}!|DrYYerj~Ch%h_L?|^XLXE<& zEEa!l5PLY>_JecZV?B|!f(q8c3YvGCY_Hm0G3_E67PAcY5<4B%T4A6!d&#z)-N!O| z@aGz9ptvJcu_-@e*TKU$t&LwwOWE<}B3pWbxgsMm6_jU6r#1kBAF|5GG>|AONpx%|JweTxi2>d&$*bx5Wkg5_7dNXF_lbg+ga1gE%-@A*kp;q z^alJtxutWxgw(U5J*uHQ+zhf_D$pK^Myft44rav%M@?N6R}-jnQs-tL{asXV&@ zZxg(w%57MMTqgO90EDGK{2^QZ89t9xlCdTcFXrGD7L{7gqBvtGPw;q~FXvLrXw#nQtpJjoW% zIZHIz-sLf}Pim8lHnPtGriP(Qb~aOOC%ZWNqb=@=tFE$5@)+BDcuBw+2RI|C&&+g? zD~iQ%+bW0Te*iE!=9z$yN67wIYJ_N#&hD_i3m~~^6<|JZ`y<=SxeZ7#to8@vo@N1K z1kedf4`r_c#8?yCc=C1hqJJ;oi|`4vhGA6pATxDwTReM}#b3n|&pP=!^T!L+pTDxi z^4aY~Uu(8C=Jso^y>{t_8*TuyDsr1U*$wQQpk64gH&&EZh&A)bXxgSIji%qQmNYwg zV6wg4QrdBCae8`jdiZVA)3+Twzw2mM*HJa2A|s>Xo`b_fhYk%51HRVPcOeINf*!bS zCPqc^S~VN1pja&lVKKk`_{VqMd1sNSvZA8WR8>*o&xY8L?IGJkJI+1h_<83YKST1M z9do2F!*{B}v!sTl0?pJgKR#6ee$RLM6I>y#QSLeCKf<~fYUgZUkvNwri>w1S zTF@yXJ<8%&ZnZ@D+3vdQJGDQx;6|-Ye=2{aj@r_`nZmz@J5XSWoNLg-^ z4%-g0o9L(Cr>JiiuF&3ETGa>l1ITFHCX5>?DrhMY&O=cd`~)sG#`GN;-|En&0CZhi zlo1~X0QQ9K?LV~jg|S0p9eP#}hC%mn-G-6rvSa%ZG_prIh`$=exEbJ>=TXICsZ|z@ z_BiSvR}LNKVH-E_n9M;!&Uw_|@y#c{;J-0S?f378^^kSmx2RRnC3v)mGCNH%4rXOy ztxUy?I*YmGi+HR0j#w+GEz&B`V(^z@_06DNK_MjC|NPi%rD|1Vd}O($x!$+*wylS@ zHiR~k7#EdFS^Grx&iKP&?54NF!zzNhqnoUW$!|)r2IonvYcITzwnF7v0y`V=AL1jd zC1A%2&Q`Vf`9*Z?+Y-T8#O8fH5xdw+yLQ=fpa{5M5HHa^-*m3s=?$1i1lWeR;&;tA z=x>Tbl^9RHe}~8S;o6f!0~r@} z2%P$HlOd-bce@F)y>CYu0+L_Q=@zvD{fkUBrx6TWsTRYt(>Q~A9Z2oBeH25%$GDvM zm^c_F9iNY(zOp-CTHp(efK{j=2;0k0EXjd=r35N?Ri5Z89u`$7T6#5{Q# zSJL;Bp7<1@-OTRP*S#)$(l3eE9wEr4u59P(igh3nj`u{_Pn7tS~P~Cl+my-1WsLU$t|Iac5_OzifU8! zej^(aaJg=IVpdvSAK3+teaN@jbEq{EOH~rBWtnpB08gz|vA3p^1o%r#^p_Inwy{Cl_g2Z|_+lC5su%sWiqu=_IXszBa;h?=nkSAnc` zbSjxs4Ytc@$JT_e-%v9&9?#yP`kGKQMbc*-e1qMz7dl##BC5E4rK&onA*9bc9M9S>W0Aaij{oMv@XBb#jW-#t37LOx zDQ*lctusd?MTXg5lkYr1b(6RP`8rE9!jT#HUT%d^|i zf_3SdL88}$;Vdn6+$%+FpS5R@>o!*Mi`IxvZDXZxqiu*a!AOv4-(I2Mn+(a{LT-33 z&hL{9=R(WZ1&OS0Lc6(Zf^yVQM93>V?5p+)2DFC=o5Q0tcrw=qkFm1An(+LGq4tkg zc=%Dh*Z^#cgr^Ya{fRz>RN?#7oD%8(+P#!K{{iRj zB_A;{UI(0OoWNfb+>SL0=y(S_$K_By!3G#wmLDS52dS-ixOw5YKR_U71h3j=PeNxh7p-ivv@d8mWGd)LE%+zF)>F^b; z4?gLEbl9kt<(lwus@rIX&74+M=@mW(ZzO>el`S3cjR^V`&@R!bWl~hGb1E^Z!@4G% zAyjA5R3Ph2+TryIE5FZPa56X;1t;x9b=IQ-%KkVt%%aSr1k=|;nMdC>A+J4L;#b1! zl8gNs)IE^f%CLehrZmQBj-|?e!EQsdoa&fLo13l9 z)1Amlv%GjWEw7t#ZQ?_*2s}=459@h)Nprug;^}(~>_IG90?HDB=o- z<*}m$wdpDObs4O1WGQfKeA@7=UqnK5ly6{p$=00#u_dWnO4YdBifmKCU$b&sHl@ZV z_^Ryj?vl*B?&8c%s39w0h8>kKWAgsrg&Mol!Z&;v=x^3;82@NkTtmhe@~h$UtcFX^ zzX2C5<`%~I!ypuDyqoZ&VRgNJf1!@oGa6pq{}#OL%gP@Ht&N(pel(13vWKwX)t^XL z`16Px%V8g(a)%~!I3VzEunT@429L|=_OXv-)$W(~Md~;_ zuHk@_s{d^q+}2J$3`P^xp_OUox`^mV{o$kGcaycQqzFY<;B%O$jTnM;1ngtdo&l~& zy^=qBQmjvk?=DoQ@SUIhmMXD?uj_R;;ceU$*Z zVbyptka~!QwAsF8=teDYx%L$B>-U)2>50r#L8c$l1&$b7TnfgpLa(qw&-nrbH!;ODl_U1h9$GvdX zp{v~Y;SLf=qF=1V{e#mPO_(VUXOU=K;O7IQ4=ilmcVB4hq2Yq9C4omLpZehVhH-v&>aw%Q(D#7x2r3$YExr+ ze?}?xiP-92fWr^aZ@Plp{wO&F{kkXpMQPXmWJR>ab>`G=elT==N8zUOn)0FX!O^QN z)=Q@AX2&Zt3hGKHdz(u#^9$PRwzi(P$rRC1xcg8o(JCB+{R%kxQzm>Wwy%)3gZ(QM zEuqAz^kDAC_U=!$y%Wru&g|(8>;3yDl6|6mOdFHq0zSQ&U1>XOXz1qXT~R@W8IV=L z{SUzXJM@P<0&HT-z>aeGBCs#!I2jn!R^DIPUtXM7o!7^j!hgRhEo;l(8z#;etL*P@ zDl1P(V`V$<2;H`I{$m8A1%3Vtv7~s3NPhR5I@>sl|d)%7g$Q)E^646TUUiF zkdn5vvX-gHr0$fC;WKv)Pk!#=J#9NHiYwZKlWRNK->NFko=Zs|=|AnN<73ah1NfEQ z_~(S6hhnJ+2RTwH|7Ty}S(COug|n-I&pDp;IAe!)ww_^o_fcpWax~c=1Z**sGZR5j z39Jjb7qF29h|+-l?e40AqSmn7w5py>nc3E&KlC?LE)KSi9v(PvclRtO(7Hnje-HkPjwnalp4pD znaGZ$H#zu;+G=LWD{9RDMtf>m^K=xEXynXYBa@%Uu3=MWaAIvI5$XewXg(!lTc1uM zjFpbDe!{!$`XzR_qa%Zvh~_P&q+j3f-&1==AN|AXcMjxsWCt!j^YCH%;iji&F5Yu# z+r=a=!WQ4i8_9Oy0Eu?u4^}4plFduO+nW0KpAoi=Ew%<`+hVqne38CAgRv86&&Y$m znS{QDrF^~=Cl$+@%1_%qv_Ci}z0Xqhc36E-%tfUgwYs{MR^_(m6+qjl-`7^}W8Xo) zX%4w{Q#W5b<6_&&duz6QIt1F5XQ?k69veKZt9AUs$@%(p&$lyL#W>2Pp6t=pRYBottZvsmp}Pj>uK+FnclB+@>SM@LAe!L3pk3eg6rF$2_S1svMddbaJ)j|05_8|j>~dO!Htt!Q@X)H?U)hB|J^v$PjJ+m>c&o{mZBHg{}4 z@3fK0M=ss-_x8N#+RlB|WwrmPtT=ioDRuYI*bT?WzO_m?|9f?=4Z>5+8)cLv+?u*; z_hJyVZJGTiRPE$5G^W(GM}Qw}xkp_?!iCVbh>UxR8gny*w)O1Vy!nuy=?`J`AxYq368Qd;i$%F>_V+&F7wW?_$#pD;M3Iot~7@RX=!fN#0lY4rXLok7e$J zo+?|}!^)G$xrGlk?o*x>8JiIo5tq&$j*E=XjE_jjK-&`5pge=Nh}Mva>{RBaHlS+* zkBCc)i%w`~4Fw4$v61n~X^E8-2Cu%n+Kcl|Ptq91h}uUR;}QE1X!|AGFO^QT#TdwK z_Bw{`mri4FB?xiF7IrU061-E zXF=Yi$b@n~v&3D_BRL;9qW1xB8Q#a)P2K;x#SB{g0Pf|KO{>TAGqCp@ur&e)Q9r=y zT0daBYyE&*TRX+d`-P^1R>U|{0#zV&X0Sx!-zOPIwU8JuqkW)sL2hc0_M zf9QI)kOjMFv+RSjN%R4I)=$HF)8}F@`pi5Zh?DwL1{fECi|1NCm%HjTyVpsn2}jP3 z;eF_|4xa~|256pinjmviYOb^kKHVi{IO0?~{e5pb&04%FHB(Lp-d6%{l4HA0FFSOa z>4(&y)3t!-Ab6nF1o<$vd@fy6r`ghalv>!iGQe;MFs!eZ&riJRHG9dkVq*-Z>`Tg>G9Ny4@oiKk1~~N)hu_Zefe0+s0U6mmUlF+LfC@ zr*Bm5L|f=K`gPLnc!O@==&IW(s6SGR`XezouZcBgn)i@v!QzH28zfRItzwtYn(_iK zO)8IVuA1}7sAs19^7Nu_o{^oD%X-fA+u&asSDtzxBH@XQ{QRRn4Vg&MCqGlEoW;)N z1E`^jnJv~-k;#oMM0@q%A|ftbl!l{|ZlZw*g`xWL;~uxKL06OE)tA+)DSiVT?B_ zJG0-IZ>uT|{e~$&CowbDT2a@v^<&(UP{z;Rx9`1?mDY+ZbAC~bC1vwj8$+v+6eP#k zYZ!y_9M%})YrTD=-~4c6aDm6LcOH}*d0>5!co5fIJ?EQIXUZ?j01I-GvkfeWj&-m= z#hTy>Z1+~&*-=E9jBdLKj%{5Jo4VSbu2=)>-&!3TwGvRip|379G(0M!t!%pOSZ8=% zT4_ODwx!v>DlscJF`Iq2s%JxWNOWbFDKI(E$3M+nUfWZWVhT#mh*MMUicZLhi%j-q zEUh@Dv?K-F-_ll7O|_qZ+Egu0E#A|+2j|CrXe&fqRsg@;3;o4+RMYKRIw&h^x-rF< zKchT~ylQ+$yx+HTu0cz#XG$%9h9zjN5Br4b<=H#6wixytvR#ttxu+z0rnDn3_gCr+*(s6NC2OCzN1uP0Pja%JOD;;A zb0wR9N%<@GDJZ|+Xr*3>q9P)bqWPC{b2rs*%Gp$RRcdrZj5#J8 z8wXtR0eyC;7SImdp*MSm+k0qaWbZ-#3@*xB5;DWk&MbL|`Xt~!&ZwHT%y~Uy z9{sI;12XbAdw;aMkDq4?x|&+>qgwR-R?l6{!J4m1^J%d&qF?wrT+y6Xuy3w|IOaTzfY@frGW zbfYlvK1aP-@BsZ9{e`hlI)7gf5tkZ^K5xeFxbXP29|hoG^4DXdVlrYQV>0P?TtrOf z9agIj@8489-7D@914q2Vn>#jk{32I)e=#uu&__g8i47b2aMOD!(RUb z_WEscA37|nW^KqzQc|gJ`_7@2GgNNf1-rX zX5(GlbVoUFFkVTnjr~{q*mwo&R`#)vo2#nIjbr0-`5(BBJpxIl{cp+*aLVRH2t@=f z@pLb^nrY9XUtBg7^Jg@mUZe}q!{{n>@`FSh zlA!>ySf|R|JnIz6nY_V64yNE8;t#qz71bA<;B}KJBit{$Uz4iiU=S_Lv!Zy0av^d( zOz1rw=AykMrz40{b_eP+@)YH>$jPF4sXdwMu*}NnG-NsvEl8jKrWQzj)b*)?=nEHa z@zu5H^uxtSQ9T+{7A$oqrMAFgDa89^w|vzv;{9-k-dHtxLkGIT^i`Dll&jVCVU=l8 zQ?9HkDleZR1CM%LF92%!zc%Fx?U^aDs4px(=ZY`eq&=%B+iQ}(If)t)yf@uvOS^F}4mbhGvxpv0M8(w>9DUe38!dk$7Is=uQ>hbkd8 zA=+~oo{7@` zrPOqf_8gS{i0LiuIaukeK397VRg$a!ragx#$u%kR8AwFdd{KMG-geEk+B5QqYG$=( z%&%(tlon-PSx}BCi^{ZeK$%jO6*FpJ6eGL07^lYd=Tba1VfAfZ*{@9Cc@S?bq3wh+ zi{ECYOPN!~@a-b{qJKxlcjJgk>Ae~JXI2L6BhVWIcy|dui^^gAOD&a_`GsSP(+8%O z&85X9#rgDaskv!c+3EfB zGvf--TE^=$Xgr2LmPco%@w)`D7GqDQ7}@bnN~_Y0TIe-Sqv~VI5ex90^N7@~e78@$ zt&|iNmlfAEwKliaNMHySfKs4?(zT3l`hbQ}fGX^K*ykuR<#hzm6W7m|vbOoSEKVT3B9KUR8`&jnr5V)iqwb zlh?T`GXN!#8O6`C5a)5h!cjaQ!e{e9=c6eE^-N@4hN_Wx4&$$B{6#82!b+^7zvSq1 z__PS4E#f;OBE3V;q-ra8lVF<`tx4{s7*8*mN6pKNqvI2^ql<^k^OI|+ka>E}ygW5w z9-f(-TV=;iFgp#k&G4P{~o?LB^pK0%2A< zHLR5W(UloY}0} zM~)PZk_9Ooo1ZOOKDL0b{%0*7-FZ(|bbavV3LASwh`j-GIC}<^HNE1E*N|MhZ zRU`Ewr6zUKm2nWZvKxQ*2^k_ab@begvB;yy9>_C#vXtZ-+~IQ`T{kYI#0x@w2_EvR zGx+3)kO=Zw^r_CB8Nf}xYZO*?6raxE-~ITPq`@IQWUktwrCUYIW$269MHZKU1DT8k z;JgG_$_x~gMIXKY|@7gQy>cj6LJavOhE#lKb{OgSm zWQRFraTSBH+x*L)rk^$ObC3zyvFpGaFIwQGU5Vl8J zA_)u0FGY4FiF(X8EuuLybWpci3+Q!TIf!1ygv^oV=uoVnR~avoebaGsyi2k=At2PF zkqPun-!F>3bgGP^Z}J8*${G{+O8p_tn*$wJ@LOU{-xB1r0)Odzr3)paQm7!^{SjfS#_+F$HpEqmkVqb7RK0}nC8tRD_5O)d zIwaC|$vziE+hvSQR*c>yy*AndN60|Bu1g%*O@d!a2aQ8qB+Ek(>0EHOSp<*H7ukxe zk%W2$?-5)?Kcevpo{6IJlUejke@|+kIq)Lh(l_)D*`)n=QxAl6D$fY&j0(sIM&c#) z;DD5tt3e%27}`lZ^bzMoPts$M zl#|}*(ynuRNzi~~k)%OVhp-}9BwH;hLQ+cKjpIN4v$bd;MgsO(Bxo!dHXPel>Wbe5wNJf7Z{bfme(5x_B7;por=qJWGMb?f0Q=|*^|@6*A*X+a~3y`=q<7RV?! z)GKKOy+JxHHPki6@Dz&>1?KS<(OSoB6neY>tfcHpzpu;RJY;hPW9YCrY^07o`E)6@ zx-L89n{akSJcO4w4mj*ZE4)%Wd~Pp(hVVmvcu-iAG(&teh@OqIm!?r;5|EO0(kZ0F zMBE}Nl)i+l196esxpUO0#b%H3dnfuKji<44&`AIh zi?f72$%gAPBKfJ?aHHKIt3ul7Sch<6NH&J70%1(@>Kv09HN%eq)^%d;_H53Pv4OD)>}{nO))gJ zH$y5&AEd?--{q$i*O2DX=(4pAtK@)@OBBU8Q`@=CsU$(_4e2K7AdMrXh9UxKkx3IJ zA0=jzUwVY;poolr){+is%_-g^={SPlBqJ0FQZzefx4%a2HVN7hJr;3#N7^x0>!(wP zxIuRMfaqU(HyS}=G=XpBXVQNkz+dE%NsHv?qER@N1QC%k{9%3ho~({k@Os-(=$$Q z%gEc&hPOMd!v~@(TQMjwL?TvYE3gDS6?Kx=u~!F z#;bZ9AmdWfGvgdY!bSX|m2e&VQi1(PA9ww{bDe9t&r7^X97&p#xQ{XiA?mI*3!#{c zbl0eTQet!sC2s2SAlDjbM&M{Kc_w$RWCSf&>U5~(+n!?YLi92uWR9Xy>XGo&XKo}D z`aDoZfzC3j$AknY$yxz^%Q-6bMV9I){w3d}$F@X^DR>EzlsU8~ij%i?tmTpX%asfn zGfVlC(&?Z9%?`*9(ZADZPh&~`5+$kigvZ{={t&b@BK?-IkxY&YozZ8M`gl495{mtz zXNm&IB0I1mIunmP&CloY4Z%jO9pgCDnJ|{?kkl{fD|uW=ap#Cj+So;d{#Z2YL7wbX zTKZ9RMULo@zX8BS7&+$34hyBP&l~3-a!y0kAzIR$j%1T;fx}-D_ekobkMisdo&BF4 z>FE+d`m%`s2sRmGIpV(-At%mpxpB6n>wwe`*@uhRz3wOnlU_(z$J1yDAg>mOAU`Q>VCdJb5b29d8-uF~%s) z(So-7bhsQGcb`?r6+G#a_1V1i2ND~yr4mc2!Q`2V|700R3TQ2WG@o=vY8`2-Tmd0& z$ZyDc5HC(8@v_&WkhlrR1#v-+O&0eM`k?g{lF)GxH90WU?XM#ylycyi9_yvEw33cd zJX4x@q1z$7tz4)0Xd2}3wdGE-tXt?ji)F>a+-9C{4e=}IdDeW2%T4l@hz>anRprd0e9(*QlD_BdaQ7 zW0EoH@g3099BdHtv2MWL1^YoWHVJzto@w_`-(?%bQ#WO`!r$6w&B|$Z07eNy}{s@Co%z2^78JuPta#^Fxx} zHf6gQqYb^$czqa;#_qwVwDU(}QagHs@EFG5^xT2ZnziwI@fM9s?P)$rJR?Yl@VR4D zXQ-%WIUYeKDboTRB+O0doA!pOuN`81S`i(>xH_CfIfAqaKmGW30N>I+WjET^yn5;7zF*=z!B<6 zenRh)^pJeFXcUxvO6ex5>TM+rZ>FU z9@Cfvvkni*EXk6t2@a}|mJuX067ib;q7g_FNRs+MQ~FNVLOF)c$6@iV-YdQ5OkZ7F z^mh7tYgq_MBYkY@+krbt2hmbONL-fGICZ}tJ~Pmq<1zgwH{X0@dU?v8D`;+?pIbKf zj?PY)vt{yBw&$Ee^Z#^eRgiy>|IidNw**9k^OMU*Mi(c{_y8G)6LU+*&03ioM>ZBE zYYldFoBI|f=49h;*&yHS$f7GLwD+gIPCbpyFHEDK{S!0uNAfAhi#{BkS(-PG9v+>Z z8QniKA;~jpZg1LZ9$l_BYgAksTby24UMgIgo++GPJW$lv-c17(eDwbX`3ofa+j`CI zeZ52G?yi=$-oZ8_4(0-LX@$9cV*ldG=;ATtf)-o0I&Vr2n|tIJ|E@$J~+1ll6+abj{3UkFe}$0%=adQ9+V zW_s?x$~1-^L+7)zD@f8q9-ibKU_$SQ364?ogqsPF0^U@TM8kZ6}4&acceu1ZYtJODF^0#fh1TQHQbX_@&^IZ zm<&eXvr#Zqw-^p9VjiCd)HK-W!UCv|wt{~1V=JN;A(233Wr;{jY9X16&hf|eq5(lE z7p-mWUAYm@FWSBvVj3*I;H;+y(Yt|WNR!d@EqHJ2CE3lFM_aVD|dTw+^w{ync ziAH2XU@yoffZ0yuBnz-GKZo8Rc1vcXDtV`&9JNQ+Ld`=MM-}XMsLw2{4+-+ zqjMn50SMgU>?qm7Mf#WwrY?%k!2?Q#mIh1{YbU4# z0R3$PJzax?&?m~Xase_NG+39Gg|#6G?dOwvvcES zjiO`;mti3bM&VHrv`idbHfzRjYGrnGt^nc2xQOzm@IaOsaD$v=c;F5e=NA^IDZrTp zkWdgu^Vx}Iyts@oV|rp{d`Scc^d1d>F80HsAwZLc9Y8qz`81%)7DFJ6G_cfZp9~OaB2+vt*t)x&Zo3FAKe1MtB5`GN_@Ze`IW= z1zv=YhoKeruf@(1>6SDvgBCCYnw_4bCJpkB9h+DXYCSr3Xm0)pVyOd?c&D3H};8%BEuD9^4eiTKLsHNgu6Phg&Vm?X`i zcu6Co@kQBQxHurN=%k&ns{ivbnG+=hiH6AK^fpl(rp+TYlYyWT#*<>c6-Wee;_&=5 zqWwwT(h_5I^P`(;dsqv_7u~mZ4YqVQb@j9jp!d!;Ib|E{YaiOyG|*=58Z`G0^o?}2 zwzZnmng;QATE2N(*HCBQ@Q@iT2AX<@c3}2kZtC4(-qO|Ens08~j+xltpt*0r+||?H z-PMNAx_Vo>hg-XPJIu{^ueXmTg*{zE=ya%0ysCB8)rR-l%>bsQ6FoOIcXf9S?Z`K` zcMbJYpY7AD8m zS^ywgg4{qJpQ0xO8G~(Ghw%a0=|g}Aooxbiz}$rYw~%;9jC+A0^)u8r02*kZZ0j0q z%QrU-bPW;{+6Vf2&^cHE8WE1eAR(GU%p|F{b!~0yxk(PXLSH;-E?w=-k-&j_Y+@5GZP0!X9}m5XVHqb>>Np%`jJ6eoL$5> z`WZU?C@8g;hYIw=qO@#9Tjz2!MA6S@+K*3Cd)msO#4lRT??M-duP0%t@Ysa+XuEF_ zTLAjD{Q-PDgNSpEoG<<1q0OkV4gMHJFO(AIII>Hq;n1HrJ&R{lZCphe@zpQl1dNCO zsZ@iCp_Pi$%07xO&LeNY>2rUaeho@;{1LzYK6q2&O$tDI3(hH zd@|1Ao0U|o_NOZuxNS5GC(?4TyOyVH!ir-7xKf1EH6<9^f^)LvID=zVDskGg8fQXl zl{%#!^-LSZdSi=NHEtIx+FiltEwW3M z=agSDKjlv40p%U#ZRK6%Q_5$R|5U!Ed=5KtW6CvP*LT61Z!6zXUR0h}zNfsPybd=0 zm-2n(2g>KML;9w2t@0D)N6L>ObAM9)qFjbkEz{UXCFz?}?t=K7j$KyTy`>z=!`Q`q z1AG3*u~U17a+Y$Y@`Un9U1G2l!Ym) zOkv?H0<}XKi(=6%hQ+ct7S9q`B1>Y)EQOhs_mvM=DobPOEQ4jTESAl3ST4(Bn^->X zSSrK?_r=OTm7lT_R*Kr9WvrZ4Fe|E5R zot>Z8vOd<&wz2^>$cET38&Q6*{DEy_+u07b6E!k-vpsAtJB{sQ zqijDLW8-XsO|k=QicPbF%9q(8Hp6DwobsyjM>fwE*y(JMEwN>`!Va?|>?k|Nj>_qCyM$fJE@PLokFhJ*mFy~ZHM@pg%dTVBvm4lr>?U?I zyM^7#ZezDAFDbuecd(DMJJ~1LUCPguUnsv+extms{F;4|eTv=9?qQ#1_p;Bh``G>L z0rnt!h<%oQj(wgz%)Y=LVUM!M*caL3>_6BO>`UxP<#zUE_7(ONdzyWfJ;T1np2eM4 zUuWN7-(=rn-)8^GzQexDo@d`>c(ldyl=( zK4AZ3|6(WDNoHfKD8b4&M{RNw_rc9QetZMp$o+W$59C2Sn1}FC9>&9Y1dqfWjL|%X z$MQHH&l7kePvXfug`0UQPvhx4gJ<$Ap3QT3F3;necs?)Sg}jIt^AcXlExe4E^9pX| zmAr~q^BP{u>v%nH;ElYAH}e+W%G-E5@8F%hi*M#zcsK9CEtGw{pKs*@e2@?EVLrmQ zDUT?R^6kpw%6}+dR~}QosC+{?UwKx!M0rs8Cf~t#Do-n4RldS^@!fn6-^)+q`}io| z&&T*UpWu`H0H5O1{2)KXXZS3innOQn^jJRrwpgieIgKTDeZSL-~wywQ_@U zBfo}U%dg|t^Bee${3d=gzlGn*Z&SX+Z|8ULkMleEC-_~;Gs@TaC;6xN-TWT@X?`#N z48M=x&mZ6q@`w0m`RDlO`NRAR{1N^re~f>TKhFPyKf%AmpX6WWU*S*jr}ev`e>Ff2RD;xDHAD?n!_;s!LXA|T z)MzzEjaB2+cr`&yRFl+XHAOY6sVZvKs2OUenx$r|Iclz&r*2a7)dICpEmDis617yd zsAX!oTA^CiO0`O@R%_H+wN9;98`MU%No`hJ)K;}kZC5+gPPI$jtZq@e)gC{rXcreZ z6>Gm+H!L5SFI-w#Sn^+Ze$a#oDi(bFM&)ncru~apNA(>Qzxs}1>V3{FZq==U0>l{+5s?tARNWdFM5RW7C=wJ! z9AYu6B~&vgnBm!K(4_6OF?2KrhZrQbQ_v7|V~C;>oKOK#P!SOo@LItVu^w$~&->Tf z``mk~C{XitI`4hoJLg+_?X#z~$Ft%P$D0(n zBsC7##!s`&Z&H+V8g0vI!ikTuxn@RkRaDws6;<&uHrGtsX)_y}XYt-Wt9i!M+%sHL zW<{G+QSWj#6rC|+-puKZv*%sb)HrW$(X8lGe4M2@J3_P4HL7xOe4M2@+oCgV+Bu2} z&dhd3!JMq$Qmu5@rK;@#@YK*QT$nbJ+Dxt;<*E%Bd@}@pZ1Z>dM`7g~M(()VUF= z8|=b|I6TzhYKPsNtE-KlYP);7A{$%pQq|j3$ue6?vdor}EVJ>+G8bQNsU<6Ht&)|t zw#iDDzN#!fLzz1K2<)yY=<)xNrd8s8@UTTS! zms+CbrM9x=rM8mgWv<*ZSFY=)@}zrCIyy;5C+X-U9i60Yba{DMywSE|l0{Q2vK&4> z-9BAv(Pb9dogv_28y#wP9uTN$o(eb|6?A z0@mpV){X&d$CTAuE(q2Jg0+EQ?MSdoU+&UZXvdY++ld5r`)t8nF2 zy7DSrd6haaW%ZS=J(l_K?AlZ1+EeA)W0_G|eU%Or*yXQs`Kw%iR5irU;Y5_}^a_j4 zv5esgMTv7z>vD{F@tnjJq0jd35SQPwg)%-8oA( zYS%y2uK%lD|5Uqjs$Kt7yZ)(m{ZsAwr`olz+O@Abr0e>p#`RB)qhI6b*Esq$j(&}! zU*qW4IQlh?evPAF>wT^zRqhIUj*E;&Oj()A9U+d^w zZc$cmxdqtKx7>nfN8hqvo?ZJb`z@=t>=*3lTlUMdqhIIf*E#x@{Sxo!*SYrBx%SsN z`gN}V>m2<$*Zw+3zs|M4-nGBp(XV&yuXpt89sPPozuvXK-qEjj^y?jc%h=26En^2e z`t^=}y`x|6=r=g}4Q26j?L=Ro$j;gZN4>#OZ*bHb9Q6iAy+NsqWlH|Ei>J>+G1NF` zh7`ev%QS1Uv|JkoE>B!Jb++SS7b|BD04X^s=0@mLvqQdY*EG$*Wy_-su`XKO;buqJrJ znvl@dWYU~=HJLQ0eN86KDHLgw4O6RCgn}DYEdu&n^dmV<7te0A-Bn!`Z$>>bw=ri5 z)*w0c^JdSo5q5zlOYH&$yMDC`k7u2D$uhemfpv(IWtO3Xs}d+{kbF_RNFSh2n>{5# zAE;+ef*@_wj6!|ou>Ls((hbgEsO@(TTB)+3rMZo>XV1D~UbA~nCiHpAtSeOPNha+^ zn@qZC-~^0hC43LfQR8%%v(oaLWToXV;K4S2iY=$o@{eSt?$^wG%`Mj%o*DCA;s#ljITW7tIYTYXM965zM71$ zF5}Czr6yBeO{Tn>OnEg@o_i6ceblEY^0r5Hr@QJFX5aQK4c^ZvFVD)ZA=xCvigXC= zuu)_aiR>$vcvR9YX^hLORaj1WZJ510)4K9Z>&j_eUelZ=_*O|{&NPa%ETehmyvvkj zs7F|ac-(8bcrDAYK4BS}PFRMfvn)fsx^OhqvJB0ltZ;5fLp?%6JdTEVEe-1v8k$aM zXgW(ny_SY1RJNo(r7o3Ss6ATecNSLxXlK`I>TUCr`BxB%vrXF)gv_%kE@w@ZOyDtYNqL=W}42{Oue>d znow&dz6ev6$0$>l=dfntcQq5Qtr-oQtz)kqshN0O&BSYKW_?mKO(!+ebhc*dwKda( zS~KxQY9^1-n#prmGx58ciMMFh>?zZ*i_~Ho5r0j@UmNi^ zWc|rVnaOCGLtxz%#li!4cN2d$k3N@0;-YPmw6&4AC|!vwjl@O!1;M2>EK~gvdh#6R zQ-6oJp{`7ci}r;)mq+5FeOwixr~XKp@*L7re}}k`p2S7z$#Y0g{gO{NCHlm%NxpDh z!W3z4oIJHerbyw;N!bTCN2K0Wk$USKu(~xb2+*Z@JQM==bL#D*D~q8y^3WZv<7quQ z6VJTI?V|^gFCBlx?VH``eLV9yw~yARukq059Ls@!Kko|s^SvK)eEVDtsdcP4tg9KsDP=R4A*@xMTq z_|;PPXl!ia%Vxq|&E=CPU)F5CD;&!FNJhup*mUvqMsurh26LxyVzU$mG1J^HyNh{v zj^s^Y!#d5Znlq=g%shviG;49o&8xT-X0uo_nr*^5&>Y&nux;fl_h>}3dQoYcd;?nk zqh0i)^31<^4+$ycNCWz35mTMW^x{^XhfR zmN6;HUrWhS)Mm81;GDQ(Kc{cbNF6yZ=X{4Z*%V!#v?b&&c6hzTd3hQi%PY()&70xE z>^Hx?yw~k>qMO4F4u99-hb_(@;P5zyQx0#jbtvfOuuE4kgf$R1SE1$jIr_fEs`0zc z`?g>0T_k!xf3#@+VqMWVUT*b&XdbUX_jr4($iG!JIJZZ%H4liMLv=QP%xGn9L%*}c zzZ0#@Gpd(agEr@v=xWYE7jj@t2>KEiy_Y*Q5D-6|Lv% zXgs%gThVpCi=J~QTFk$qSNoDWE;vtrbV~!#E0v&AN}^AyLYFiwHiACbg)PDWtO;pA#!UBlZ{n zL;iUwKxZ}r4d#nJb3bPM-R3)JGhgywvT7`Lh2ePhHTx)u9R9!2fNKRkXIdT45A}JF~v1!%E@|QuSxWbcLH70YCB00PjlN zq`D*39f#|Y<_7xdezdX572rf3)*HfX{C2Snz9-+EmvAZ5qf|+CD6R(=l6YD3p0^-U z(qV)cEJGyCM=sW5Y~-Jas<7DT0`5V4Z__U}g7$qcmc;!|tQ7aE82?7#&5sSjT|hna z;iQL{Ua?`CLe~FPu_{eb(ILe^4IO}cO{~Af#rok2$BAJ{@ICK;;d_zN`eTDK3?4d$ zn#i|uFJ~=@{&y+14UeLmmfl%SPH9&TeAM~;f5-P74Qma4cd*j0}Pj-DR!}~@U=C8yjdAqTH48Xc(5Nluv zEt21Vj%HNk_jXvuFn4048Uxt9*p5lB1Fzu&uDEBQ_|@%tuEyd<>~R*N?Y|!Tm>*$} zbA$QU3^%&T{8TjW%*dO~E$n2!U^H&SBIgdQXP#t4R;%^R8b)s|JKF}VZ8kA3o6Qz1 zIkq7|ZD*B-JWDKi{?q&w`6<9kCgyeVa}C$ZV&({}WqNykyuL_N{jrW2 zh-FNPSBgE1Si=m)5@tB|FC(yhsl)DNq&FICmoZqnjKj+1Y^+=Ez;fhQSdIJ|i;?@V z7Ws|$5OyNJ!$#x}Scm)x%aA9q3i&e@A^|PX=3@u; z9v@)q@ga5|A7kV3zlAem+Yw;b5yPe<7kiEZY&nXt<2VQ#jzh8EI1<~9qp{mK7MqRZ zvDaWuB0Y3f-F+dPtP{OHDRPu^803&*p1O0#;32&T*W79q@Ht$t6N`ZZ=H}n(V!|(E ze#uM|{t%sMBKu9E1dn=&R3vG7wM%2;L`tHT*p!@tXTCq593T0t2CNTyGRtAb@CuQb z_}?O2naA0j$e1d_O2|k4r&`tsbCg;Hg%ZM|jEpevfKr0U1Lsh7jMa1jCCT1+1pD3v z)Z6xzSh?(CzZik_)?D_0nydv3DZZ$u#S*3!>x@pUWWFGGiRsztp1Eyb8xTtJb$kt0 zBX7e&eJt;Kepw5WNbVQ?jhdU@^jp3_`Z&3B!C3eG+2&B*;f#7yJK0F(BBY-i_b1Ij?J$#w zTJ@+D_!Olj;Kfd&!a@$YNH{<9xKQkgoGcnjn`%o$o^^(2PxWSh8pys> z#eP)7J~W2?XQFozHk3_RO3ueB@>(n)Z^YVhF_w(?AaO7E9>pqgH5Q2Lk-N7bZ>O;$ zZ1X3r<$W?)k{7yG%Zu#~%jQ-xcwbX$U4 zH`BitccQw>)cujV^CIp8>c3fBvt9kaRd=z5w5mU)?p^BsTHR|S{;SnL)Bg>$CaeE; zb(_?EN8K6fo}um~>NfcBe6tOS-1ANpzqeQYL)Cw>|1Ke?Xqv4OZr<`&XWVx*#OB?u z>Cabpq`DWW`z>_~)$J;-*@^9-=hbLPiMn^I+uvtz^LnZO2ywBMWW2q5wVqn0tEcTx ztrc>;^sUy`_8V4)lDAI7S9)#4+J3MUH)yyG8LqVM&=4DId)3nVy~bK9)@|mU#`Bu| zXJ~~|@$xmVb;~rpb&nRm*4Bq3_QNjQ=x%rfvfK5no?E#qk(3`rmS4#|82RjJ*2n8u z*AC;ov6c1uG51MovwX7H9Gel$;o+tRxr#4Xh_$demAO38jKWIzd@~w5;S0?-u?(JJ zPQw;>mN{KdvBtnDe{RkY8%r}*Y$we)c7j!$eT3&z2A+0|Dc19;UV5HYp(k0D)XE?q z8l*#G(m*TF27JcSl(Q7%5sz~g4~fF#&*Z#5K!0EmfNi`t1UMO}14aX5fwO`0fl0s& zU?#xd(C|iOysLnPzzx7nz%9V-z!KnIU>WcTumX4zcm{Y8*Z{l^Yz4LhEx>MIFYr0+ zBL~O_I8X99U-EkaeHovbI!b>J_j;KZ=D*7wq4l(-S--Ab^N;eMr1gnXAH(ksJbp`1 z$es|sIrnED_PpMPLC~4wF}KD4yt?>&2$U>mu5X__4xJ3>Q_QTJ#KKTrML#WiVlU(uA^HTEryJzd?N8oNr}SJiFRG=EX| zO?A`izM<|^b(aPr?I?9KPC|loaBwDMjD&d2nsTSQtJLiquoHXZ#5Ld2kcZU$4|Usu z_XvMR{NAY=vQpjo0b^#CtKZh@OieRX-M$*G<$H&!-C#$KSbuF`&cRby`pM2?dh z`ke3fwf;Tl$vXC_G+=Jw^diz%y!TJ)s`CF~!=C|&+dNOE0> zwB>nA$>p&p$T~Sw{l}>bUncxKb@_)+VjI-ms3B*m|5SD7YY04>G}5aBGG`(q9i@-y zwY!N$GLCVkLds6oCvu+5jd9di&h>>Gc;;uabDAHk>|k9vPx?ORN&kNr`g`m@w#@&o z{U^HfME(Dl?Ls~DEdt%eFn$SfNvt_`b$mkn!gzE1`|(@iOXJJqPsX>#)A7CW<+(k8 zez_&N!*j>vo|St^?)=<^xr=k}&D)f>CGXw5U5T8$O^LpVK|o(Zw(vA8J|S@$cw(X{ z@%_Z2#9fJHiBI$UqVpH*0?M>RGwWa3Sx@T%CwGL|<)>3K{g4BvSB~B}znCZ!AuO7gk?OW>$ z`>Hdn?Uc4gAZ)9&za!Y*k{+{AJhpgj?2_Usi5%$-YJ1mLy6-7&e?Qvo+HODUwz%8F z-PUy5-feI99^EUtkM4d^_u1X&cVF0jQTL_YS9aghBc})2bZ=^~!7l?Uf(<6m-w?F< zuLSS<8-rH=ouI{kkLMl0`@vTK1Koj(0?}}adpca6e_iK2B*yR2`URWJ3BfW`7qplL z;8b8FFd8_WcbakFvw(Bh6()eMCjB+QwZIR6g}`;dUBvwgSOVM)ECqfI+yndva4&El za6j+>upIau@CfjGAO$=M{1I3I{0Vprc#^W80P5%u&|0WSgT zC~rMsFM~ILUje@g-U!|VehvIO_zm!8@SET*;J3hA!Eb}Nf!_hY3w{s09lQg)6PyNG zfL%ZWKG!+!)|Zura%{|^B3!)Jc@ zE121T0v-b%2UY@408au>1)Lu+&sXSdU%?#i&sg_o4EpP;X=By2v1;0o*ouPdORrZR4pK$!J0Fpg)asOo>}zq!*?I+vR`5nM*^1J?30W zJde5644nl~m^Rpj34;;5(ATH^RWJonU$%(oy|&Qnrz zEJIGsb2&Bf13_P56pN<@RE^VGjea@$@H&MS|5Vsh( z4Y(b+gLID*_XMz>c;+JGF~#c>EcW^W@E@-~FaQ_`3<64kQh<^2lEE^sob^!w9zobh zU^H+VFa{V4OrV^Jl*#*-_XPf@fIkzyn*2|Lp8-D$eh&OR<*Y$3a4`S=|~jOTb|Al zn@HW0)PqQwM|=-`>L+Q4FA8>Qsm=VC{4{2uglr>3W)-u55UG!hr-U44OSa{Z-_8^% z)yBzu7F(X7%&TF{$KlND)0sPWfImUgUK+GAQfnEdwTwiP-fyMnTj}*ydVDQCx|ZHt zOHZz)7uTZOc#$=-Hu%h67wqxZ2V4A?@x%B0SA*UDHg+-Q3A@)W)5V87V!xB`uLopb zd!PDMv2SfPRrm%6DQeZin%PRNR-2P(ldQw5dAO?{VM>{7(VTllBGDtRv0K zz$?H;;5Fb4;7#By;BDX?;5}dmbKuxuH9fPMo>@)LtmfRMA1&%n?FIr#paQ63mmds= z8ltUT!x(IKEl#m>r`fsF?A&Q~?z9<24~zz%&U>Sr5}XBGO}=Y@Yk?mC3xVr^A5!)r z;NO9t0XGA;0Jj3aAbv4$8*n>t2XGf<{R&tD+zl)Rehu6M$a%uOz_ zCCs`dth3Fmv(2ot&CI|QvoD1dk!A*_kRsB|!W2?OnwgkFibyjXQ%DhMW@HK}BF(H! zAw{H_nJJ`*G_x~>6p?0zrjR1i%+eH6M4FkJLW)QuMWm4;(nt~LSb*KY9-s}_3;Y-L z{2UxGvrUlpJ+KdsfpfrJz;SRcI1iiv=YtEth2SD^S8y@78@M~T2lyaxPw>G(3a*`k zYp3AaDY$kDuAPEwr&viTR#J+Ulwu{N{F~t9KLr*6%x|QUw0{eJ<}H#*8p$M$WRgZQ zNh6u0edaBaNgBx{jbxHWGD#zuq>)V0NG53{lQfb^8p$M$WRgZQNh6u0kxbG^CTS#- zv=0YRPP-gVyH@x=oOTVIwr}t*Pc7`0?ChMdGzZVX+l3pSf{YFCCa&4^hRf!w^s*`w zmhZxZ*Tb=~3eu9v)og|nC%Vp4*mIgWN%PHQ_K1HD=He>~RziD)DTdR23J>iD4;|pI zgO{#{yS@zGK=`Y`HsD>J-y_X-@DA`!!qUN~T9;+oq87Nn(Co%e(FW%a>pp>+-@}f8 zTo#qv_bWq-?A(dGd_Z~fZfd*~_%#46Mhxv5a363#@Br{2@Ec$m@DT7Y@LOOx@H^lU z;P*fZ_yh1L@JH(H@!qrz?eRKVydHQNcqQ0PUr!1ClMs2Y+D<>U@optD;}m=^k!Bsc z(aV6uZltFqrj?jBO4>~+yNPL)_c40U#z@F!4Ux3lUD`I%3Jse!Ph(yTwy`%#NiEc1 zGbvi!Xtip+qSUu(z1StGlg$&BD6M*jQnK%YEwonl)EHDgm3@>kMzUy^!q!&uy&vr4 z-O;wWg;^3U$;RYT&K_vA`tP=j-Auk#ECHtIUfxEmypgu}+iBMh@J=ngO{q&ie;TcU z((FR1%*uA9Zf91XMsK1ULTbuoZibdUVuvH&VPc(e=W-HyJd%ujfvJ$Q*Ke@il6uyB z3M-`->!g9yBavzQU?nz&)MGh=K8~**P38<*{%x>=?;B0$e0l+QmHB7vw+3Us^+Pl! zH*ufB3GXeO=HAK|lj_ZHO^RR_x4@0 zgD)ukK+m|ZS8J^wVz2dA?7^_vGC#&@%QHXW`%F3JCUoI(zSWfH6`Ms~cQlBLISsEh z&tR8zu6dDf3|(lp@m--QW;<3{ckmsdUwXeZJLRiB=6$~Ev($Vb-}Nyq*lFEoc44da zfccOw`z$l9eB0+?^AQ^JHWjh+PP@OK@E(~v4-6uXbYAHn}ZeX)j0t&yM`mcy|xrGGN|zgO8$VC05dgdH;Sm+jEvi`&v+kt<*3b z_8;TKMaW9U+oeU}6`$g^no?^o%Uc$%mu}ws+pk9s6P5(q!bqQ2J+a=#S#yN+`4idjU>3 z80q;E8!bE7&6}Z)G-+D)R~O%yOQ2 z!`GWrK>RC$$7syOp)bnG`pzv9*kr;OZ*-QHRTpKP?t6!MeA-p|f1qj3nP*Z?um=f|C^h zjo>d?BEeQ$LU#Q1d3!bm>9;XMM6jf9s`vZA*!?Cs_Ztmgn--{Vn;GGw7^EZtr-B zBqC$adkyj;7rhhdyKM4cdFXfjl22NBOZ`e0YioIMuZ|USl&gO*AAUJsLpB5-gfrL{ z+F4B)%@&u4@!Fr@Z*&F2+PM8<$vMug>q=kmWQy%NXQtas3-JxS>yXPcNNpATy zi@gRQpY>{&MrP(`5&~|a2h^`AN^QDqJDhKz4R^7hA^k-zN{Q@JMC3&x+j-fYR?_Dm zNMP`BC*$8PwSCaNYy*9`hrD|_Ng!n*3moWT-C}7ItP%bovOs5PNwXhbnoXVUf9rEA z6HQTcZUpkY6-pw_?6)tnrDlEmsadD>(z&t^XR!PyTjCe_g2$+*uEWTR+T?iaF8W;N zaGLjIcZKWG_SOEzBTU^Hc4gl{xt)$fXL;I(DF=C2_sTol$9$D1p^j9vJ=hY=z_)4t zc{Qc1kzQ^zl}kx~v3giRVA+*cgFlPT1D-bnI(qxgb(LSgVBXp~?Z2O*)Krd?x`<31 z&brLF?bEt$oQeo%$io`kFuroPyP{oP+J&@# zIHvt$=E=|aLXZ4HI+3}>-__j*5py(k%ic%QiX+_}=9gAT8|-bgH8w{n{!)_3FQzTX zFEOH!;9XkiOV4zK9P&g#=va{S(d%GFLu}gYd5WC3$WD2zVmn4*PU-IiwF*IK7SQ)0 z6zVCAoWxit;;YyKU8zfF(47;TgJ`4t+OsSJQog;4v2n9)mwr92(=w!u5+^i;me|M1 ze32dtFZo9I|NLcV1~Q}8#rC1}X9(F5v2kH93hvm0(o-Qwk4b+?Tf>?0}|&-Iyxag>0|b{0^8I5$3GpVRj^}hN2Iel z9l}}um%n>+z8Srx#ABJ)UHoU68Q~>9;eyhi{C-${`#OC%`OIFzl|A=padvl=X94+b zVD#JglHAfU%I}ZBXBcH*;`WBx3(N7b=Z1a_egDn^=C_v`iHl)wVS(zlOF`_BQjurt0s2N z7Q&wC42Nk#oTb;%cNFV7?9YyI_E~0I2w{04&c+xk@m|KK6fl9tcTDRTGA595w2;;EB~WFPk!(RQexZ|iqpX~_CC|i(~XKy<$(a{O{$zlJ`aN>M; zl4w+=A31f|&lSpFUk)FNv>UzmEmVGcJQ@i~WGMMcj%cdn*XN?6iX$&&wNocJ?bOM{ zi(aa?>ZOiRz0`5&r7lFazKpw)|I?U-F6w*SgZT~3b!JGX8mT+bNc|GM)HhWxH9_@K z7ph+B3e`)^SH08%)k|Heda3WAm)gO13f_0xsXb<)YNxJO?bHpbo%&bRPTi>5sh_BJ z>L%4r{ZzG6zwkz&oqAfeQ_rh*>Mi-#3;s_-v{Ub?c51t7r*^1z>V4HtrByrCqS~py zsCH_XYNtL_?Nlq;sh7}Ht>eon1*)SuR&`YUR7Z83>Ztmwj_P>TQ4LTX)z?%O$32eUEXIT~FRj z<+~z2e_A(-e+-*xqQA%O$5_fG?=gAo!Cr8-=IT7umT1;K|IjUxY0c#`Ul9Dlj8FdQ F{{X0e^%npD diff --git a/cmd/mist/assets/qml/fonts/SourceSerifPro-Bold.ttf b/cmd/mist/assets/qml/fonts/SourceSerifPro-Bold.ttf deleted file mode 100644 index ac7837fd9ecae031470a4913aea9186602f0b2b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113188 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 diff --git a/cmd/mist/assets/qml/fonts/SourceSerifPro-Semibold.ttf b/cmd/mist/assets/qml/fonts/SourceSerifPro-Semibold.ttf deleted file mode 100644 index db2fc804b6496baf401bde1692985380b989be5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114352 zcmeFa33y~xnKypUtt6E_snovT+AFnXsU($s>m;3}J4x?J@B7Bq?2RnlAR;!1*aD-7 zh>W11!?b|V1Q!OCQ50+u5dooD(;IF zF6Z6Od(LH?F;;^=1x)VmTQ+!w>zZ#c-g*Sk_JL(13%6Bvjxv7BON?25vT$-@*;`*< z`#HuJJjvMR@`cM*^gq4%CmP1v${8ztcw$*yEk%;3l8!R>o?oKiG>Lkb<3!gtQxvFXe`v$G7(YyBZUFWzzTdE2j; z`Q5qrZG8Xn*v@U6w(>V>yK!#}pSSD;K)b!*30!Z*wSVU+XYFO$*83Qfit+U;Pd;tS zrf)y>27b%12nY_JvT5(0f^KOO?!O%O%cpKSW!q0LZ3Hf_J-}G!);*`4c~;ALPu$IT zExuFr&wI|;w&$9&|M+>v^gqGYpz@K@v2{JsOtO!E780H2>aoFl zLT2nU1mjOjH{u{ONxFbd5`?{=H0cYhP}<9a(wS)ALYqb#M7xy*HC7hnXQN#-`-t=} zfGq;-lguXlj>*#ZSx8y|*!R({MJr2zk0USfV+muh~>N~Hs=TH4KurFy_iSsdRt z@&97A(f|ufT2{+9;W>KdmNo-k&s;n>d#luj^EzhIT!qhepe69!<;){>vM@i)Wd0ya z@D;3FTEZMs$?P$WY4#X?yHqNgeTV;?*#$m?)B7~dwdfP!n`wl126w{$y&7mjbfG5b zLbN%XdC&^gqkv~whLiFcVMtp*QOJ`ykAvk`yQ1|I7LpX*sEub+Jr=UVmJMaK;9`5X_~DpAY_H)1r73L;ZtZNJNXTAM6#5XCz7f6YLKstjFFrPS@QtzR><1P z_zi0Rg!UYo1ingaAzB)b}9vZZaZGyfm5XWzV_7$Kz8vhgc zaVE1$uY-aT2{$df+wFs+s5n+^Z~9$ z{v}q)e#VUKC$kUmi*bI0RYK;C{1!C&?)Bi)C-9wmT(>bldySRw&oTq($0QjRXeY+{ zmf3fC57W_eMO!7tgAFoUr^xQ?8#tDr#UyF=bsU3edUoaPShm4#0mj%xO4ICMeFgWh zJ{%{|2GACwEkJ8P8$@eFYeHKh)qvkh3(=8eQN51i*rT3j?pdT>M{%TPm(GQZc+uw- z=vM%`&{=*d#S9u3E0S86RTE?hsgPA@WE{WAoM_w7=$wv@IoC&6N_q`6`Z@Dz zK8^DU$fDB5aio^H4&pqh@v#)1n}Q54k}84A1nXhPSR4O0)|MTYSF?5eYIZtW46OyN zL%k+=0L`hw=<{i`X0!{@wlLEy{D#>FalR5q_+qnHqkR?ai)iq@W_O^iL0gS>CK|!0 z?Lzw|+C6A1(8ka{jdnfSS!nR>W=};s9qm@Md(rTG_<*8G2Gx&okXHx}8(0zlBR(r( z|1IvpY4%9x@BL51i+L3v=C|;>*^|7I`?#NX^6&BjZsQu>%6`S3Vo$SY*ss~M>^XK6 zWA+7J$cy+7`1kokyo?XQ3oB$rOv{S#>!qxWm9q-Sdljo@I#vT|G+-2%n3-9i{cIQ^ z4p20}+j)>b%)RKfi@D)xd7u}37zY6sWFhFyS{8w}h_N_JusT-H8dxJsvL@EdT3CvQ zcpDFM@;*Dk(|$J0HnJV;Ja!rT82dQ;1iPGF$v(xdW!JFl*k{>I?2GJ6>}GZcyOVu` z-NnAi?q>ha9%4UaKjK~dpZRV4R^G!syqA5OFW`NAfd2{p<&Rk(+s%*gAMtfUd~JSqx^AxJAZ`#f?K$iYxyD8$~xF~b`rafJGhhA za6PZ)I{qNMfuFK{{9pK2xrv*h1E1jCT;>LD2A3WHNvkFkFjrFqCpvXrs>c7jr z&wh+w{TU?wN$~MG_7eLo`%m@;dz<}{y^G%JxgA`O@&=v)SBCjwzJ_n(C-F1+K7LTL zONXSpq{Gs;q<@!wEd5$~QB$BP)|6|)ng^TW0zw*l8Z z@>%kQ@_zY~!1ca4xGwXo@m%e>PQ_IRT&-DLw*uEY1NQ{J6?g!+{wP?j;>v+5pZx={ zy$w3xduZP#)MxjiK?a4^_yUf%pxuS`U9?B&j`#UzVJ!VDeLmYU+ccZZ-I;zTUG>rc zV=wihEkNsg@pmu2_Tq0Cd;a#!T}PjP{$tNSc=XrLLx&yx724BBpFH~R(KnAibToQ2 zaMXMB(9y3S-F|c<-T&N?=YIO!k8u1P+MUmR^|_BdchYlPo>}lr^E1h3>Yj-|<6`XT z=bpa&sb`--L( zm!9FT^4Iv=itWQ#DW=}wsz9ogY9yP4-xb#mz;K?q#uRv+||1=`5Y7f2j>?MHkJ z68u3j!nMSPTB2K{sozn4RAL2vd!b1sDL9D&yPDBB3TxEmVdQub|V&#Rz6uYm?7 z{rPit2jYOk>{0eOG)Wgbz`EHLte1U~Enru}*ZnjbWCz(0V&_Hdb8IoYo{h85vr+a> zY=Yf@`1uQL3A+(C@}Joh`!ZX_Ze`Q#E6`A1#kjqVt!1~fb?j?wJ^MOF@xQVS>|fYU zb`RUd?j;S%PG&RgRCYf*g?)>i27Puq`#0nR9$;rdvz^Jl2QBw7#{Q3yANUEokUhfo zK^Gojmp}(x46XMab_RQpoy~s0uZEO-fqzlepC!R2 zB!}eUm-7Ss3jS&S8GaqVo`0TgW{03VNT0ifHa7^pZiE);hV2;PpW@5-a()een*W+V z$DilV@Mrl^{sL^q1N?ii5Wj);2N79p>@X{tocadmS4|)0vmZOm2Auc7c4{`Pj~_+~ zN0tY74IJVdaUsP3hj8O4-nnV(p@M)o;)87mrt9QG zY}wQ<{9QifIn+CC&z^3Zo^Ho;3g|ib3T{6zjVJ6@pMawP)g8l4g|RXDkR~`ewPfnh z{sH@;-hpYm$0H9OdSG(u&;tW@&-66zD$4d0J-%?4MeVZ|eJ+aN^J3*G%cc(X+7Gem z0|)4t%cgvuL;DXLupa;(>h)pvz;OW1jtBIr08j$Y03`+w^Zk=}7!E#C_=k$QJxmEL8L1)23h2@1;6~0w8T6DKIrhTBevG}6m7fNC! zHfa&P%f6$KT0D}$A{Ruxx$r0U)3PF<1iO5Ia6TWem`FV%m?P;J<2 zc+l8nywy}>>Nky>R-3k)&M;kMI$*labhGIW^RRijd87Gc^Ir3Q^Ofe$n!jv5Wd4@< zhvvu4N6oL9|7a<&R9hUDu%*e;YguHOvTU{Nv0Pxe-14&JO-tHZYBgEC)`Yd)I%HjH zU2olOJ;(Zv?MB<}wtH+3+8(t%WqaB7rY&tRwVUi-d&1ssAF?mCuea~EzvW<#a)-s? zchoy>cGfsu&WN+c+3y^8u6AyBp5dx@SGsNPpu5rC?LOju#{G)>Et$#Xu&RFf4tYj? zNPbLyR(@4}+aq}@JvMj^TRnR`7kDoBJmYQh_Iek2r@ULed%PETFZW*Ky~+D^?_uxv zeT}}ye9!t`^}X%C-v65akAZ?fb-)n_2bu!CfklC-z}CQ?zy*QJ1J?v?!CRzcIuD_%H znTE{`k2SV5UfK9)GLpP5`D9a~>6)g)&E3tnHox1_-Ew`ZC^ekAv9+Kz+y7W>>nqsJpV;)a~jHb|<=9y1ToF zy2ra$cJJ=KwEMH&hkHytH}+oI=jfa2d%geQf`J8(4O~9hGWht=?xDMfjxMZUcyQsP z!;ayd!3RPvX!^5vaR~^RO8f@(``AR3ma=TZr*rgQ|G3gn=adQXw##c zUf*24xpni(&3iT<*!;ql$}Pby16ww3xn#@rTMln|e9PNgEnBy4y=v>r+p4!UZtLDQ zv~7Ib)V9srPTqFTw*A`Uex3As)k?o(| ze$Vztx4*n2w&RQ)m+iQI#{)ZF-YM;L?OeL^vYij^Oz*1SwRzV^b{*XHtzEC}HX+VJ zE?SC7*C72}hT23%;A1Ig z_fh2d)(oPC%qPX_86H(l_K3e#-w@Dg^&xF26-t>?dXLV-U%%$8g9qhnu8|KOT$}du zXEyLBew%*fl~>}w{cZe}SB~9?zM+fg9h0t;uESXk?6lgUYU)rmtIGDUf&dlNL-meA z0u(BM>T1}&BZpZ9I#VUOD$$pL1ngqnVOE9DOYylDO;S6ID?n?G)Hm>uw$SKlPKA70 zv(eX_(kJ!&lhbSYchbL^Zh0~_{o=}}JD=r6v$Ma7$ICwd*@{G>LRxbSVY>$LCzDp9 z@1=-a8xeh}eKS$tOnJQz5+F#O#mtK6U=@xg(ZQ;^`#@R#)?sEs*Noy*2hb=IpE7i^ z7Tq@DSdY#I8e5v1f>HPuW?hlNm=u@3RHMmgDAKw#Mnk3K11>F1T?ozVcry=fTe5sp zy(Gn#j1DZ6_ng)>lIX3ivGXWB1%2L1$!Kulx}}FpiwmarEZ(;!*}Q)LqWHS{f`x{zQmpbZ{ zE{`jA0@!n0Im~qEVX^2d(cJ~Q7vmTZbnixYLHHtrlZdZxbfLS)6Fb$gv`s#5YnLQV zE!?}ZzIok6BkBJTRQ502HSmc~^VmfDcL(Ij z0}uASXe&{#F>FYdh?;QJ&`+Xrjkqd1G6Q z9q}VyW;|wJ$VbAJN*ZwnY?CReLwoE^!i2x0?KeFk9jIt*EWbi})pY1ko`f7azw^BA zwXd!jx}@gqUU5q9qM9a+kpj*kHf55#b*X$WM?&^-x}ajDsU+T zv{b+fflD!<8gW&O!CnK7Re&PIK`S_?&&R~gX{2XI2Vwdr>C?ca@@i>q`e#`LrA>s$ zTiXWr^^_*&AebEk2QdZ`h)`6#YKSd0dD2x(fMSJD0nzI?GFA#EabOY^cye&djPC_R z|7(D?9dIZmZ6%@ynagu^OVuX97gKeBQ@9J87(dvfAH5X5$He$T!ZAnMt zvJQ`@b463s&-oOu;1$~Fs(8%dYFc;E*yz4>O(xr?&ZsC0jh!+ybjnz$!XI53D~T)k zfp7l>zSSW^rs5YTbmDpVc?jUi1E^Xrr=m;gj#5Pncz~HAt$y$(O8h}1jb{;b(BrBc zO$&O20P_fXgg~cig&xYd%kZz+<3MONmzPE@IPDQy&tsIn09j2xu}Vt+0>@tp#@4Qs zcvM=&BhrSfPD_+_?OQmsucsuR%ZU=wg?l@}dXR&39{x;#9%jVBDm{#ZoG}mmd~A)t zOE2&uEK6}!F0QnSJdy^P*ZV(Fht-becQB`asWW``k=f;Z9r_YP)>G|Efcg@kzK}3g zF-;Uo3qR@;Kg#i=9JFzA=qqidhD0jV&4uFa=FLqBiKK|H19b|tg{8q{r(7jFO+`}B zruXP=x+*Sd_(t9&?JViJu=lgIea$gLuq~)BtT0wP?Nxfaxjk-Odc{w#Eky?v9riWR zzb|I`XQuw4V_D-pPj+$+h>B89%Rw%HN~J)h1k@~mgcL#nl7uKeiCM^s8Fwjm#)dmw zptu5e<2!yp0_u10gzCdANIIS5N25IfF9fypq2{EqitDAXrC%NV%o1r;hC8dI*Lz;t ze%((Ji9|6sZ;Gu>%+V2v(w>X@qC8v%N8z6I!3<4epotYRpo-u;o0-FyXqB(m%fwYR z^?0tHCW#l;2>Llznl2Dh9-Ee=pEzwiAZw-BfxdWLCh;f6SjCkASD8Ux4b9*dEY#ztiB-fj zvoKMR*SW*Ji)(xuo$$_d;EJ6mjT#+|m#3FWFZy4adUf5Z@4Wn*?;JmD9!wYWchY^r zWAl|J(xv=uF@~5t`?mB5Xkb7FNTq?EP}b+6tUAd#qU1X@!i~;p_`^&OBy|Ew(&zU>3Qy z6~{g=>C=tCq+Bvp7bntDetiYuf_ZNEV>iGS>7h59GuRji8$%v8E&{j|YgDK(13e>W z85UBwUF6>+Br-2q-$u1PUo*sp8XAUThRpHa_S2_ZTBc6#=)f^GbvhqQ?ON8@xNKKS zJ#t@c)g>#IUpy6$t-5$69Z8QWepwIbUWQqlY&4>FEl22l*>a(m7(ws|$Tngw3!Y2? zjxIsn0@w#dvl>9zDo~iLzCEL5Rqt3ce}reew?9dt)l0@#)Mbr-#o)Gn*)??bDrpOx zwaAKrg^SZSHEvJN8R3qmky!0$8)bQc(`-!oyr6#z=3!K6QXT#rPU;ZLjhA|2NIfxR z29s50p|k6OqQacudooA$2|@{t;yo*FsMZC2-jcdK!=cQPKWJMZ#}~E8ym9qFEm+k- ztc#9pY|<=DRR>J-ICtz}U6s3KELPgG;;d1HftRcpJ9kx6$?(ELt%C2{(iPxgIcBad z&EOj&Y+`xxCKEtbY`+*R`EH&J?7V`N49A#YC4=i01Dt|MVq->Uc)?I77+Zp4Erw1L zh;9|%a01dwwyiPinj5(hfd#yxgoZ+-<83TONicyfe83w+ZGPS0SdYZ7jYXRKN<2k+ zXRSSu)$-vpF46@$BGJ}LFW+eNH#!j;?Hf!#nkaR}K4bS8ihDjn{z1+W{6 z-7TLWiDiM=H~4QM7fr}=t5V@7qWJTul&>`XKshFmCx3yw2a3gGOb=vdpd$5xP(W9W z^1Q)NDrpvcS8R9!wp_$hW^Fc}GMRZ}(@;zw=wI8~c5<+2#9*#>FIZgRh`3_QH+j2O zHaAcEw8O?w*q-nj+FJNNeYCOF9UEzOI?Y#~TVCGTf*CqfS+%@nEIQQaa9A%pTUTkX zwZ)S(uS|0ofsA|IWfD@hyE-`gljpEC9rNnJ(# zMrl*e{{9H;8kj%^H`2Sm@8WyzxmeKN51sfU^ecp!1eNyl{PTH3R7>2^Dk4kDh8#}> z-jF?VSt-Au1=IzoP}>yzK|!iZQ718ZB_*7XOZrMz~vWQueK!`%_n z`rk`C%hEGTP9Jo;`?d}3?75KK&(iJ-dq%sLHJL0eD|>iHSpxJeg`K(zcvR-_D572# z<;l=IM8Ui5f)W>Sjz{wKzsS@HF+Omgqy)6SoGan%>^f}2|M%l=9yL(H_)} zs1$1^$!KOJSr6Jq09&5@%XeyQsvuBM(#*<)H4DI%AxCEh4`$3J4Oz z)@8p@2a8z-vFISmR#L*iXfT;gvN`3(X0kMwal(pXaC@dV9ndp|RO+u#}i|=2*bych}f!N_sj?k=meMTUBfyXp*Gf9-Fa!Wckj=>dJ~KZZm;? zA?X+JAEKzhnJaNQ`qdKsYMJi6397~@!hr(8gi3&zfl!#<#uy`ERI)|o7|TRZO8y>Z zUPwSKj^QJek|kxH0?mXA;qz(*Wz^Ij=;YIeC|%SHeV#IFA8)R+#ytA&=DH4zJRGZC z*yNI17so>V&Z43(5Aca^R2Hm{m=l9_8#csZn11SA*VVCcf!`swSA;8qt7Lv_X)s=V z75EGJt%ZN^3&_#@JZg>#`AU&8d`cKac~p<+c_2SQ2B)SZmeQ6Pjjm+Kw6cF`-PyeZzP|Mxog4anMt_4d+SgfRYaFTDw0SZ5 zh&ovCs$TFanB$d`SmVr-bsqtIdAw3%shk#66{pH8r|@au)&UQNR}?*Ec%^4f!7HEO z6*-Z_%~D)Z%$|>(*{BWW6TsXoxTND3G{>xQpJA}MvGMM&7CQ$LvC(Fir)@kw-m>hj z$^w2#t*LHd{f0G>RJgQT_Idl(b#!bP@OM5W*mDfEAm|tI=Q;3)VwJ21r@FN{4&^7k z$gRy~@|B5*GW1`Wh$vHI72u#G?ZKrgR0(9qYbGB~(pRMADZe!t)Q5eR0!doFAkk%Y zns<&gujujw`lcFVBTdc%4R^Zi@lIW^JDymxHsr18>?c&(HVg!vO=F2Fdl|`@j6Ziu z{{dg<^vq~ejc;ynsmZJyT8vnV8o})F%Z)ZzFW^bo(X2!!f9J*-$>d??!1%I&Ta-1| zL+^-8li46dQ)nqOvdR!o#X0XrO@y!cq+-9@w>TJXDfZgJq3YtwB14UI!ACe>n*PHO zM={E;C)UY6r^9ZM>#K_@OPy;MwjT*C4poK272)yFkp?&d?%5=t75s8y?(4z~u8Rnh zMR}M^5MY7;_fx(IQA|N}2AR%s5rQpJc{l^zP^Zqp1hcByjVA?#YVM|Qh%?kcsjzYN zQ)m>G!$qW#NfDE32BSrUt@nvAL?~#2cW@;x5xTl1MQ*(Emz;TX%KUb;E)j_);@WC^ zd3i-&^Te_eRK9&@qsfsRj2JNOR^s;UUcbziBpkM*~v z`ubC?eNSm5okw36Yz~web*20({`z27#9UZdW+*qAdfU7`_0EoZcaxA~jYIVT zd>jg5{S0Vi!hjft9*Cm$N7dMBER&NEHH@DpR5>k>v&M?#C|Rx=$O}0S6#tNSL)=X{s-ka?$5w3E>0KEB`p^Za`{GvVS@cgv?U70W z)x_s0FmG6?DI`Gw8&F}-C=;eiWI+%skW8M4?dNX|kD=yQl7Hv|I&RLwWZ zF;vq;qtie~;v@fBrQyul?1v=ulP7n6FAJ?I;&&91r9z)ZZ=Ob zZ=9=a&2h1ehD#aK(sYxOUZoU^5B*k#J6%PdLBGvfoyac>&qFZ4jcTV7Cuamd3(D*=nveRiNOmw7h^&x&+wCz>@#I^osPGEt8!IgWDW3+Z+~S zrKV6*Q`m`Ph=1$92Gh3gq*ri!>e-1O8vLyjepfRDD+x^9G`1LmT0$B*_GQTRU>2Kau7Kv2sOuwVjfLlNVT`ne9 zd6+{vhhfGOCP%UqSSYif6m94-BQ4iAC^K&PGj)ips2D=fzL{QpCNvRJ?2YCu=;0C6 z|EWCaBp!6;@t~go{ds^C0aAH@C;_5*{Hs`dG=BzgdxG&)BadOUk-(0}G0av$^_xu+P>CrD$6$h5oCwnSG%bWTKGMZ{# zPm|YPYAPeGMEqBjm&blhPIZ7FFo1I?3xlYGVJQ#4PLA4fYymyf@-fOL7M zhxh(LC_hjtyrgk(Fhe8K=I(=@l|faTX9zMGkE`k&YsKKxmIyz=ovUC_=bv)O=lgXu z|AdhR--hNZ$-{#W=Ox=NOnNYs$tJ7$a&GSE>gu4Dm|9R9>Yr+8nCcIO2UhX#?%J_) z`}UnXcGY?NH*|Ha@AG*2)^~Mn=%-XNG=yi?Ev72THHd;+@GL3px|$+Tvxkh{e}(Eu+NtXlG^tYRs6Ej(kzpfUV`v%+MUMT7EQl3f_y)Jz%?1rUUn#^j6k)pOd~( zx&4%5G-!+!`JFzw&>X1Xlj(OC5Rbo9#Xr*0ZE-t&o?4k>*5ukF|a%5gqUq_EuNQ`r3H7mAflFfv8z-tu>oW zdsZ0&UZ>xnGY=%)%^{OPzk8{+*e~0>$VvgP^4Yifa%m^B669%BAyFe73pG`nV~v_P z%>j-N_$eq>vY!<6lcxyxmjsTSM2ehxcv6da3L-~wBww!YuWRe)qs#0QnhP#;St{K6 zCcCe_%UbJvqM_`-mF?;0g5EL|pK<1Z9&F|>K{sb>jnvwlTzBTFp8Tr2<9sFLC(%Wv znu8L}g}74Y>&zItg^E8fbiOu(U@#%|AmdCvtA9x+%VmXr zudCOo>Aty46AqWISgnr^G^WdgRmE3b-{0hQ@KAZ6y7;Q}|3O{EG0=RLKZD=O=KNKM zJcrLb2ISNGy>jImk(h;GA;+ATv*fcKUu(Fll}i(+oicnszq2eo!S5`EAC`WCN6RB5 z2h=A`Ir@~BD_3)rxjxO40X2D^yF*1IXNdEA{nzBmlWN*uJ!s0iZc6OiUw2c>e-3Qg zz2Ip7?)3}5&F?HvPx58yf8lo*MlHo)v-K}OKSX^ z!%@wV!{8`25Sii>B}JmlC&A4|>;%bDQnk6TDPPczb>3i%CYs%$cCFv6_Zmy>VcmU* z4aUznc?|q1ORwly)n*UKW@DwH#M~R>KcsLV{bSxD#1K5PgHbc+|NLBeuDdyZ`U7+2 zp_IqSlPNw^nm&me@3D6m^N*+h^8wc_w*>hWrxjcmNS}QkR*cPJRs*%Ynp349q9^RB zA(in(Cxln<={)#k_WmlqboO`I=Pb>_b$saw@3+$Wuk8Kt?EQL#rSe8fn@~ENW?G!tCpeL+@{6as0actBH%cVE z*()!~J$VvECsay=&`vFShAuu)*(cZCUcw*J9(!v!=RerE;>B_9T`sk07Z`sjT|pI~ zS4zJ%Vs&mZy$WTZ@wLgrs8A`Bf+dN$m7qlXAZUrYVbHQj$byHTBzPj~iG_?P@CvMf zSMEohv1Uv5em7TSifUx96L6FxK&ITBR!!si1jm0x$WdjkJH&IrEg^gU6T&O_+B`V@ zo^pQ`A3q`7t;#U{UWbNcRk`2Fd-Col*;C+pz9bL6ISV&)lrpGv=@K%g-0$VkIRgHM zbP$zVLDI13zmZ>(2dC#KaC3%U=|4-TNzKA#zCZK3d_vFxt0ajIkXV&IbKn(N1xs)b zbj313U*-NPtf?b7#xg%u;H$u`DqOjr@KxY?tO?9LpZcl5&FcM-1FEIW!o65)Ebd4D zQ8x%UO@L`78GA&i&yixH|5P)tl`6O<2bZ45{R&*mv3iu~2EL%yE(6D$=K|i3K^B~y z1^in0JK4&kdGpr!I*_WSDKkkqoocmmnw({24u+Nzm@xckSwa4^XSPPKS=*dyR*O-o zFg0aFp&=DgD}{PfQz)fIsou5MqFC=cDAudrSl_syF(^vG6Q%8EcB~v&*|V?bfWS%A zt7$d@C!I=zt7hK>t_pm07VhSIgg#T?<5@VSL}uR=_ZL##TNWrrEndCu}I+|17r z&lk02g7!6v?5JbqczA_6HWfIHA?5xmzFG8Nflp=OI>51@LaAL7GNs&aopV3QlmgfD zZF$c*FAI0l??MZQW?w@M+*hC?%_yciDWj1aDK=`%o3Bq0Adv@9U7#F5y=PqEt=SygkyB9PoswOsjE2q^0q~P(2mZg%|t!e6@7u8}Cg@_8FJSxnKmGct{6d^0KS~Rz+ zq^?6aQ)-ncr_d%0P8}ZECd^nJj8Kb!H6YjAB47X$HOc5EqU+_+54;bC-dNB6P4#!`DgN;PvcpE>-lwgaPqqpxSfA84^HD;fjjvv z=oe@HS+}U`>cpz=!%9p&PnbJMx;yfuJ6C#1wL_>GLUlX|FfGc!+yxYP8yflJRJWWI zf~&=m7R!)tu1;&HajH^UK~r=>Qs1}ytI82Hg#%G%nZ2^Y*yXNIc^zhR=ca*dJy=Ju zHdhapoa~BMyHie|udv8%HaEt6-6lmm zx2is~sGAWoi9PSc{hi`D3Y=t8fx9_oy;K=@0B!@2P&0mkzy?-c))gQFlO~G*-I2Oat z&*G?R%bY&Vx%Em7_zY$VZA>Tho(#;Wlx+sZP#IVWV9Gp;QV*`=9+k|AQ{bqq@zX)% zjOODPxnM3?%nqXbkT)+MU%aB5Z%F@Cl>RrY=Y06ekJ=WTIsL=Qz6HbSmy+g$8HH`R zD%C`3jjv|Ms?fp~8N3y>Owu30TksmPfC@3e^W)*=+?NM`BYQvQ^Yh?8%fhR9Q6Bt( zEZo9*9{kH$c+H&qU(CV{yd>}b*Ryc!HzZ^*4n1cTx#6YQT|$*XRRQE8+nh~T@5q_A z8B_w)2#r9+8%p{&3hklPWJSR!5?ZAuO9n${5K7Cc(01S(b>h?J>^GX#nyfxb7tgK9 z(r40k@CQC@Wfqi;Qr0DsdvnUPo-}rQ;;B^77ymG&TINcV&QU8g(cG%7^lN5IVc%%@z`$?l zjX3njV%&u&0Cz3SK6fFldC(VHP-uFj{4U8+Ml|Z-eA`i=at_LH5PRBSq&W{KH2NZmIPtk z*CGZ(?HR@sgc;-B!(lB195rb|A1Ls0jvarp@Z9|_)izLl*tOF0umv9R9IZ5fW3Fzj z5}Ez$AQ_%a23%bykei8C(`Y#dT(uwo5W79FfR`jIN*!Dm_S;c4s2WJ+bZjn=qWKx@H3uh)A}1wspctZEjJ`62U+rRy zmLVdj0+fs>u9EzxJ zmt2?f*$w)+m2>HTS4JUsI-E)c-5t(|(bnvO^QCp0Ey&`0##-WPtA1Vy8kJXJ=_|K|U-IuNAlj`zX=x!a8%0M7&nuHQ1+#;4bjg zCs99x;yGUEZvn^ssB=ONjo_TT0_+0ydpOP6b+7ZLgz|GHN>z0whFArLqmrz30;xt#3`90QAxW11LJ{57f`C(pDJ*wMN(#Q*au zc+7cqPCw^-L8e~j097@)W3k6jCPU>3xyqT_@`{*H!!$d~z0%{zGiCEss!lvnFLOPk zJe6LpSj^?AXaNP~sYnIpS1Qfvc^9W-l`b&oc5q_?MxCXKL>^Sgu|}Bj;?Z}yS1ZBQ^4(>5LKuw>!}Sz z9c~n<)Qxn6f*ZQG@9c>u8+PrmMh#r&S=UL$DhW(>%d1jUuM(d){y7&%`5LxqxPKHSIZa#AO*Y?yWzzd?T0XfUq~^#YB!YdU0L_pfIHNEFK|XN z6ddoY6{*Uc5x(lx@4guRx6|D#s%a9LWqFxF#sT6Yee+U;AL ztY6U=tX(iwSHD4)*CiGIj0{PlLl^3fy-W2yROj>PnzglZO;69_P%u;F6OKnCj%Kwq z8?uM7!2dadWL3F82Y0bQ;Cq}|;D;?njrRz4xKk~( zs>pIWBbNqI?-(F14UpSC17%hu@*T8l$Dt|_%7!R&Nih{hDLmyqW&VmxIu-67W*en5#l4{} zCl!+#4CZQMz#lX%UZU5XJzW*{RamU{YMoOKSORT+M~ge&8jHK927bP4mr%tZBhe9m zZUY_V+?t|!bX1EZgrt&XQ1TX3``{Ghu;i0M2wNQ|dH~5>t<=Uy&^IB6Q^nkCs|{A` z$_*8nVt0OMdRWqdGEtG%|d7`fFbOf?7zD(_gtNC0a{>&0yjG z`XCdskO^A8Nb7f$op{`^)XMHWw4w!$E(QpVi1(|DL3ol`M1ak#ja~3+lY!3nD3$4H zvAKl%dzT3A7nlm(yK<%?tT7}k9>nzUBSoEq;8}|*TY~p0oOqzXEwtAvXf5gr#QiDt z{;E7U$(#arVF%&d{bb7(xQS#`#29bzKVaOIfp&Yr1y?3sR8s>vEv5z@Ie@y;0XUIK zFw&L*WIjl%xmZM)O&NMkIiqb;l+6Qz&|8@lqbNpI%?8;Dea3cX7Uh_cv=LJ|Ar}4uz<7tcH(TjwmTx|2eNfXkHLK zZ~jIVV71oq!>x@YX;o67!ec-P47V+aC4!<%Hg8 zksjWOr5++kS|ztOEbt!*jfX0gK;lS4X|St4qzl>`!e)1UQ<1U8xooh8mVc}a!mbew zSAd2sIU3fJj;qgGv^P(x)PmU@$yBoE0Qsiygw=oT0$ws%lyNOiST8%V{bN_~Ax zhK97-Ac2Z4GMOh>DVC!pRSTlfR$B4SAm@&hrPy3!GjUopmZf8b(QOPa3k18X>hsqt zd_{8DOYzy70W2cRr(w7!8OA2vMuQPGg=SwU?>5@We9P#X%x%=~N4{-_~TbF!t@Y!Atf>Kb|dNW*xG zbIH=8V4W?|8ys8K(_iH=n44|=wQHVA`K-2PySLls91T00!)AVUsj=MEABZ%?yw;|! z;g5A%8_cFqVWAcavW&r2XL2Cew=txxU5E|&{f3d&IyDzASpvr*kHR?I| zGt$+_H_YF2D7UNVU$W;=>bNx&pRaZVjmChZy4n#i8iS7N9kml(fk4+pZA3Zp-qm}0 zOs1Yat8p}&dQN{kFu8xtnthXjz~sI)YxYmVmLb>A`1hqNP&KnKBVX!Ts9Y~|dOwq5 zX5cPu6H3`E+Fh_rjkuK+Q7D_E1>wk;KmlR?k$*q^(U0>}9)pH~a<=+M{Csn1ys6|< z>F4~zlmA?kEsVZZ2soNCNNxrtR+NP0&(bBlMdHwe7qt`9m z+ub#!8HmaLaA(M1Pjq;KeFNi-tEtb(?F$~aVl=3IR-N2jpYwATVL`11^fD}Z+<-Y4 z>|p{5)*xa?2pFxLqskBji!=dzyN$}ylW!C|%>jLZH`(v6 zA8oP^_uT02oNB9G*eq*G96GD3q`cf*ws3f0xFLLLM~luR$$ppL-{R9*BJJMxB?jl^ z;lZR+A8ZYps^n;=Mj9RJ8fo6w+JyiL?~wx1Z$efi6bWQAZ}TwD&krJFtL{R{kjth@ zXl2hP(p#>Mocc3y&+J1##<)krmnnE9zc6ypoh?(S}hxxTzccg#E6N|Raa$EZ4 zC3oD>&p)3&OOYL_6?s~^7`|C{6}p-%$?-v5z66yxgZ_KP%4Ga5Y!$6tQf8K^7cTV3 zi(`NmY+{jVZleQSz))m}PV0R19;4^84RsC6y1f40spjRoiYuaK(74)O**7#iSl8e{ z^=$fSexS^jT%2s2Ot~idjcv_R z&r^fj1_DK06VqEf?UQxQ%iHC~EeAJw7B3zjjDGxlX;D?{*i@o*=bDx!EsoI0uKuCR zP8r55J}R9U{}p(lg+!}kLR~?d!z8Cq6pj~y=3)y*qXrupf#<(^bw?>LN#7}5+;!|* zrIL=w1Zx!mot}h_s6rm0E0-s1A+^www^y^8ILrn-GZbO}PoBf&v3g#FKhj2ZKb7P$P4qp4=LAks0HXz1CS(9SFSOK|d3$4| zXW;zawcWnr`k~lJi_6mi`B~QHN^ZPjig#32m+H&TI%#Cl;sxnv^-cW~^?rNfa6GX% zUQyAlW#~gBHybg}Ca6xP;B{{LQ|UkL=&e*Enjk&2#{}Xu8ohpS~l6m%3tfk~H{C)iZ zog-v4p^xwfOvaEyw>vV~6%2MwMj}gk5OFX0P<}uhb1EPId;0+&Pv3eD-}wmqfKWJW z4vhNw7We_BSEZlzk0O;tHWf1%m|y=#`vJfBtNZ{L^wMMK^Zy<{;46PuKfnSWq5AV5 z?*~NR-w*JB55N2$@&m5<8~6cH^#7Ir9e#k}uk`~EMe>=y)(@CDu^&LO73qk-w;zxa zhT<>w17`nWZU9E04}QR}L5u%Qen9Ep&<`Nrp6uuUkRRYTkYz0{HdcBJWLvA&9A{j| z$@=eE-M3C|H|xj`IJZYCI)NX6Tn>Lxvdql~sGf0Ib`L2vm=fNMvWkYbd8OJt^1(8( zh~lhkGCOIidlGX^bdv1-WHh?8Clu;gI;3~knv7w0O^rKjG}XHGlEpi)b7*MCfY&>) zV`ymSfH(cxf~lm@*tBZFf~h7Pr-Thwasv7j%2o=Z_ai*Q;(oEQRt=5~ zqRao-;Gci>LkIte{bw&i>`!l-ufV(LFu9${^5(Fcp<*gb>nVZ05>`+^Pr*KwV*G`H z{)NW{`m|s0d60<`#QCim+NyEBpe-1WL?Xq~i0n*Srw^v5e_1$%OF#FMiLD-@UVYg`Ob0 zJqfBtGE`M#cu2GokW^?O$ZyEU<5H|K06degHe) zzIi~~U;h2=+lL8NKhVDYZDZBH%D(;eu`2A_%wK5VvY~07efxiLshXY^{?A^-rPx>P zf6l&ra2Wcb?Hgyqvv1&C@1H~*YRUMXs{eyv4el^}OLN}7q}R!bgp5`t{^E>ue#LBv z9mO+@@AC|?w=Hccrj%FFZriDIt;UeA(xWRZ_O%ZAE0YUr%5)KfGghuM1dMe{`V!>< z+Ypr;qTWpO6Sa&Xjww67i51ZiaQf|+=D-Uw_iOf|PeHnm;ahwZM=jT=@1C3l-oHT& zLK*4;;u*}<$+X=1&bg#OmB4Z2(1?ovD!j!|;P-h^=pT)`U1437E{axL6?3EVA5FU3 z7qnlv^}O@8UT6>cL?0(-JK1me>!`ED>W*2eN08VF`=xdx*RR~HAADAX0K_JJ-s%Ho zD_QIiCdgfM{rrAOw`4kYY|-3~No)`?{ds~mjk$di)#bdoKIG;@(Fa7S^imcxj?|wh z`lGy=QYmo6c5;YKL#TrA2|}erbub00S=yyUC*?@wQm3t0tBXZEMe(5QY+2nOXi7H9 zI!O~MD=PGaKc49~uPt+#DyN;W2dgBOm7H;E%q{pN2y61nC;|y z1)VFhbRGbXdsQ5>{8v%R;h0;)Ol8l6C-N0}!$Biv(#*(UBuTD|w4%Vd2fKb|X|Lrz zv8n9`A|_=;CH>0}gBj-O`Ip$2u&-|oX0XvWdcUhGDX2|S1%g&GLOQALdaF||DlV3) zqE%9Hagi)N>-ASB>LX>#mzPEA6V-k%jVC;lZ^Sc$Tgl zwK`GxErC9m9a7#pfOqUB~WbpT>9u{Mc>Ey|e51$MEj@kP4&Eeny|6-!9e! zz48OhP?uqc8+yZmCJMPX)0+d#r(NTI=ppy9uXt}Ayp`6D;eHcp!v37Szev4bkL8DW zb?%=Za$j?eo4axMSLh4qCq4hixIf4-Uy1&k*bfC9&%wLm32qi}Gr{rvFna=Pwmg^< ztYG)!TEc$?=#d`F<->2h!9Ap6h{wu(QW4eis^5G5MBhUlK$zc`UMRjPp0BBRuluCm z9JA-{<4?WUef-Y!INhi8gPw1&*&rH2PbxH4 z_gl@>G2CE@%6h#VwOFDaz1|c3sZNgB?QvPBljC-KOa?#c_h#?m&ohqaqqaGHR6Kuh zc7zW~FCyojl|41{qsSi3kZXgwYAi(5e68Bw5tWY~m7^X0YHmtx-*IY><9oc6mwwOD zbLtMv=3~D#JkLJ&d2?hLNzG8oq^pJ)Yrc8H=cV6Hzny#D*4a(GLHaT9XLy}yX4_%f zd=&aLY5cJyZGQxt@L_MC&-7i=|2kS(eEh~GuTOk&f=Z8=b#@bbS@}K|tkGJF>?=@{ zP+l+Mo7QFP;14{R{bZ{eg#5|Recsx?+iP^(rQ&qaErkA`{-j7ju2p6xGQNdvi| zUQ({qBhFBn1kO`BjYbbuCn0}I{T0OyC^|x!B#af6=?TSybJ|5vsVD&^W**OU&VGW9 z&*pVV^ZtD&nRK!B&>{bcF@SUku1(lw{?FptEUxMEAM^hdIv}Fz0QElT0D|K_z)1%X zJPdKP@)criH@(O8^Wt*{Q$NQTr2CyGydIq0#RoMSeC|WtChGoiZ5P*malLi+V#w!j z@p(X8TW2qZywP<~T!-;_N?eD;wF}pAaUF)VaHg5v$X81bL1)qUCJ%^oC{J=9uUwS= z!y@UScdsYDZkjD(w@bgreOW(MP1TEC7RfN{vA5l(krC z3w?O{8hZ9k8l_Gt_iXKnpI%7r44!U9)fRqX5zGL z7_Z+^%5O0os;J%*M+}HM+T}s>1*nO!BTCBS$f4}scdk^%qFWvNMDAkr{ZmdIp|mR)`6-g#)M+-XLC5lqCX&86i*ZiaO#@&A8Z_w7Tqe z7Yzy9j-O{gHcCSaV6bWsjX@*b-LY^E}P9&>2^Cyu^5%;aigHeY3xg&$9RSweN>Cp z$8z*oLx42|xE~lwpa*G`3LKTn9JhK#@0?N=n^5&Iy~Z$}{iF|c>=1NJ;n^L~L^G&= z&YZ1M&knOq_|~>8{519Z&{}gSnq6^6mBl?dxe_ELihdBCv+|i`5Z;)WPyA#hXk0*K zEd-4#k|4XFKCz{|xUjIKT>IV}N#-$8TTxtCP*Ps}uQ^tfIoxsuv7$nDJIb1?vh1_f z`n?9d#~ZZ0H{tMpfqbV=7BAVuu-R zDuUsF>BxY1RSU*nNGXqVaZONc84X835n3gJ&3~7&NvywxWfy{*5-u>gCSuh`FvK@m zb#m0^PMNF*Z^UeF_f=Lz>h+$4-P<0u#(Wi3mUwSiZm)9}7B~z>xzbiqRhOud6Lx1? z!Wr|s%(1?Rr#38Z6TZAZY(Kv^1C!)S-h~Z(iKYj68%

V|^%yxrZkYITGH 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 diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml deleted file mode 100644 index bf83dc3b2..000000000 --- a/cmd/mist/assets/qml/main.qml +++ /dev/null @@ -1,1030 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -import "../ext/filter.js" as Eth -import "../ext/http.js" as Http - - -ApplicationWindow { - id: root - - //flags: Qt.FramelessWindowHint - // Use this to make the window frameless. But then you'll need to do move and resize by hand - - property var ethx : Eth.ethx - property var catalog; - - width: 1200 - height: 820 - minimumHeight: 600 - minimumWidth: 800 - - title: "Mist" - - TextField { - id: copyElementHax - visible: false - } - - function copyToClipboard(text) { - copyElementHax.text = text - copyElementHax.selectAll() - copyElementHax.copy() - } - - // Takes care of loading all default plugins - Component.onCompleted: { - - catalog = addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin", active: true}); - - var walletWeb = addPlugin("./views/browser.qml", {noAdd: true, close: false, section: "ethereum", active: false}); - walletWeb.view.url = "http://ethereum-dapp-wallet.meteor.com/"; - walletWeb.menuItem.title = "Wallet"; - - addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "legacy", active: false}); - addPlugin("./views/network.qml", {noAdd: true, close: false, section: "ethereum", active: false}); - - /* var whisperTab = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "ethereum", active: false}); - whisperTab.view.url = "http://ethereum-dapp-whisper-client.meteor.com/"; - whisperTab.menuItem.title = "Whisper Chat"; -*/ - addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"}); - - mainSplit.setView(catalog.view, catalog.menuItem); - - //newBrowserTab("http://ethereum-dapp-catalog.meteor.com"); - - // Command setup - gui.sendCommand(0) - } - - function activeView(view, menuItem) { - mainSplit.setView(view, menuItem) - /*if (view.hideUrl) { - urlPane.visible = false; - mainView.anchors.top = rootView.top - } else { - urlPane.visible = true; - mainView.anchors.top = divider.bottom - }*/ - - } - - function addViews(view, path, options) { - var views = mainSplit.addComponent(view, options) - views.menuItem.path = path - - mainSplit.views.push(views); - - if(!options.noAdd) { - gui.addPlugin(path) - } - - return views - } - - function addPlugin(path, options) { - try { - if(typeof(path) === "string" && /^https?/.test(path)) { - console.log('load http') - Http.request(path, function(o) { - if(o.status === 200) { - var view = Qt.createQmlObject(o.responseText, mainView, path) - addViews(view, path, options) - } - }) - - return - } - - var component = Qt.createComponent(path); - if(component.status != Component.Ready) { - if(component.status == Component.Error) { - ethx.note("error: ", component.errorString()); - } - - return - } - - var view = mainView.createView(component, options) - var views = addViews(view, path, options) - - return views - } catch(e) { - console.log(e) - } - } - - function newBrowserTab(url) { - - var urlMatches = url.toString().match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); - var requestedDomain = urlMatches && urlMatches[1]; - - var domainAlreadyOpen = false; - - for(var i = 0; i < mainSplit.views.length; i++) { - if (mainSplit.views[i].view.url) { - var matches = mainSplit.views[i].view.url.toString().match(/^[a-z]*\:\/\/(?:www\.)?([^\/?#]+)(?:[\/?#]|$)/i); - var existingDomain = matches && matches[1]; - if (requestedDomain == existingDomain) { - domainAlreadyOpen = true; - - if (mainSplit.views[i].view.url != url){ - mainSplit.views[i].view.url = url; - } - - activeView(mainSplit.views[i].view, mainSplit.views[i].menuItem); - } - } - } - - if (!domainAlreadyOpen) { - var window = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "apps", active: true}); - window.view.url = url; - window.menuItem.title = "Mist"; - activeView(window.view, window.menuItem); - } - } - - - menuBar: MenuBar { - Menu { - title: "File" - MenuItem { - text: "New tab" - shortcut: "Ctrl+t" - onTriggered: { - activeView(catalog.view, catalog.menuItem); - } - } - - MenuSeparator {} - - MenuItem { - text: "Import key" - shortcut: "Ctrl+i" - onTriggered: { - generalFileDialog.show(true, function(path) { - gui.importKey(path) - }) - } - } - - MenuItem { - text: "Export keys" - shortcut: "Ctrl+e" - onTriggered: { - generalFileDialog.show(false, function(path) { - }) - } - } - - MenuItem { - text: "Generate key" - shortcut: "Ctrl+k" - onTriggered: gui.generateKey() - } - } - - Menu { - title: "Developer" - MenuItem { - text: "Import Tx" - onTriggered: { - txImportDialog.visible = true - } - } - - MenuItem { - text: "Dump state" - onTriggered: { - generalFileDialog.show(false, function(path) { - // Empty hash for latest - gui.dumpState("", path) - }) - } - } - - MenuSeparator {} - } - - Menu { - title: "Network" - MenuItem { - text: "Add Peer" - shortcut: "Ctrl+p" - onTriggered: { - addPeerWin.visible = true - } - } - MenuItem { - text: "Show Peers" - shortcut: "Ctrl+e" - onTriggered: { - peerWindow.visible = true - } - } - } - - Menu { - title: "Help" - MenuItem { - text: "About" - onTriggered: { - aboutWin.visible = true - } - } - } - - } - - property var blockModel: ListModel { - id: blockModel - } - - SplitView { - property var views: []; - - id: mainSplit - anchors.fill: parent - //resizing: false // this is NOT where we remove that damning resizing handle.. - handleDelegate: Item { - //This handle is a way to remove the line between the split views - Rectangle { - anchors.fill: parent - } - } - - function setView(view, menu) { - for(var i = 0; i < views.length; i++) { - views[i].view.visible = false - views[i].menuItem.setSelection(false) - } - view.visible = true - menu.setSelection(true) - } - - function addComponent(view, options) { - view.visible = false - view.anchors.fill = mainView - - var menuItem = menu.createMenuItem(view, options); - if( view.hasOwnProperty("menuItem") ) { - view.menuItem = menuItem; - } - - if( view.hasOwnProperty("onReady") ) { - view.onReady.call(view) - } - - if( options.active ) { - setView(view, menuItem) - } - - - return {view: view, menuItem: menuItem} - } - - /********************* - * Main menu. - ********************/ - Rectangle { - id: menu - Layout.minimumWidth: 192 - Layout.maximumWidth: 192 - - FontLoader { - id: sourceSansPro - source: "fonts/SourceSansPro-Regular.ttf" - } - FontLoader { - source: "fonts/SourceSansPro-Semibold.ttf" - } - FontLoader { - source: "fonts/SourceSansPro-Bold.ttf" - } - FontLoader { - source: "fonts/SourceSansPro-Black.ttf" - } - FontLoader { - source: "fonts/SourceSansPro-Light.ttf" - } - FontLoader { - source: "fonts/SourceSansPro-ExtraLight.ttf" - } - FontLoader { - id: simpleLineIcons - source: "fonts/Simple-Line-Icons.ttf" - } - - Rectangle { - color: "steelblue" - anchors.fill: parent - - MouseArea { - anchors.fill: parent - property real lastMouseX: 0 - property real lastMouseY: 0 - onPressed: { - lastMouseX = mouseX - lastMouseY = mouseY - } - onPositionChanged: { - root.x += (mouseX - lastMouseX) - root.y += (mouseY - lastMouseY) - } - /*onDoubleClicked: { - //!maximized ? view.set_max() : view.set_normal()} - visibility = "Minimized" - }*/ - } - } - - - - anchors.top: parent.top - Rectangle { - width: parent.height - height: parent.width - anchors.centerIn: parent - rotation: 90 - - gradient: Gradient { - GradientStop { position: 0.0; color: "#E2DEDE" } - GradientStop { position: 0.1; color: "#EBE8E8" } - GradientStop { position: 1.0; color: "#EBE8E8" } - } - } - - Component { - id: menuItemTemplate - Rectangle { - id: menuItem - property var view; - property var path; - property var closable; - property var badgeContent; - - property alias title: label.text - property alias icon: icon.source - property alias secondaryTitle: secondary.text - property alias badgeNumber: badgeNumberLabel.text - property alias badgeIcon: badgeIconLabel.text - - function setSelection(on) { - sel.visible = on - - if (this.closable == true) { - closeIcon.visible = on - } - } - - function setAsBigButton(on) { - newAppButton.visible = on - label.visible = !on - buttonLabel.visible = on - } - - width: 192 - height: 55 - color: "#00000000" - - anchors { - left: parent.left - leftMargin: 4 - } - - Rectangle { - // New App Button - id: newAppButton - visible: false - anchors.fill: parent - anchors.rightMargin: 8 - border.width: 0 - radius: 5 - height: 55 - width: 180 - color: "#F3F1F3" - } - - Rectangle { - id: sel - visible: false - anchors.fill: parent - color: "#00000000" - Rectangle { - id: r - anchors.fill: parent - border.width: 0 - radius: 5 - color: "#FAFAFA" - } - Rectangle { - anchors { - top: r.top - bottom: r.bottom - right: r.right - } - width: 10 - color: "#FAFAFA" - border.width:0 - - Rectangle { - // Small line on top of selection. What's this for? - anchors { - left: parent.left - right: parent.right - top: parent.top - } - height: 1 - color: "#FAFAFA" - } - - Rectangle { - // Small line on bottom of selection. What's this for again? - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - } - height: 1 - color: "#FAFAFA" - } - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onClicked: { - activeView(view, menuItem); - } - onEntered: { - if (parent.closable == true) { - closeIcon.visible = sel.visible - } - } - onExited: { - closeIcon.visible = false - } - } - - Image { - id: icon - height: 28 - width: 28 - anchors { - left: parent.left - verticalCenter: parent.verticalCenter - leftMargin: 6 - } - } - - Text { - id: buttonLabel - visible: false - text: "GO TO NEW APP" - font.family: sourceSansPro.name - font.weight: Font.DemiBold - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - color: "#AAA0A0" - } - - Text { - id: label - font.family: sourceSansPro.name - font.weight: Font.DemiBold - elide: Text.ElideRight - x:250 - color: "#665F5F" - font.pixelSize: 14 - anchors { - left: icon.right - right: parent.right - verticalCenter: parent.verticalCenter - leftMargin: 6 - rightMargin: 8 - verticalCenterOffset: (secondaryTitle == "") ? 0 : -10; - } - - - - - } - - Text { - id: secondary - //only shows secondary title if there's no badge - visible: (badgeContent == "icon" || badgeContent == "number" )? false : true - font.family: sourceSansPro.name - font.weight: Font.Light - anchors { - left: icon.right - leftMargin: 6 - top: label.bottom - } - color: "#6691C2" - font.pixelSize: 12 - } - - Rectangle { - id: closeIcon - visible: false - width: 10 - height: 10 - color: "#FAFAFA" - anchors { - fill: icon - } - - MouseArea { - anchors.fill: parent - onClicked: { - menuItem.closeApp() - } - } - - Text { - - font.family: simpleLineIcons.name - anchors { - centerIn: parent - } - color: "#665F5F" - font.pixelSize: 20 - text: "\ue082" - } - } - - Rectangle { - id: badge - visible: (badgeContent == "icon" || badgeContent == "number" )? true : false - width: 32 - color: "#05000000" - anchors { - right: parent.right; - top: parent.top; - bottom: parent.bottom; - rightMargin: 4; - } - - Text { - id: badgeIconLabel - visible: (badgeContent == "icon") ? true : false; - font.family: simpleLineIcons.name - anchors { - centerIn: parent - } - horizontalAlignment: Text.AlignCenter - color: "#AAA0A0" - font.pixelSize: 20 - text: badgeIcon - } - - Text { - id: badgeNumberLabel - visible: (badgeContent == "number") ? true : false; - anchors { - centerIn: parent - } - horizontalAlignment: Text.AlignCenter - font.family: sourceSansPro.name - font.weight: Font.Light - color: "#AAA0A0" - font.pixelSize: 18 - text: badgeNumber - } - } - - - - function closeApp() { - if(!this.closable) { return; } - - if(this.view.hasOwnProperty("onDestroy")) { - this.view.onDestroy.call(this.view) - } - - this.view.destroy() - this.destroy() - for (var i = 0; i < mainSplit.views.length; i++) { - var view = mainSplit.views[i]; - if (view.menuItem === this) { - mainSplit.views.splice(i, 1); - break; - } - } - gui.removePlugin(this.path) - activeView(mainSplit.views[0].view, mainSplit.views[0].menuItem); - } - } - } - - function createMenuItem(view, options) { - if(options === undefined) { - options = {}; - } - - var section; - switch(options.section) { - case "begin": - section = menuBegin - break; - case "ethereum": - section = menuDefault; - break; - case "legacy": - section = menuLegacy; - break; - default: - section = menuApps; - break; - } - - var comp = menuItemTemplate.createObject(section) - comp.view = view - comp.title = view.title - - if(view.hasOwnProperty("iconSource")) { - comp.icon = view.iconSource; - } - comp.closable = options.close; - - if (options.section === "begin") { - comp.setAsBigButton(true) - } - - return comp - } - - ColumnLayout { - id: menuColumn - y: 10 - width: parent.width - anchors.left: parent.left - anchors.right: parent.right - spacing: 3 - - - - ColumnLayout { - id: menuBegin - spacing: 3 - anchors { - left: parent.left - right: parent.right - } - } - - Rectangle { - height: 19 - color: "transparent" - Text { - text: "ETHEREUM" - font.family: sourceSansPro.name - font.weight: Font.Regular - // anchors.top: 20 - // anchors.left: 16 - anchors { - leftMargin: 12 - topMargin: 4 - fill: parent - } - // anchors.leftMargin: 16 - // anchors.topMargin: 16 - // anchors.verticalCenterOffset: 50 - color: "#AAA0A0" - } - } - - - ColumnLayout { - id: menuDefault - spacing: 3 - anchors { - left: parent.left - right: parent.right - } - } - - Rectangle { - height: 19 - color: "#00ff00" - visible: (menuApps.children.length > 0) - - Text { - text: "APPS" - font.family: sourceSansPro.name - font.weight: Font.Regular - anchors.fill: parent - anchors.leftMargin: 16 - color: "#AAA0A0" - } - } - - ColumnLayout { - id: menuApps - spacing: 3 - - - anchors { - left: parent.left - right: parent.right - } - } - - ColumnLayout { - id: menuLegacy - visible: true - spacing: 3 - anchors { - left: parent.left - right: parent.right - } - } - } - } - - /********************* - * Main view - ********************/ - Rectangle { - id: rootView - anchors.right: parent.right - anchors.left: menu.right - anchors.bottom: parent.bottom - anchors.top: parent.top - color: "#00000000" - - /*Rectangle { - id: urlPane - height: 40 - color: "#00000000" - anchors { - left: parent.left - right: parent.right - leftMargin: 5 - rightMargin: 5 - top: parent.top - topMargin: 5 - } - TextField { - id: url - objectName: "url" - placeholderText: "DApp URL" - anchors { - left: parent.left - right: parent.right - top: parent.top - topMargin: 5 - rightMargin: 5 - leftMargin: 5 - } - - Keys.onReturnPressed: { - if(/^https?/.test(this.text)) { - newBrowserTab(this.text); - } else { - addPlugin(this.text, {close: true, section: "apps"}) - } - } - } - - } - - // Border - Rectangle { - id: divider - anchors { - left: parent.left - right: parent.right - top: urlPane.bottom - } - z: -1 - height: 1 - color: "#CCCCCC" - }*/ - - Rectangle { - id: mainView - color: "#00000000" - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.top: parent.top - - function createView(component) { - var view = component.createObject(mainView) - - return view; - } - } - } - } - - - /****************** - * Dialogs - *****************/ - FileDialog { - id: generalFileDialog - property var callback; - onAccepted: { - var path = this.fileUrl.toString(); - callback.call(this, path); - } - - function show(selectExisting, callback) { - generalFileDialog.callback = callback; - generalFileDialog.selectExisting = selectExisting; - - this.open(); - } - } - - - /****************** - * Wallet functions - *****************/ - function importApp(path) { - var ext = path.split('.').pop() - if(ext == "html" || ext == "htm") { - eth.openHtml(path) - }else if(ext == "qml"){ - addPlugin(path, {close: true, section: "apps"}) - } - } - - function setWalletValue(value) { - //walletValueLabel.text = value - } - - function loadPlugin(name) { - console.log("Loading plugin" + name) - var view = mainView.addPlugin(name) - } - - function clearPeers() { peerModel.clear() } - function addPeer(peer) { peerModel.append(peer) } - - function setPeerCounters(text) { - //peerCounterLabel.text = text - } - - function timeAgo(unixTs){ - var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000 - return (lapsed + " seconds ago") - } - - function convertToPretty(unixTs){ - var a = new Date(unixTs*1000); - var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; - var year = a.getFullYear(); - var month = months[a.getMonth()]; - var date = a.getDate(); - var hour = a.getHours(); - var min = a.getMinutes(); - var sec = a.getSeconds(); - var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ; - return time; - } - - /********************** - * Windows - *********************/ - Window { - id: peerWindow - //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint - height: 200 - width: 700 - Rectangle { - anchors.fill: parent - property var peerModel: ListModel { - id: peerModel - } - TableView { - anchors.fill: parent - id: peerTable - model: peerModel - TableViewColumn{width: 180; role: "addr" ; title: "Remote Address" } - TableViewColumn{width: 280; role: "nodeID" ; title: "Node ID" } - TableViewColumn{width: 100; role: "name" ; title: "Name" } - TableViewColumn{width: 40; role: "caps" ; title: "Capabilities" } - } - } - } - - Window { - id: aboutWin - visible: false - title: "About" - minimumWidth: 350 - maximumWidth: 350 - maximumHeight: 280 - minimumHeight: 280 - - Image { - id: aboutIcon - height: 150 - width: 150 - fillMode: Image.PreserveAspectFit - smooth: true - source: "../facet.png" - x: 10 - y: 30 - } - - Text { - anchors.left: aboutIcon.right - anchors.leftMargin: 10 - anchors.top: parent.top - anchors.topMargin: 30 - font.pointSize: 12 - text: "

Mist (0.9.0)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy
Gustav Simonsson

UX/UI

Alex van de Sande
Fabian Vogelsteller" - } - } - - Window { - id: txImportDialog - minimumWidth: 270 - maximumWidth: 270 - maximumHeight: 50 - minimumHeight: 50 - TextField { - id: txImportField - width: 170 - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 10 - onAccepted: { - } - } - Button { - anchors.left: txImportField.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: 5 - text: "Import" - onClicked: { - eth.importTx(txImportField.text) - txImportField.visible = false - } - } - Component.onCompleted: { - addrField.focus = true - } - } - - Window { - id: addPeerWin - visible: false - minimumWidth: 400 - maximumWidth: 400 - maximumHeight: 50 - minimumHeight: 50 - title: "Connect to peer" - - TextField { - id: addrField - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: addPeerButton.left - anchors.leftMargin: 10 - anchors.rightMargin: 10 - placeholderText: "enode://::" - onAccepted: { - if(addrField.text.length != 0) { - eth.connectToPeer(addrField.text) - addPeerWin.visible = false - } - } - } - - Button { - id: addPeerButton - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: 10 - text: "Connect" - onClicked: { - if(addrField.text.length != 0) { - eth.connectToPeer(addrField.text) - addPeerWin.visible = false - } - } - } - Component.onCompleted: { - addrField.focus = true - } - } - } diff --git a/cmd/mist/assets/qml/muted.qml b/cmd/mist/assets/qml/muted.qml deleted file mode 100644 index fac8267c4..000000000 --- a/cmd/mist/assets/qml/muted.qml +++ /dev/null @@ -1,74 +0,0 @@ -import QtQuick 2.0 -import QtWebKit 3.0 -import QtWebKit.experimental 1.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Window 2.1; -import Ethereum 1.0 - -ApplicationWindow { - id: window - title: "muted" - width: 900 - height: 600 - minimumHeight: 300 - - property alias url: webView.url - property alias webView: webView - - - Item { - id: root - anchors.fill: parent - WebView { - objectName: "webView" - id: webView - anchors { - top: root.top - right: root.right - left: root.left - bottom: root.bottom - //bottom: sizeGrip.top - } - - experimental.preferences.javascriptEnabled: true - experimental.preferences.navigatorQtObjectEnabled: true - experimental.onMessageReceived: { - var data = JSON.parse(message.data) - - switch(data.call) { - case "log": - console.log.apply(this, data.args) - break; - } - } - function postData(seed, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed})) - } - function postEvent(event, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _event: event})) - } - } - - /* - Rectangle { - id: sizeGrip - color: "gray" - height: 5 - anchors { - left: root.left - right: root.right - } - y: Math.round(root.height * 2 / 3) - - MouseArea { - anchors.fill: parent - drag.target: sizeGrip - drag.minimumY: 0 - drag.maximumY: root.height - sizeGrip.height - drag.axis: Drag.YAxis - } - } - */ - } -} diff --git a/cmd/mist/assets/qml/test_app.qml b/cmd/mist/assets/qml/test_app.qml deleted file mode 100644 index c69587839..000000000 --- a/cmd/mist/assets/qml/test_app.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import Ethereum 1.0 - -QmlApp { - minimumWidth: 350 - maximumWidth: 350 - maximumHeight: 80 - minimumHeight: 80 - - title: "Generic Coin" - - property string contractAddr: "f299f6c74515620e4c4cd8fe3d205b5c4f2e25c8" - property string addr: "2ef47100e0787b915105fd5e3f4ff6752079d5cb" - - Component.onCompleted: { - eth.watch(contractAddr, addr) - eth.watch(addr, contractAddr) - setAmount() - } - - function onStorageChangeCb(storageObject) { - setAmount() - } - - function setAmount(){ - var state = eth.getStateObject(contractAddr) - var storage = state.getStorage(addr) - amountLabel.text = storage - } - Column { - spacing: 5 - Row { - spacing: 20 - Label { - id: genLabel - text: "Generic coin balance:" - } - Label { - id: amountLabel - } - } - Row { - spacing: 20 - TextField { - id: address - placeholderText: "Address" - } - TextField { - id: amount - placeholderText: "Amount" - } - } - Button { - text: "Send coins" - onClicked: { - var privKey = eth.getKey().privateKey - if(privKey){ - var result = eth.transact(privKey, contractAddr, 0,"100000","250", "0x" + address.text + "\n" + amount.text) - resultTx.text = result.hash - } - } - } - Label { - id: resultTx - } - } - -} diff --git a/cmd/mist/assets/qml/transactions.qml b/cmd/mist/assets/qml/transactions.qml deleted file mode 100644 index e9a035a85..000000000 --- a/cmd/mist/assets/qml/transactions.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; - -Rectangle { - id: transactionView - visible: false - Text { text: "TX VIEW" } -} diff --git a/cmd/mist/assets/qml/views/browser.qml b/cmd/mist/assets/qml/views/browser.qml deleted file mode 100644 index edecc8696..000000000 --- a/cmd/mist/assets/qml/views/browser.qml +++ /dev/null @@ -1,506 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Controls.Styles 1.0 -import QtQuick.Layouts 1.0; -import QtWebEngine 1.0 -import QtWebEngine.experimental 1.0 -import QtQuick.Window 2.0; - -Rectangle { - id: window - anchors.fill: parent - color: "#00000000" - - property var title: "" - property var iconSource: "../browser.png" - property var menuItem - property var hideUrl: true - - property alias url: webview.url - property alias windowTitle: webview.title - property alias webView: webview - - property var cleanPath: false - property var open: function(url) { - if(!window.cleanPath) { - var uri = url; - if(!/.*\:\/\/.*/.test(uri)) { - uri = "http://" + uri; - } - - var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ - - if(reg.test(uri)) { - uri.replace(reg, function(match, pre, domain, path) { - uri = pre; - - var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); - var ip = []; - for(var i = 0, l = lookup.length; i < l; i++) { - ip.push(lookup.charCodeAt(i)) - } - - if(ip.length != 0) { - uri += lookup; - } else { - uri += domain; - } - - uri += path; - }); - } - - window.cleanPath = true; - - webview.url = uri; - - //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2$3"); - uriNav.text = uri; - - } else { - // Prevent inf loop. - window.cleanPath = false; - } - } - - function showFullUrlBar(on){ - if (uriNav.focus == false ) { - if (on == false) { - clickAnywhereOnApp.visible = false - navBar.state = "titleVisible" - } else { - clickAnywhereOnApp.visible = true - navBar.state = "fullUrlVisible" - } - } - - } - - Component.onCompleted: { - } - - Item { - objectName: "root" - id: root - anchors { - fill: parent - } - - state: "inspectorShown" - - MouseArea { - id: clickAnywhereOnApp - z:15 - // Using a secondary screen to catch on mouse exits for the area, because - // there are many hover actions conflicting - - anchors { - top: parent.top - topMargin: 50 - right: parent.right - bottom: parent.bottom - left: parent.left - } - hoverEnabled: true - - onEntered: { - showFullUrlBar(false); - } - - onClicked: { - uriNav.focus = false - showFullUrlBar(false); - } - - // Rectangle { - // anchors.fill: parent - // color: "#88888888" - // } - } - - RowLayout { - id: navBar - height: 74 - z: 20 - anchors { - left: parent.left - right: parent.right - } - - Button { - id: back - z: 30 - onClicked: { - webview.goBack() - } - - anchors { - left: parent.left - leftMargin: 6 - } - - style: ButtonStyle { - background: Image { - source: (webview.canGoBack) ? - (control.hovered ? "../../backButtonHover.png" : "../../backButton.png") : - "../../backButtonDisabled.png" - width: 20 - height: 30 - } - } - } - - Rectangle { - id: appInfoPane - height: 28 - color: "#FFFFFF" - radius: 6 - z:2 - MouseArea { - anchors.fill: parent - z: 10 - hoverEnabled: true - - onEntered: { - showFullUrlBar(true); - } - /*onExited: { - showFullUrlBar(false); - }*/ - - } - - anchors { - left: back.right - right: parent.right - leftMargin: 10 - rightMargin: 10 - } - - Text { - id: appTitle - text: "LOADING" - font.bold: true - font.capitalization: Font.AllUppercase - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - - anchors { - left: parent.left - right: parent.horizontalCenter - top: parent.top - bottom: parent.bottom - leftMargin: 32 - } - color: "#928484" - } - - Text { - id: appDomain - text: "loading domain" - font.bold: false - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - elide: Text.ElideLeft - - anchors { - left: parent.horizontalCenter - right: parent.right - top: parent.top - bottom: parent.bottom - leftMargin: 32 - - } - color: "#C0AFAF" - } - - - TextField { - id: uriNav - opacity: 0.0 - - anchors { - left: parent.left - right: parent.right - leftMargin: 16 - } - - horizontalAlignment: Text.AlignHCenter - - style: TextFieldStyle { - textColor: "#928484" - background: Rectangle { - border.width: 0 - color: "transparent" - } - } - text: webview.url; - y: parent.height / 2 - this.height / 2 - z: 20 - activeFocusOnPress: true - Keys.onReturnPressed: { - // if there's no http, add it. - var url = this.text, - matches = url.match(/^([a-z]*\:\/\/)?([^\/.]+)(:?\/)(.*|$)/i), - requestedProtocol = (matches && matches[1] != "undefined")? "" : "http://"; - - webview.url = requestedProtocol + url; - } - } - - - } - - Rectangle { - id: appInfoPaneShadow - width: 10 - height: 30 - color: "#BDB6B6" - radius: 6 - z:1 - - anchors { - left: back.right - right: parent.right - leftMargin:10 - rightMargin:10 - top: parent.top - topMargin: 23 - } - } - - Rectangle { - id: navBarBackground - anchors.fill: parent - z:-1 - gradient: Gradient { - GradientStop { position: 0.0; color: "#F6F1F2" } - GradientStop { position: 1.0; color: "#DED5D5" } - } - } - - states: [ - State { - name: "fullUrlVisible" - PropertyChanges { - target: appTitle - anchors.rightMargin: -50 - opacity: 0.0 - } - PropertyChanges { - target: appDomain - anchors.leftMargin: -50 - opacity: 0.0 - } - PropertyChanges { - target: uriNav - anchors.leftMargin: 0 - opacity: 1.0 - } - }, - State { - name: "titleVisible" - - PropertyChanges { - target: appTitle - anchors.rightMargin: 10 - opacity: 1.0 - } - PropertyChanges { - target: appDomain - anchors.leftMargin: 10 - opacity: 1.0 - } - PropertyChanges { - target: uriNav - anchors.leftMargin: -50 - opacity: 0.0 - } - } - - ] - - transitions: [ - // This adds a transition that defaults to applying to all state changes - - Transition { - - // This applies a default NumberAnimation to any changes a state change makes to x or y properties - NumberAnimation { - properties: "anchors.leftMargin, anchors.rightMargin, opacity" - easing.type: Easing.InOutQuad //Easing.InOutBack - duration: 300 - } - } - ] - - } - - WebEngineView { - objectName: "webView" - id: webview - experimental.settings.javascriptCanAccessClipboard: true - //experimental.settings.localContentCanAccessRemoteUrls: true - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - top: navBar.bottom - } - z: 10 - - Timer { - interval: 2000; running: true; repeat: true - onTriggered: { - webview.runJavaScript("try{document.querySelector('meta[name=ethereum-dapp-info]').getAttribute('content')}catch(e){}", function(extraInfo) { - if (extraInfo) { - menuItem.secondaryTitle = extraInfo; - } - }); - webview.runJavaScript("try{document.querySelector('meta[name=ethereum-dapp-badge]').getAttribute('content')}catch(e){}", function(badge) { - if (badge) { - if (Number(badge)>0 && Number(badge)<999) { - menuItem.badgeNumber = Number(badge); - menuItem.badgeContent = "number" - } else if (badge == "warning") { - menuItem.badgeIcon = "\ue00e" - menuItem.badgeContent = "icon" - - } else if (badge == "ghost") { - menuItem.badgeIcon = "\ue01a" - menuItem.badgeContent = "icon" - - } else if (badge == "question") { - menuItem.badgeIcon = "\ue05d" - menuItem.badgeContent = "icon" - - } else if (badge == "info") { - menuItem.badgeIcon = "\ue08b" - menuItem.badgeContent = "icon" - - } else if (badge == "check") { - menuItem.badgeIcon = "\ue080" - menuItem.badgeContent = "icon" - - } else if (badge == "gear") { - menuItem.badgeIcon = "\ue09a" - menuItem.badgeContent = "icon" - - } else { - menuItem.badgeContent = "" - } - } else { - menuItem.badgeContent = "" - } - }); - } - } - - onLoadingChanged: { - if (loadRequest.status == WebEngineView.LoadSucceededStatus) { - - webview.runJavaScript("document.title", function(pageTitle) { - menuItem.title = pageTitle; - }); - - webView.runJavaScript("try{document.querySelector(\"link[rel='icon']\").getAttribute(\"href\")}catch(e){}", function(sideIcon){ - if(sideIcon){ - menuItem.icon = webview.url + sideIcon; - }; - }); - - webView.runJavaScript("try{document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")}catch(e){}", function(topBarStyle){ - if (!topBarStyle) { - showFullUrlBar(true); - navBarBackground.visible = true; - back.visible = true; - appInfoPane.anchors.leftMargin = 0; - appInfoPaneShadow.anchors.leftMargin = 0; - webview.anchors.topMargin = 0; - return; - } - - if (topBarStyle=="transparent") { - // Adjust for a transparent sidebar Dapp - navBarBackground.visible = false; - back.visible = false; - appInfoPane.anchors.leftMargin = -16; - appInfoPaneShadow.anchors.leftMargin = -16; - webview.anchors.topMargin = -74; - webview.runJavaScript("document.querySelector('body').classList.add('ethereum-dapp-url-bar-style-transparent')") - - } else { - navBarBackground.visible = true; - back.visible = true; - appInfoPane.anchors.leftMargin = 0; - appInfoPaneShadow.anchors.leftMargin = 0; - webview.anchors.topMargin = 0; - }; - }); - - - webview.runJavaScript(eth.readFile("bignumber.min.js")); - webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); - webview.runJavaScript(eth.readFile("mist.js")); - - var cleanTitle = webview.url.toString() - var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); - var domain = matches && matches[1]; - - - if (domain) - appDomain.text = domain //webview.url.replace("a", "z") - if (webview.title) - appTitle.text = webview.title - - showFullUrlBar(false); - } - } - onJavaScriptConsoleMessage: { - console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); - } - } - - Rectangle { - id: sizeGrip - color: "gray" - visible: false - height: 10 - anchors { - left: root.left - right: root.right - } - y: Math.round(root.height * 2 / 3) - - MouseArea { - anchors.fill: parent - drag.target: sizeGrip - drag.minimumY: 0 - drag.maximumY: root.height - drag.axis: Drag.YAxis - } - } - - WebEngineView { - id: inspector - visible: false - anchors { - left: root.left - right: root.right - top: sizeGrip.bottom - bottom: root.bottom - } - - } - - states: [ - State { - name: "inspectorShown" - PropertyChanges { - target: inspector - } - } - ] - } -} diff --git a/cmd/mist/assets/qml/views/catalog.qml b/cmd/mist/assets/qml/views/catalog.qml deleted file mode 100644 index 29e133074..000000000 --- a/cmd/mist/assets/qml/views/catalog.qml +++ /dev/null @@ -1,144 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Controls.Styles 1.0 -import QtQuick.Layouts 1.0; -import QtWebEngine 1.0 -import QtWebEngine.experimental 1.0 -import QtQuick.Window 2.0; - - -Rectangle { - id: window - anchors.fill: parent - color: "#00000000" - - property var title: "Catalog" - property var iconSource: "" - property var menuItem - property var hideUrl: true - - property alias url: webview.url - property alias windowTitle: webview.title - property alias webView: webview - - property var cleanPath: false - property var open: function(url) { - if(!window.cleanPath) { - var uri = url; - if(!/.*\:\/\/.*/.test(uri)) { - uri = "http://" + uri; - } - - var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ - - if(reg.test(uri)) { - uri.replace(reg, function(match, pre, domain, path) { - uri = pre; - - var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); - var ip = []; - for(var i = 0, l = lookup.length; i < l; i++) { - ip.push(lookup.charCodeAt(i)) - } - - if(ip.length != 0) { - uri += lookup; - } else { - uri += domain; - } - - uri += path; - }); - } - - window.cleanPath = true; - - webview.url = uri; - - //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2$3"); - uriNav.text = uri; - - } else { - // Prevent inf loop. - window.cleanPath = false; - } - } - - Item { - objectName: "root" - id: root - anchors.fill: parent - state: "inspectorShown" - - WebEngineView { - objectName: "webView" - id: webview - anchors.fill: parent - - property var protocol: "http://" - //property var domain: "localhost:3000" - property var domain: "ethereum-dapp-catalog.meteor.com" - url: protocol + domain - - experimental.settings.javascriptCanAccessClipboard: true - - - onJavaScriptConsoleMessage: { - console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); - } - - onNavigationRequested: { - // this checks if the domain of the requested link is the same as the catalog's - // If it is, it opens on the same window, if it's not it opens a new tab - - var cleanTitle = request.url.toString() - var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); - var requestedDomain = matches && matches[1]; - - - if(request.navigationType==0){ - - if (requestedDomain === this.domain){ - request.action = WebEngineView.AcceptRequest; - } else { - request.action = WebEngineView.IgnoreRequest; - newBrowserTab(request.url); - } - - } - } - onLoadingChanged: { - if (loadRequest.status == WebEngineView.LoadSucceededStatus) { - webview.runJavaScript(eth.readFile("mist.js")); - } - } - } - - - - - - - WebEngineView { - id: inspector - visible: false - z:10 - anchors { - left: root.left - right: root.right - top: root.top - bottom: root.bottom - } - - } - - states: [ - State { - name: "inspectorShown" - PropertyChanges { - target: inspector - } - } - ] - } -} diff --git a/cmd/mist/assets/qml/views/chain.qml b/cmd/mist/assets/qml/views/chain.qml deleted file mode 100644 index 9892beddf..000000000 --- a/cmd/mist/assets/qml/views/chain.qml +++ /dev/null @@ -1,244 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - id: root - property var title: "Block Chain" - property var menuItem - - objectName: "chainView" - visible: false - anchors.fill: parent - - TableView { - id: blockTable - width: parent.width - anchors.top: parent.top - anchors.bottom: parent.bottom - TableViewColumn{ role: "number" ; title: "#" ; width: 100 } - TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } - TableViewColumn{ role: "txAmount" ; title: "Tx amount" ; width: 100 } - - model: blockModel - - itemDelegate: Item { - Text { - anchors { - left: parent.left - right: parent.right - leftMargin: 10 - verticalCenter: parent.verticalCenter - } - color: styleData.textColor - elide: styleData.elideMode - text: styleData.value - font.pixelSize: 11 - MouseArea { - acceptedButtons: Qt.LeftButton | Qt.RightButton - propagateComposedEvents: true - anchors.fill: parent - onClicked: { - blockTable.selection.clear() - blockTable.selection.select(styleData.row) - - if(mouse.button == Qt.RightButton) { - contextMenu.row = styleData.row; - contextMenu.popup() - } - } - - onDoubleClicked: { - popup.visible = true - popup.setDetails(blockModel.get(styleData.row)) - } - } - } - - } - - Menu { - id: contextMenu - property var row - MenuItem { - text: "Details" - onTriggered: { - popup.visible = true - popup.setDetails(blockModel.get(contextMenu.row)) - } - } - - MenuSeparator{} - - MenuItem { - text: "Copy" - onTriggered: { - copyToClipboard(blockModel.get(contextMenu.row).hash) - } - } - - MenuItem { - text: "Dump State" - onTriggered: { - generalFileDialog.show(false, function(path) { - var hash = blockModel.get(contextMenu.row).hash; - - gui.dumpState(hash, path); - }); - } - } - } - } - - - - function addBlock(block, initial) { - if(initial == undefined){ - initial = false - } - - var amount = block.transactions.length; - var txs = []; - for(var i = 0; i < block.transactions.length; i++) { - var tx = JSON.parse(block.transactions.getAsJson(i)); - txs.push(tx); - } - - if(initial){ - blockModel.append({raw: block.raw, bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) - } else { - blockModel.insert(0, {raw: block.raw, bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) - } - } - - Window { - id: popup - visible: false - //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint - property var block - width: root.width - height: 300 - Component{ - id: blockDetailsDelegate - Rectangle { - color: "#252525" - width: popup.width - height: 150 - Column { - anchors.leftMargin: 10 - anchors.topMargin: 5 - anchors.top: parent.top - anchors.left: parent.left - Text { text: '

Block details

'; color: "#F2F2F2"} - Text { text: 'Block number: ' + number + " (Size: " + size + ")"; color: "#F2F2F2"} - Text { text: 'Hash: ' + hash; color: "#F2F2F2"} - Text { text: 'Bloom: ' + bloom; color: "#F2F2F2"} - Text { text: 'Coinbase: <' + name + '> ' + coinbase; color: "#F2F2F2"} - Text { text: 'Block found at: ' + prettyTime; color: "#F2F2F2"} - Text { text: 'Gas used: ' + gasUsed + " / " + gasLimit; color: "#F2F2F2"} - } - } - } - ListView { - model: singleBlock - delegate: blockDetailsDelegate - anchors.top: parent.top - height: 100 - anchors.leftMargin: 20 - id: listViewThing - Layout.maximumHeight: 40 - } - TableView { - id: txView - anchors.top: listViewThing.bottom - anchors.topMargin: 50 - width: parent.width - - TableViewColumn{width: 90; role: "value" ; title: "Value" } - TableViewColumn{width: 200; role: "hash" ; title: "Hash" } - TableViewColumn{width: 200; role: "sender" ; title: "Sender" } - TableViewColumn{width: 200;role: "address" ; title: "Receiver" } - TableViewColumn{width: 60; role: "gas" ; title: "Gas" } - TableViewColumn{width: 60; role: "gasPrice" ; title: "Gas Price" } - TableViewColumn{width: 60; role: "isContract" ; title: "Contract" } - - model: transactionModel - onClicked: { - var tx = transactionModel.get(row) - if(tx.data) { - popup.showContractData(tx) - }else{ - popup.height = 440 - } - } - } - - function showContractData(tx) { - if(tx.createsContract) { - contractData.text = tx.data - contractLabel.text = "

Transaction created contract " + tx.address + "

" - }else{ - contractLabel.text = "

Transaction ran contract " + tx.address + "

" - contractData.text = tx.rawData - } - popup.height = 540 - } - - Rectangle { - id: txDetails - width: popup.width - height: 300 - anchors.left: listViewThing.left - anchors.top: txView.bottom - Label { - text: "

Contract data

" - anchors.top: parent.top - anchors.left: parent.left - id: contractLabel - anchors.leftMargin: 10 - } - TextArea { - id: contractData - text: "Contract" - anchors.top: contractLabel.bottom - anchors.left: parent.left - anchors.right: parent.right - wrapMode: Text.Wrap - height: 80 - } - TextArea { - id: dumpData - anchors.top: contractData.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 300 - } - } - property var transactionModel: ListModel { - id: transactionModel - } - property var singleBlock: ListModel { - id: singleBlock - } - function setDetails(bl){ - singleBlock.set(0, bl) - popup.height = 300 - transactionModel.clear() - if(bl.txs !== undefined){ - for(var i = 0; i < bl.txs.count; i++) { - transactionModel.insert(0, bl.txs.get(i)) - } - if(bl.txs.count > 0 && bl.txs.get(0).data){ - popup.showContractData(bl.txs.get(0)) - } - } - txView.forceActiveFocus() - dumpData.text = bl.raw; - } - } -} diff --git a/cmd/mist/assets/qml/views/history.qml b/cmd/mist/assets/qml/views/history.qml deleted file mode 100644 index c72f8f3ae..000000000 --- a/cmd/mist/assets/qml/views/history.qml +++ /dev/null @@ -1,51 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - property var title: "Transactions" - property var menuItem - - - id: historyView - visible: false - anchors.fill: parent - objectName: "transactionView" - - property var txModel: ListModel { - id: txModel - } - TableView { - id: txTableView - anchors.fill: parent - TableViewColumn{ role: "inout" ; title: "" ; width: 40 } - TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } - TableViewColumn{ role: "contract" ; title: "Contract" ; width: 100 } - - model: txModel - } - - function addTx(tx, inout) { - var isContract - if (tx.contract == true){ - isContract = "Yes" - }else{ - isContract = "No" - } - - - var address; - if(inout == "recv") { - address = tx.sender; - } else { - address = tx.address; - } - - txModel.insert(0, {inout: inout, hash: tx.hash, address: address, value: tx.value, contract: isContract}) - } -} diff --git a/cmd/mist/assets/qml/views/info.qml b/cmd/mist/assets/qml/views/info.qml deleted file mode 100644 index 0187bba6d..000000000 --- a/cmd/mist/assets/qml/views/info.qml +++ /dev/null @@ -1,143 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - property var title: "Debug Info" - property var menuItem - - objectName: "infoView" - visible: false - anchors.fill: parent - - color: "#00000000" - - Column { - id: info - spacing: 3 - anchors.fill: parent - anchors.topMargin: 5 - anchors.leftMargin: 5 - - Label { - id: addressLabel - text: "Address" - } - TextField { - text: eth.coinbase() - width: 500 - } - - TextArea { - objectName: "statsPane" - width: parent.width - height: 200 - selectByMouse: true - readOnly: true - font.family: "Courier" - } - } - - RowLayout { - id: logLayout - width: parent.width - height: 200 - anchors.bottom: parent.bottom - - TableView { - id: addressView - width: parent.width - height: 200 - anchors { - left: parent.left - bottom: parent.bottom - top: parent.top - } - TableViewColumn{ role: "name"; title: "name" } - TableViewColumn{ role: "address"; title: "address"; width: 300} - - property var addressModel: ListModel { - id: addressModel - } - - model: addressModel - itemDelegate: Item { - Text { - anchors { - left: parent.left - right: parent.right - leftMargin: 10 - verticalCenter: parent.verticalCenter - } - color: styleData.textColor - elide: styleData.elideMode - text: styleData.value - font.pixelSize: 11 - MouseArea { - acceptedButtons: Qt.LeftButton | Qt.RightButton - propagateComposedEvents: true - anchors.fill: parent - onClicked: { - addressView.selection.clear() - addressView.selection.select(styleData.row) - - if(mouse.button == Qt.RightButton) { - contextMenu.row = styleData.row; - contextMenu.popup() - } - } - } - } - } - - Menu { - id: contextMenu - property var row; - - MenuItem { - text: "Copy" - onTriggered: { - copyToClipboard(addressModel.get(this.row).address) - } - } - } - } - } - - property var logModel: ListModel { - id: logModel - } - - function addDebugMessage(message){ - debuggerLog.append({value: message}) - } - - function addAddress(address) { - addressModel.append({name: address.name, address: address.address}) - } - - function clearAddress() { - addressModel.clear() - } - - function addLog(str) { - // Remove first item once we've reached max log items - if(logModel.count > 250) { - logModel.remove(0) - } - - if(str.len != 0) { - if(logView.flickableItem.atYEnd) { - logModel.append({description: str}) - logView.positionViewAtRow(logView.rowCount - 1, ListView.Contain) - } else { - logModel.append({description: str}) - } - } - - } -} diff --git a/cmd/mist/assets/qml/views/jeffcoin/jeff.png b/cmd/mist/assets/qml/views/jeffcoin/jeff.png deleted file mode 100644 index 2b9c6651a922ddf3fa209455b0a9bf4317d6c133..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84076 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

~urYns(~E9Kec*sUCR9N2R_`W^GP zV3-1Qo3D}7!nZ&urJMxn(n@1{2=Xk; z>1TYXm&Bb6W#&-_9~7z^1obk%40395>t9!ul%H%kqwV1O5_VC6&Y^dn1G|Xw{6Yr$ zjo;aav>))C@f;QKhv%Ct7_}PKS-qjWUf@+rsuB z%laKdWU?-m71nRE!nChPW$E!jrVl|RKQC;{7FJ8!i9y->bdRQehXe`+=(8>K3>-YvhDZWRyuv{<%uL#+V4Mt9?HQ3py7rwFov~ccRzUo zgE=qDme=V(=gL>n%{p^PiKczW4s#(CTa@R#GzXvB5$N%n83}aYSegSgPq#?zBFtd; zeN4#5E$T2_CF5Au5qaK+tG9v}J$y(A2ml?x>O&n&tcP@l1YL&Mk!NlS<0owt3(S1& zU$#n5@34Nrlm1n%ET&c{K^R~f_H|3xfnnqjd|cDK#-9k-`Hb{ zG8iEbL5mlInu@gS!5eN|{&Q+mnGC`2TMgRUW!3swx8OXov2OD;3sFZw9+^-dXlM;W zYmn#hA&<2jFL-3zao%vf!->!~x+;QzR=mj|$=VR9F5vT#XUYrd?l`nvzEoj24n<9B zD3!^udbe!uk|j$j^uovUWE;*+$9~M~T_;l(U2=KXzVF=z`qv7jOw3dayzac`hfm&| znSCd$UEG>;@o$*8e6Ylg3*nqRd`?Q@vABKzJ5Qj4>(6atP z8sW)I7q*9fUbYN0<+U_Vm<2U7ge9sF*EanT}>cwa5!L^pk)hBz%ueSiiswMQQVK~o1Z1~V^%Y;6i?O$(Pt#@kxp zDELqoX`UCBq5C2Wkjf#G*B6~KN0DGcmX@Wi39c;9s{k)Yl!s#G$sx#TC6q7HR97l{ z4-LqJPjpG&P)-K%afx@lwpp%QgO6T1unEo|l+;`um$9F$P{J0cSqmdN%y$OG_s&yCIpu=L!ao zvZq2R^yhI9V$m0T!e!5vQ>v)t%WD-})XV}KS=k}|P9`7s9o45*fcvp>A>}-tKsI^U zo=~nPTv~7K5|}o&_|1~S_t9ju6~K#&hoKGHLez0SS?_LOsMb7O2yUuaBI1IeOTqhc z&AmVw*a7effai%r?eg94?9ypg8NN*h;H6(zr;8y}AZ8ktZiU|3!{P)W)0e6p4u`{` z$w3RUepJ{$P-8yxxbtBbFKYC^mIB4O6P&3H0x-xZZ*Bv1O#nd&xH=~o>vGbaplN_U zpMeq_3A{vG`h)qu;5)8>QlFdTA`F-kSdcv0jXz+|k*w{>fejNt7%yI4E9X#04_ zUMa6Ak;b`8ZrJkGw_I8*Vk0pX?dZ+e*F$%oio-7uDBr5z?i=xV``ZaPu<-)S?B* zQD@{KT_1>%hGU^lnWsCF1XjWDC?haVp%&Wi* zg<8zf=pzYY%1f0-=6tBq-O|jsJXJFp(_Asv)pshI766(& zI{dzEZTehl2_}sv0VKxa22;=n-C#i`J1sXa$^bSxC^TF7EDt@`54J!a1$Y@Y7=b)i z#?$d3#bo2fQnCOKjPZfW%%ub zSR=0kZlxu%^2mlGvgz>?a4n?WG%dOp0CE5XT8DfEnCmj=%MY-2Gq5}}v{Z382BZL6 z^g0DygIm45SDmTuc$Bnujh}ID{^6Tiv5>22fGF41S*)DAw56PWNHkNT7sXxEI5Bc)G3|tPF>A+W>6_iy|VHp*q z!YGhsyqqBCyol%V;du-fAh5-{JNa2$a3(jFNDVCV?b~{E#sg|b{cIK+w~pw7l-Vm_){wbgA1KhU2tjz>F7Wjq02XGhl2?urLjru#I%x}Um5&4 zd_5vjK1tF`--1_ku~^A4KE646T-)z0T!#AEu(N7yh5{{G17ZVVTEj-8m21{8L6=r9 z@`4>Sfbh>Zo=_u+51F{=j4nKbxGjWZ)-OR$r;Py=fw=~v99B3c9GP0VJU$*5Hv+Qx zeF;9`K|nVIQ?!!3#mSIXw9bl9@C0a51TK!01uRAT0gNbH0VL)daSEJZGJh#~%*v%4 zZ9fXx>%*)EdD#72V)E*Y3-I!V4J6glq$LNE&QqrK+uJ`b_rveYua2N1x3euMpvmyu z`EwXrxBfh{k9bSg-AU>Bw`1e+u?!y!mIL6%(I0qBPKBtLb+bO}J4$zHPd6s}wLWF~ zkJ6tl9+u&m33t^!&dq$xYd>~uMB2{|tDbo-c)U6IdUL%ev7Fy2nYwiCr30rPz4h7Z znFx6k9(a@4uA8}6u@7y5KBDPE&*=hg27n~v`%TYy4QIL zuz|0Zbb_e*G0gHM(0bpkw}8FXt03(FT6yS-!1}Abn8m<{VFVi zuD44I*Itg$_rY|CYRftO0RMbY1+D1yhQrsp8`P};dI{tMGc~mNwE$+6QEM9Ya2?w+ zSlo0g5G-l2((1Lh)3AIb3TI%36SQ#+&{vLW36~L6vFnsFq-n*n9?B-z>pWf*u<2&T zs}?qxD3g9_9t_WE54n3V2M|?oX{h$7bD<+wp5?C)~=LoQyhT~hn7nWqC?Nv8EDU_b+iX}D1X=s`^RrRx zTWl8so@-2X9BtbvO>-Ax{oyV?WSh_%uhA2BYk%k+>(V8C*C#nT2ag*-SkKpfHQYNY z2X^CIQ&xhEd_|%r;g>#O$alq-u(aG*+11Ml8g#$=yVnMR00LENg z$-z(IKr(9vpR1LUscR)Y{W{<%UIQM$T-xlQmZ23ytJ2V&?J_Hwpv>p?1W}#IK=fBW zT2~w-R*nNk{f2gRaI%n(L+XQHmx}?JTfu{o0T#iOFl%#i5dzH=sHg|*Y?HnW0ke^Z zOkTak2VU_-3R;t-QG>KV)#_yen@*KtK9~ru!SpcXJ+JrStPk>8mi#D7 z%ZpzNAwVe5vL^87u3Yd&z> z*D@$4PLIInTcQu~z^I!)e|nlhu@FMB>9jqIYFc?++AMVPQwca46pYHMz}({QLCj`R zf#eA{&lgh8k9i*IHoAE_>$J^>QLgjjYz8m7bFi5F-aY+t$;v8CtKoq>y_4%Yiq8Y( zq;b}Q>$iPn-MUr(`Tsq6zNCpkVc(pvTfTEU=I*YUp`eSEyKEykVTUzzs-;`bwhhW0 ztWZ@O8Bpw;erFl&RDlZtY2Nx0*SKq^GoBEbnYNuB++KfFq z^yUFd1l1HkhgKqQ?YXOelt75QU|j{(l{JsR=m$E-yFOr}9Jdoxb>;$O=qtgLjXaxi zKu|ZUmOOk*j=R1jfp$<-j^P2zfw^|jr{aNHWzQ6Xte2C_7PcEII;1&I7IAzB1Ko{#nZG8@aCUl#Q%02hZBmduOA>>1_wlu}k& zj^R^TY`z-P) znndh`uxj@2;?ru8`SYuchAd_)fa-t%9|<~W*l~Sv1IaMW;?9}^zxVTb8u|RL7MC>v zM7D>!V?fzF9;l_~y;715%OyW@ToQwLJB_`Yvk?HY_OOg@g>cW~!JFoB#WDghf!Xbx z6=87)%9Nq9KnLh5zkWk5E8Vboxd1jFqWSTtZ=OL(_KGh7&2H5Rg8Y6Nk4vAxqX;*G z7k3Uy?h0-o@C652x&%Fbk%7QRAXKmgaB`loK12if(wgQpGF|c!O44N_3Eq&ySqPQz zf0Sdd1kmy!8EoD_eko-ExKn6&3IMFWTh>i^wA$Gg)UV)+_R`WsGp()KJ_CDR7;tS? z|26&DRd7SGJdfATVYEMh9-KqS0}szF=M0nIgP!#VrrkvrW!S%Lr(DWG9zvcHu4Kk9 zd~oiv3dC=8({@J)(Ry%1$O-$YPZx%f!p|YfX>T=HM1B%JhPh`C-dfXzMEs1N z-YwOWn&GCB>p2FWgV^6nmI({I)nf;*ESa=mT`Gxn8HOEw7^dcmfLtYo6;cRLzo-SvMk$ zH`NB82B_g>4>c=%qY!%EErApMUT?(~`)>)X_F6E@deAmGT846Lv_lRo-kxC@0ga#R z;q)+L^*j8`wUEHTj8;r@U2-sD%i?7Gi8w{O3`srss6 z6vkU=s?kN^e(WR!8_coO8F$TTAl0%TwVo+JnY8@3E1vXwxI zD4HQfu{yF?-PeD&?{A*xxAs2odvATk#%f^St9|cz&u-RUyZ@ba)^3jHGe|FZl^rl8 zK%RnECgge?!7h?8I$OZe`0_Sc!G0NiZx=a_(#H~1ai=9_HRg95w$v#6A!E|I43nWgTRIJ1H;pHn}F!$0^Z4>I`&E85dv z?`7$LOH}H${0ysbnCdlN72bhx?0ezI4}{jkGFzDsc}5cZbIl};P9pWsx;pJIcK1R2 zg_l-`Pd_;vp0MG=?bwyRIiBa7^q&m#sKsu4;md#H;~#wYw|_D27l+!ub~(+~4}W9n zrC(bcHs1l8(2qJ002w>8DEHyJ8^aFY4SS6<89bERb(Df~bXL$fmg*{d@F{+ct_`T( z>Br93{Tpb9K(~Rdwjr>r-48O5(!L7n=a{!6iRLc zvwA%*uob|jrCaF)Mz7xa1hKBS^<=SJFrU~-4|i4}FtX(#U#05>+=~I&`C)~1VuGqt zYN-n*G^QoJ4}bzGC)NPl2JrnX2lHVYC`~6FGH=|J$vl`Qi3G?Ela?siA`SQ+`1uWt zeZwEyFn8NH*7B=%r?*9d^$wX=ixb+`FUmh`=%NY-#mnY%f^m+ee12HedY(3RnRJ`a zfb2BYpU0j;PBCDwCwY451wJzc0KfMELJdYqxXOS|eSc>-y#M{-g*Sg?ZTHa+eq$=~ zrLtby$+gqD*>5ded2u-X^p9z9IuL`<4sG8(+B+WJd;3`?ie7zXHJ!aiP4$hUYIgfx zGsd5o;x}>E!0GPUuD|OZ-dlXRWHO~egh3|&>inH=4D+x24!G)s+IJuaAmI~LgR2!B zl+jJd%SkeU6K?c+{cAEuw<**}uSp!-Z9wP2<0!FCe42Qd9_uEPjfZ^ZWzoqdMznfH zgEQcvK_HEvfNVXAVS-Y<>KB*^eCmSB5E-K@7mVZ~)97rW6JU)aPr=vE`)Ev4eX&mY zpD{R%lkLBR8BS{eyzcxeRgcoL@da)t)efjDi^)>u%8O~>Hm~k$v29H`IW}$LcePMf zPjG0Ehv&F^FS)TktUe8qjAtHtA2F>YXt*XG-s>tS`R@K9k)eLvnlXHx7k{71NR>MI^{XQdy7v4*;tU8SG&~S{kMlJ-}rTRK7Q*j zK2QI4aQw?|nSUc|;r>7Ruisp}`^GnO{NurWdPMKw^bY#SGq!+!_~XstMYe|Cys?~t zS)DyYDjmp9)Ca}1-2y+~ZQQy9?$BhEP3Yr4MN_;8x3{9qTl~_0#4J4@VchvHr@-)` zO8iTG(DbnZUjR4KYm-_7&gED7ky1Z&X;yHKq&ot&U@nLkkY}XmJ~$kX$7X+15?dlEq$=goAzw};~ zHFeSAtLpgh!Txan$pKt@Ell057W*1yDS+hG`cYVmm+6b#wd&bSS?xF7r^od)HOhmu zz0X1I+2J=K`75%SDbuEo{GpOwySFktxPLf2dd!;??poad9jkhdpMA=k*!FP!l{dcm zhkx&Hzxh{`$$z7gvHx5?v-zjLy>$0i-W+y*f_TgJT00CqS_wz{kKTL6+TFw9i?3hh zRl1(ic6g;jrJTuNG0a!LJ_vf4ZWzf=2};l)-gsrwsc4Iz^u?n~WIYX;oU(ju?)KN% z7W_BZ(#+Yq+W;@S()uJ=Ce8rcOsKgT!pXFzB2X_};i?nb)l>|ldrGZPe((y-1b~nB zSi=kOy2{`)(kPWCaC!B?Cs1`smAB5kk_V)u;Zj--D06pWOOUgy0!Jp*@=7m25{{%B zeKHi%R6Ky1c$s9AAM{Zd$QSzQc1j#|0*dVz!NK$dgXnyT>$=~*+CfmROTZ-$@KYCU z`E;98e@E#Z*3w^NZSA{!{`>*DP0Mc^j;aCs4awWit+8=858J+3M|udWPjvG0?(Sdp zwuaQZ&)Y~|R>ntzrTz1oUT@yJNg+~?)@8qXDBXLweG|10b@Kj?c2Zwy56g(_2zA5J zqaO_~yz$jHH$M8_rPT9YO5g>Q{@wX&cLA^;0k*yK+xr?M)8!o*(X^t8!*m zQ$Sc=v51C*S1bF4v540dp){7V5%W&D}5b#YNMvSvujwY}O zJ9Xwrqbdp1u|!c)`J6C^9lyqMX9NkPrB{;pH>-t4n1* z`u+dz_QK5H#dn+zBM>=Y&R+R`nSD{I zmd+NPo`Ve_%4;e1bTqsscRS!&KI1^MV~TU~)DGQ=%g1iLg|z#d2)VqXMYl^JK%1pt zk#MyWaq8+)u##_IGA6)wDOXx)lx)X!y~f8~fUJL&o1En93!B?4*zcp-a&p;$l7B{( zWfmwSrAh~hcqiaVBOU}30P9&_-vQPhE&yr-%1E0aoNW{kcKt43ya2M#wJU&Z8xp5q z0ZY;~-?pg$s(v>TH7LJ8qVtJQrg-I@#V+4kQdX-Zy5y{sn}-LaWHaiCfG=rc_{*yi>eJ8aH-G26-*|HuO-iE7h9-`~r zWqzVnW$N>1|5)!;_eEQ^=>xSc+KjSJUn5UwX!OrqlnRnrCfSyTXFRMQKdOFXS)FL} ziF@$q$J8mSLGHfz>womW{5Q8po|nYpu((uae&hSUv3T>%Uzs`J%M3?bRdzeFhT8b> zN1MYgJAz)M(>S06)ow~^!LLJz(OOjRVbggvx1FtZzgJVy}{B2kQ>XSrK7iXe5d?ytBqubq3*y*Lav(`~<#S z1;X=yDL$1>j^c^DO$KBNIF>CTa0pMO=SbHesvvJVk)|VQ3%Ftfz)jc$Y@M7lZOc@7 zu$UGyphTOv(T%fnqH^#-oc4yqE-)?q8tqJ9h#SV_uXmT}@bm>EVG<6%>MzzISNz>7 z&4UE+-`%Hgly|~@zMleM>KmE1E+h1JF7lb2Tw&K&<+;R33fY;Nj?lC!#WnA{~ z>XV}s8>xeVHqpmHg1dLByuyy|qRVSm5Cd{DFkH|BWFv7l0MtJNSYG}Urz9_>W4bFqoi;2UoHsfJedNy3iI{6|!lgJJ>CGIAb z3(~Xd7|b^Gnhw6nA9bYcZPhIC<7C`^wv<_y)P)xSIq4(#ThCOI{UUwCI%|IV*Jb?X z@SZ+Wyh;e@eCkd}q~0y1UdSg#N5Ay#_G*`^rT$ z?=*e!JsK8Y{&)Dg#BFrD>`+71V2&rN5CmaIwdw>V;L`1?xAwI^Dg=AEI@n0GMLV(M zCNtAzFdrJznf8CSam21Q3#Gq-0tRtqiQVz3MG4bY0|8mNG+J>~?C^6*X2rn?dL<#H zBEhbMy6GCMe{{5A8%T9cuz{1KofQ z`5?Kvuty5kk4#K1^ITUjhLL0T$zm(7cYv4WWZS#P!$0_^k8|u~%AcySBC4(gO=44B z-pf>78{R>*Xj8dFEufvI?fj(2zXAISA~#h$?4#>Vff6MI6}e}qH%#;Wd2YQf#>(oE z8aR*P-Jdk>-B}!-K0O+?d5aXBlUKrN;o;!nhn%!_g+q@PzA;9*Bo>~{m&ZK#=l|`! zxswmRo+VfZ&!#$Nji{#&57@DGIDGXh>zN$zFceLfE~abB0WvXtu(W|R_H*5YNhm^j z%db3}MZeK8iLc+x()D5S3%`?<7c-mR4tN$XkV{Sitv12cbc`b}{FAEoE>0z7)eLfI zwAeJ0^vgYFPFBX_|G^`q7DlwdDZsd)#0t#ocX9#nfI@CC5Omeunl~jwP4b2{ulY!Y z4pIs7iZ95?4v#)~l|rSBpS*Ajx_(cts|TbB9~q@woMR!NQtn9h-ktcp+g z^pE9_X>q5+x_#u)JbW`L)6*Ma zH}Cz%fAv3p+!$Q=+ob~DqsM>x&E+?~@ymltvW|CYeqWJV2V;#y_iO?Ij6{Wy8a zuCyA_jF|#+@5K{FGQ{2e;vct(j0qL5_SGEd`p^r$y2VZfWueGH=Qvg(4lr{UC^fwvTp^*9E33TzbDsln7uekINn!y= z5}Q?Og{yqct>0EFbq9V#_Pk;rNOJ&W#yX(uF_1ZZ4f+{BKTbY#ppj(;OiO~N?uhSJ zSEc6@6u0^d(({QxVU*ap5lk3%9I9SU*tKTPSJXPXA~@BZ)Dm z9I-+pnSFOED0a0+9!UPUJt%FLp4xe!Y?(WA`)M?v4I4S1;W0^(GmCi$cz(mD_Ya1b zSr^~Ktf`YdcCkIXKU{zHjbDEMkN@PG1pYPfo~y|V;XK`Y@QuamFVD~Hyu(03TAblS zR;>#=m_GXP7N3ck9d2;QhXB(%_1N)SKg%tFlUJvzAVTo(-BG{1PIg9dcP5Q4fL*a2 zN<~T-GrvnnyVV~4c_9RR$W8h#Uhy_7Ko-wNwAJr&E-a#3D!;CJROpQ2LF z_^@pXFoM7&a4PK@CipmsCRiFr-ELndreEn=1+xhXM6VhEEuhS&cnB|DYpVwm3cv!g z*2C)!o`=UDtP$if#zm0Z$w9my^0Rp)hWDE7I;7i>owYpj*M|*Kj z>@hTHW45iOJk;GBlC|}wG;6pll)yciZGqW%kBs!o#}>&I5b`^ALJmEOlZT;g`pndS zRSmyZQPpdjE-gVVHLrSrPti=%Yj;&Z)pR{jaCLX*>x0cB8aKC(h8uhyKHVgAQ$J}e zV%nHL#heYVOrG^Ka?gA*nr68`o!n)T?LH5JBkS2Nt0BrUm3r{_!{PdiU!OnR`F+(5 z|9iqN!Ox|Vc!!1I>vPNO{Mvi~gehs+VHi0K9M5IA|H&3R)s}`emIOHf$MF%1gQIoQ z?lyiWn(i$4RaY!vN{}K_=ml%-lMdepjC8&RJ9y{V&b)BvYb2Tg z3Z6K;z^s6_+#S5?ZS~g(*3sjdCkCWS0jA2LUQk!-5+t|x&Z5tqMbw;OBJIQ#4S?Lj z!ZQA=J_$l++2;K$(jjj(*+2s5o-DBbnZvm8cl3LX?E>u?S4LAM*SN7|H$;wuT~L7{XEuM_Tv@KO~c`1U$#RRs&%qjSd+h278=j7li z7>XpoVD{o&mi4;_!{)Q&;SPJu9W-^Yhalhp@@|LzysJ8rPjd%p#W_dY{1cvzHyv*L zax=mr2`t?G8i(QVX{v4142KVD?DS<|0Q0zF0V%@Ss<^S&1_(jg1gnR4-Wi=YXO6p4x1bx~RXX>g z47mVY>mdUQ+UUWn`p34d=CDqC^R&Jdx~liF9Xid}|7@?Kr|=o6yc+PzvFvXO@=ohjkor!JoUzIWxLpyu`Ivs&g> zDjoAPhpK_2R}m^!uigCWzxeyVceAH|(eIZ=;$3|9$y*E8Uiy;9D4wF3XWr}WeV-au` zU;0%Z3h>$FpmR?gWA|F5SP8lO>r(KjW@sD@n@+vkO+Q(LZrX16n4QMMTj#U8d%`&l zuJJWqT_zBq;hw?R2Vn*!ehfgB4^cTJCU)++1z!hmO=8s~S`P!ove6;Dk%+-|1}^|d z>{G%>G-`lMD+=T$dIOFkf)M}j0sBJ#%r2$x_N5Te$Sce7*-$}CnZPL}4eyvlpZG4aNh z7Uo{`_S4R*-_MXwIn0wfXE$_gY#noO4{@i$wOaqrGXm&YbKX52+QZ-#cAY16FUqhZ#vXFK$9UY^V1n(1FFn5h{#$te%LHEVpGyP0M>`*XVePfwxpun$ zxCWeyG->#Z7QXB9>BqagMh`rl-RIB1RN8BeKMs_182t&KGPSAzk3={-urh!~21c3; zpw414kl@XLUs%60EZ+SUI^-uM@tUsEZumgMeFR~dH2<Nxi&!M1#Dy^!m;oo41Z;4Mjgg29vU;mhl8>y{g`hy!bj%&#hQyi4 zI39okogh<7zY3sT@9U>`!jJf_sh#1CB_C0QMe4&m$ghYhRoR;%rCJ_b)of0H!~Es4h_L06V%#Y6lQM;$f223@sV3oA#1Ny+Pzm4&xH86l}GouDp|# zzI<`I?#n*aXF4dQO<>ea`ed_D$M4~1{oqHwZt~TXkMHjfFR-Mmv<)dqkCJw1l`{IZ z(h}CZ`Wpd-`w({nPBQ%A)VQ3PRBbMLnU> zt=14EU}~UDRnBzh&$vlg?~EOAyIURwpuKM=4iiB0x84|L)?OHf$A7@u-6y0fq^R31 zNh|7vo)`0}oyc;QSLbK)NevGNV);YYvtam?W3*5CSw$Z3?Zk*n$qwO@lfvX_vJN0I z3VQ*rz}oCs1m{#UsYks4FbQ&kZPxn&qS>&(gRmq;U-1Fpr~{OSi7yyCp%#?@^~L~? z#Af;~opTMd4<>mqqEBXA-%Mbh6ofNr=86XMkxGy$XFcYxGF$$sFXEBGqzNx+d{wu{ z_`ogo4Dm5e+*v+g-N$K!Y<1vDn{J@kXCp&BWJdOtuf(o8Yu2P=o~sSaXr(c>Nwp;5 zJ;vm&3L<|kEPM!FU%AH0 za<&O8#zfV?eRct*|LL&tY@Z1UJ{6Ng&)Wo6i(UhQ9z}l%C{Oj*3hM)=BGllpQ&wj$ z-P|NnkJED}{q%rZc=7ARq-pr_ah=D2s0oNf%8jT{>7D0eis|v;SLsC!0a(T)p>Cbz zd76**ZenMEKIMC2KAeJ41PYvznHB9dz*?*-b_7r33kU*HX8Hv@?5@f6B(Mdxc;&1F zBu*vW1y&}^qbATU2op64Xm`VdXEj7$X#j~j$>xd)zxbQXWCD_UYISA4WRn#ac><6= zan$WbhYPqb@QI*#LEUh!?4~1|X03iK>$A|5>CJ9=2y zKTk5vLzBF#B1-jgkG^)yPLionOk1};w)Q5JqPqOdO?d`udLf!TR8^u)fZM7O!Ych9mBfm zod?_bo^NRU=+)4j4W0m-Tof>h*4|k>{XN4|sgyGr7VmtO_udV5*S!a*7`fi@r)jnK zeh$URXXM_%_Iw;^HRP_ne(I?Fbd^KG$HFvK0|Ul$0J1%p0qsEUyd7|{!^ZUc0E|=$ zov+;)oPbwJwa_rgm27Kr%2$2W0ry_;AVC5i0<4K#jj1YLZOZ)yYOK*l90g-aHgtK7cNH zQo62u;0Il|m)b->@=qapJ@tD|B}@JGu*$dTj5JN1H8w+Kf^cbDNqg2B(OIXNKOL^F zv6+G$nRjlh3x}c+nb%@e9uqKb{-zO{kt;(2dy6;b0=IQEmP+>3#sC0707*naRKK_y zo2%j)e&s4FP@vsr+xaRRJG$z`@*HhH<$1`1cXjQHWAqDdp(kE^^T{9l-MjOvci(jJ zkekMtVxbc>sh3%DcdH#99M#er`ilK{y2CpdCIey;UW0&vn(#?Ieja^wM(OCL=Mss~ z#w6P8`mJGZ{Uwg+XG`j}GMZ~$io2oH?T+gNUj@HM=~ZRK8m8QkSr%n1^drJ&RSMK@K< zGHF)6c3Htva(+-RD8c%Ca(%AqfcPu@8s2_S1YDmMPEyV-VXwCx!FW=ZNf}MwZ26!t zkLC7ZVe0yYHAHonLO+wRoW9zVWQ^rZ-BE_V;>CdKKjGZyD!&!h;v}T(WBn&?V><2G zXpr7W=!pZY4likP;*T7KrG$I-I|a3eR(-RyBoFfnJ+!h4m; zHQxlbIN>g)k(;I)DLABeSh;@d%m4iE|M%zvFTS}H67R{=2VYsdbLS1#kKz*So2s*U2J$eUIWP3_0#RWn;NLqhX|)oojShCx(rb8|asJy+Zk?vbNvOOMq4;@H+Xo!( zZM|qzFKAcat4cr9t@4T^TtbwH69^ zi-UNkY5RFsO6D!b!P}%++f+(CxvUg;S#vk<(42 z6wXy?1mx8#XRgz_@-N9mB96)g(Dlv0{HNNDj8Q*arq!E)G2Y8QdWGwx-}H$&>7+5u zZbr88FuZtKhUI0>L_n{)x5oiGd=5TRYmdm?;+AQ7NTusTfcZ~g=U0@~7G>|h6F&0n zOnW>;9VRmUMA3$;W9&;6M0CWVLp~|ByEUxcxbyns`|rJpCr1ZfY*RhpVwaK6px^)U z;`*Jn;bfbVQe=SlR7uI1ZU*s_hg;F@`mHE|rJLzNAV5ys^cx(bTZ{j8rtxa@Eli#j z#{?w$tjVq@wg?Lzr#tULRZ>#SRV7{b^gj58c6ZJLa00q!k}GKw9%iTo{Bx<9S4B>x`SvsG zgBX7w8m?v#)FUDL&42e^<;Yb&jSRoh7E9G#`N_k>*;V6svRoc&jodb>b}A3SGJt7P z?W&|n0Jqmj(|C9*J`(6CcXi0>2T22emk?e>-LS*aqE)tfK$v}1KF7No!}^Wu*Y-C) zc{RK)_|K(~c#jXCyfL@N8_eN0ozIOEUE(cia^uNvRx~&f(L05`NV}%r%aLFD`&5s| zS~RT#wy=uc>CO(U^wRM5N1g%|r)u5$B9bnzUfUnwQ@~L;GnL|0z9P+qPfw@kMV?dk zF^}i`r)U~mBefC?!+qWc+-E=PW_uC2_w}MhU*PK`RC3auFMVKkU1!&$h96*-gU!{K z3eLv$K>}}nlMn4qs_7%>j}wfxBM9MNBD8V{&2y-c^w0h`%S~871*NT%jrkgdss{3S z;_;c}!(DNw$80)KSBy085<&ILWynqH1lZ?p89hMhh?NUV9?XC#g+(%$hluT4Wwscd zk9Kp@(RjL#h0XY5{zIDFkKUj4vwX7r9HS~_jo19Ao5!r7r5rw#VkUX2VwV3{WN1=n zoq9Upyk9zKkAI$T5&J@-#QV`lb>@d{V2nuM)b;V^<6-5-7y01#(@U|k;Zgwa>Cxev zbBk9PSWoCpO1kxW%42vq;0e6(bZ1y)5<;n^B;M*gX8_m!lksAAaac?Z8pC23u;)g> zv{SpCx%{f5CYs5S@C>`H=CAR<-+P2O#cnl*v;3NXM@MaO#I?OzhIwTdW1P>vxeG}VN8d3wc8D=Bi;I&Gt5UA;j>6v zuHkjn!widX0a(vGwk`$i)Nd=JH5Xkqz9|trOhIW{UWXd8$np7iCe?VUAQHl4-^U@*USi^;V+!|Co%$m>o(uG92Q9nF&)=`yIi^y_rL z*u9r&I)2ZayR}Y+Kl|ZUK6CFF@><|s+RH(uAZI>w1VHtRTQ3~-Uv|i>MExfhZiQI^ zl)q^c=~h}tr93fY2RmtclNWdGR2|-QW!iO)EyTV#%wV6*;pluxgf@?#+l!f4b7xzr zns^8+Ig^;&Tsl^(Ex7YH4i3VjCQ07K>yzxnT3cHp4dYaK3GU64d{&#ASL?Lbt97j( z8OKz6X|pu;k!lNlG(}r}soU}nU9&#-CVNuM=8ko?5Bn`PLC;k?&S#j{$)%g}p7EnP z@fc|=W6B9FOKs%gv#tE()%kYb#^n)}3&!wTTOk6*ZOq1tu@jNV(H1KkJmhG0=8G-l zLf?AvFKi(X_8z=3v#|8KGufaNZLG9Q1A8$rJsfABPnY{~OS@_YdPXxON>}N@{0MN( z^nujfP%;qeD*Gg4Vrxw8Xt~;;$~sQ`2%cMifo!b|Gkgm!n*xkHNj9u>P6i;Zj7;-N z0D1K8)oG^h+DR#w@iJkPHB)p0beXb>!NS`#Ynu;;hn!KYF4uT=76&54l`InD5obQ? zB>+3=hF6RO%Ym!$S8stWeliKIlBP))|9~D6urx}~M(SBow`%^BF#Xbmu;}EM6jrDH zUZ$qhdxRA15;0e=2*Q_wZf%1}n@HbMuxZ*F1bdR8&m>6L!kVB_?ZVS5Xm6Hj0#)&!zH zdtd#+L82``@#=%7!X3bdRmbXN>5k(dElPhw>mZ6L>1MPu=;p4yl0kmFkHjkz2V-t6 z{g%|22g17<{qT66z569b6^cRGfn*X#I@5F|!Vlls<}@!}qs6Q6g^o0Rv)7cgTVc8# zUx67CQ3BR(QjyFJY;~1E3Nkt9{8K6t>HCU^;zfJ#Cl|ja0ht(8iQwnI=qC7{3b^5q zpXu@RJmg47+dLW9Jmj4=&C))H1ed~L;TI*!DIGe~JCR(;73(5qDi zU8>BTgtHEp#Hs{x#*cV@_iWZtu9rV%lKjGz*23R|7O-bi4N0CbsWyWm`;^PqaX%4s zj5OaT=zIjYn#1+5qOM&?9kjdNj<}z=)5ZLl4tZAE^(zpk91!!5zq2v?=f8OqFt(2o z+}p&gHPij-0a2d%$xfbQc#kl3uP_L!6{bR}?yc!%cd+dqQl}g!FNKV!jL*I@!r?lTKc}X40{HUD?Sd18DS(H*qSs(X^h| zi3ptVZ=McBB&+%LyG;JDdqpii^3XVj z+-kbPHsN>Q-^<1caVoF=gd4YjfN|1*SJ3R?^3a~INWe>4LDE;uY~95jdI7eD`--1W zunW9|`+DpWD8bLo6H1%eS{xuHo+7wXt~|m==@p;^cwETkLFidy3_pvNhmN4+1g3p} z18-(dUEN}O`co!$vIVGT`Ems!z4^%YVWi+=K_6a%aQsO-U#^gklWm0i0LX4O(vwz@ zzQ(!EH?OE75ooI2tCp>$Nqdy5ey7_eb{=PN2l<(> zNtvYTo|7c1J*N3qSf{PNkht=daO7*;shBu?(e#^i`#G>joD(UpaQ_c>M9f7 zPg%%*vCV}C-jjo^+1V9VG}sH;GNTMO2Ov7Wz3u(z)%1i2=kqM@Ijh(>G#&6wX zAKho9+8$JczPrv2l4&N;$(vp|yL_D`Z(B%SewN6z8eP9PX5HWW$O*eS?qLPo6`@Br zOq!IedrH#nFjE?N=l$K`|M(}5hL0cYv-XmmPb|LA7aItdRJ`@xA5?v?36OrdV?O*K zAV3g`BloKS0;R><9;~d z@A!mCR5K^ONCR`X1q<-%&ga}Z&T5Ba09FYd`IKm$5#a|jIS>f-O1`5;9KZ3V^lJW& z{aldx2f)}Z71m~6lU1v5RqdK3%B*ge2go8z`5GYLaeTs(Ly~HSnJ&Z zcWmE8viv{W7-yMP7?0`e*1cu1=Xmd?^Z$IeA(giY?Ii!jvx+h@K9hhCL+XQV=Z6QR zZXR;kKa2-&-u4zbFL`5QQ>FZcHWwdw54X`S++)zPh6Uj5lPQsy7;yW0?9m4t>=cnq zX#Y|VU}^no(%B88Ka4pPCPGIbZcfh z&ga=HW9F~oRX&Ts#IM54ZTFL++Zh7GKl*1+hJX0KeLB2&cVYP2TWewalTY@CPaYl) zJL(4ccRYb%HDGWEo`RzFD7c!6Z{!N2;cYZBR6s>4jx+(l%?W^0Hb`)H-I{sxVDdR0 zL>`!vS$IG945`L*a`P!4`8h*Rnj}i3o*|{vMbbM2DE)*_^B08WuB7Zn4BhZ>qeK({ zp5K8kIg@lIMmd~l^G^wyNW{S(-LY$U_W@H^eYjHK1h*h>Wl33injH=R_WO_bhdZ2j zCjc7?i4^|C^!n-U&%5_F`n>R;@kt`icTN=hi)|MN^?0y@s$pd~zW=nf_9X5_vt4-LWh3}7vxtsY zgf}5tsKm&sK<7WU_Gk5iH5iPo1i6q#= z%n%fyGTzqC9o^H3p*?2?|O&ojN9D?if|$;_0;dG}OMT6oG0=>pFc7VqR(=Q*U# zNtuhT%BsEUVhnG|cykz#{nV$Gqg|7@tsO>p_ir&Qk913X9rYP?E*JaTXsE=~V@`A9 z0G-4A?Uw2odf_Y=9(a!rncW7|7!h0`N|qMUuF)5w=;v@8L03SqvvsMrTDscbL3q~P zJ>+@bobNM5TfBQb<4n;h-MY+8#A8`aMu&RDmTs4Y#V?>avMq2-DD{*36v6l~AZUsOWYkjVD$XQcxzzH@#}+6m?hZZ16Vvakr?MUqtH@^z9yt@M*G7|?wV5d#=gj6(*E1IG?< z&Xjc6J)v>n$Jm231=?jVck7zzphfNwmag+}adAiQw!or)^XIXZ=phA%p30aW9`S4G zcYD7leZr>QV^;AEAH#bdiV%0@Tus8gyUW9^8>nD-EnVPi9IiuMQlC1vI_#14AM>@? zZP)G!Qlg87c(Ra>m%yq%)#r)eYnVWn@0`XHh$kEt8JJt4>8kk7^(8HC@Gqg$z~fwU5;K&w!d^oeuIAxThSKp))7u=%V~ zb3+iRE)Qa)Rb|*?bl#D2c|h-x*KMTST~-IE3qPbDRaK}HJ|@f+4+y#eT_^Xp_fCfQ zx0plt8mUsbV>>1fKkKJ*`m?CchFj8#*Fi1e)QuCSE+fk(3fyDQ?WmY&g5iYYG!N}{ zz>eTtH9AH4oOlxuFFJWMd4_D^8-nfQxQj7OE)V#hXKA0p(nU8H9(WbavSdgg%VK(7 zK^+=MzRpZLu&Ui%LC*5 z%Gv_kP8Wx}42&oHN5ek*{xzm7xVDr7xa!I^#1{2s3F0Y{@6U32BX{<#`VWbF;>lBPirb*D%vEvbaizAxBYwoq$m0yjvmSM;bk8re2zDr6TdNd!Og`7UItV@dpB!% zk%An)4qW%?3pVL2G`axgSorK9sm@kibOL;nz9AeKPq^u{%{n!>r0M32w|U5`HJuMV zSJF>LIydu1%oeHVuiwLS4Aa%<&5QqISkIf`2K2HtHv<6d8ovCc)#3X;;6NcNX49E) z>Spc6@^Jgs%J69CaM;}6%`2-Q;|XK6JPbR7Ny(NP4~9j3W06P-wz&hDU?0*VAm;8e zC%}{xqk{$1hXr<=k*_%>vD}Wkz@~oFI0h&^EXT>RQ`8KsN{Upy>;SfqoaY)94gOIn z0Paq(@w!t$gIluDz)R`Zhw_Xd%ysNVn!89_ZW`G^m$1FVx8?xa-Gc-4xyPvs-Bz6d zX5ZNZfR%QAKk+bclE)tarp{bR;4ax-{{)>eX6G-$r2jTXv6~4@9zwZWS5^#yhGn+S zEC9rf6ubYa$&3ej1oue}J9vgFk^E`Eo{BZa?$$1QX+o@{J(z2(B)vS8iKD~p&`W$% zx(w#x123(ZPq;fYT-D&BR3HD^)85Kjc8=;0g;A|@v<}s9OHN$;#)DYtSg^4ZV~S68 zw4%|!!Y2H?J5lnZPo!{Y>vgyTV-4h{{E+KrwHE%OXGY z`n|TJeI}#;w!M80SNClL+Ic2i{O;NbVfz5X($W%>LFjr3TUc=U7t$*LeSi+v4GRP7 zQRf!+pdm^a zZCiu%euHN-hI{=y#uh0Pw%y@fpp0kr#2%y<)f+?h8%d={(^OkgLuR3T>pq>&O3P3$ z+AV~3fHFl};T6{X>ux$p%X~nPhc@r9bK0%F)@ zVokuM#Q|OiN;Uz|Ve?17?SrE_SbEnKF9(m#>c#!@CB88|&lGLvah52;v5_KGl*AVv zpjq-HQy5J0Gs&BNa(#Xny*5!N>4iQ$KS9Q9aVu|~Pu*wuTEOgZ<0g_O;CJI1pJ_o7 zQ8#$R8^Q`8=|>cwvMZ~Pa|fNkDNs7-@=;2v$Z`neE=@QEv^+dr>GqH_1C$&y;lv1B zV9?F8Rd;RoJtpaZP$IA@zF3tw?XFmdKaqyDl&9amL2tu)MOwC&U3^-Wptw zU6n&UxH=?n64n*bsdOKb>Jm?pdJov9y1TOls3Pf-<_3WKUMo-oYH0BH+uaf%QX{DlPDOzd|0=C8BCjy#UZU*V0BBc4Gi(xV>Tyls*FJwk-yTQ5 za{-+U?@36rO*}&7V91rpo$9LQp$19C&+;i#X&IT^CrMBIdODV+GSbUb?(!^p&`uV5 z@#CMy*MBG3e*Dq?aO29tu(Zm0S{61OAtfH8n_X7Am6VF>5{d&@Fsh9x1Ui`Ta{|Tc z&*}xGW`Nd9fC})+hfC?_xJ{P%Cb6$Nf<>_Ag?Ih}VAKo?4Awm*P*fG}Jlory=Ny6s z)_$V*U0xX0uN)0)ODsn_p=*=rQ@jh+kKK(C zZge;S=#NR;@21^E;=h4@`{vEH;VK}%NPnq~6Gy`?67m6UzQ%NyshP{L4m zmgcg!HY*K|{x1>(KN%A?wPd42T5dg+mJ+9Rqz-aMnKozqr}>1aI$@`urj_)>2_KTl zyuJC55D)L2c3Q$6^W4G}B&4HTH$LV$EZTkAU3uwzyN)`=gxb!39l$u^Q%M`FZg}Ai zn>zr-qvQR&b_<$);>^2X>!*Qy&0kvb3)lQm= zGwis7|13J;xf#yq6|7ntdM1QY=n*<=%k6~P-VSF{pjuc0*ymY7cSKsZt}o}P(Dn5t z4)9(ke@NZbtq(!h9G_5zSs#!bJ$dA!Uea9$u+zuL`=NSf%C$~@EmH`31*b*M{)}xA z#G@UniR_T+1OAksEj%$D)bvc3lc+@w$U+(#ynXr5UYBXe$$nAyibg@2DYxMjPyV5< zfcU4!+4&;Aw6qd()}FZO559kK(O>eAmLq)C;XA=>J^Z!A+bZzi_S=c;Vxw9Rd>sTD z8sAxRCT1L@o-vTEq3OLvQNMOdFFGBaV%kicXZ@#Xy8V3I?(bdhr#YR;Ng>1|I-!Ww z<4o=n8gw?jxX(k=~n)uHdV zyk-brK+1EXX`cH6z!kk6e85-==Bs4s(U*X&(&=%ZXEg~Zpk8MP|U+XK;PfXT5eS+IXjn(D|0FNF7gmrcH$4dGXQPvT2qB$d`=$o0YW)^5ST9~ z{sLySpJjD<;wtgw+p3oIpKnTHRI+W2AsK}WzkY8~3os3nwgD(Kz3T>W$rJyH?{kM% z$d!$O#H+AMM0*nRhADTqPXTcrVET6nJQ0nNbSg%rIoh?r&@VunZ~LQlV|_&y8sqX7 zrNqmFEFUT83@+&X!b`kL8mBHbill2NngFjIVjkdiNs~*QoC%-m_MZW`u@CefK8~i| z0Y{3_(t&UEc&>%lY-ZS_6396N)DE-HpduS(;D6CpsIhcR@! zfUY0hRIf{b!BI8rvny>6Nq(0Hk|1J!#U;O{Of3u?au$H52&EoKF8Yt{Q9#svEJsYh z)V9GRe%iED8%Zay>Z%n1hCmU2!?Y)&&pixoGG+{`!gaK=o6r^CB$0T_ZQtoZ}~sthIDSMDwj-+hmVmby|-=BlF^ z88GVS7WY!6i`WtL8t_Qtels3q(5ursW@}kaEVJGLB~=YQPxDBli(Cs_OSHut>I@}F zWwV^JKsob82EJTlc%yNUAmk_DD+Wr_- z$pP09>V-p=$Q^J$;(nCR;=q$K=M*;L%yXE_tPcSsa{Gzzzrb~*@ZHUQjuYKyclQzQ zW7IMW!>xHgFQlX`+NA*jUsN4nNHz-CkfSMplCFbf;#fyPqvze_DVRZ|@z&@^ueiIv zJS42HZyV?~e*#@F*+AoPa~*XzJ)Z6{y)*Wn@0NhKsYugtrg`{g;L+Z{;~aGXSr#T>9lX9lJ>KJAk*}B$L1D0l_lM)v)X``L?mS$M)Z& zVGC8qAyT$LeafX=#v>`|yR%P|4JDM>Ht=f}`97TidL(5XcEL%Vlt+FINqy)#L(}LZ zI1n|lr&vfUcIMs!3rnd7>c`!6hN&8om3*etXza_A-!o})N^CRd05KAj73_=GY zUCI9pkk;zGclJ)u+-GQd*yr3kZSRELJt4Q(@rs31?y-1t3%pwUl5EdT_x1*jCVrDV zPV<^%djhJ4k4xajxU%6d5#Y8WScGVl#pE`JnK4MKw<$Y(*+JQEDKPIJOUiI zi1T!FXZYmf&EX-RoZsC7M5&kSOoq9s!zE;bq`S@5*Wgn*CgXH*(Ht|!X=h6(96LDY zK3-J;fGyzdc?)|;(k>xeW(CJQz&*1N#`1c1F>nRX?cw=->N=`4fQ(0KH3Z9dMT&0VA!^xq?~o@3a*^ zJQAMwf#X*`@*aU1N(-m_tTW(35_*IB)-BvasN z-k}er_g0jieidIp>?P3NiKckPYbLYuTdZ;Q5E{?Ib@RX~lVNMj;0runO1^4xz}s9| zd+S6So~jn+08p3l9-&GRfYql9z&i}WLtj0eoI@g2Kf2&jFm$IgfUrB=ws-ja5U=(3 zndE!)jPnwnB6V^w`wa2G$1EjVd4aPeIA0=qdO%M#iERq(RGXSP($G1p&Y4VG5AL8_ zW;2FsiOrw7<|QWN=2@0@<=WNZ*6q7FVQgXcVRY6@d`NA9ZzEix>^C`e>;zr2dANCF zX}EG_iB%a)=urtIGaT`C3i-Rl&b7_SNJu*`3Y+00iM>VOi=7|&Hdm)<-60g+Pe<7+FNr0SWW4d{ zOy$pY#M{NvlFJiI?O^{gDNmp~NR4$&m_`tigzInX+EMSz*l#bBA z2EbXlaxJZT=xeJ0G~L7g9PM3TW@736Kb;d~?xZ^0dOR#%eVr)0wjOglWb$IRnguRp zp8%@8wg*c!3*f}$R^`;1cv#|{pLm8;;i&tM(k~$n&h?d<;Te+Ny=$%z;FTT;c+r8= zuuSRJL1ZyqD(b7YK%w~mJ=NUrlRTVr#AYK+Ad zcChg}JO>DRX2M6GYz+^e`l`>tGz?n5TH~bN%IeH;g##O|UtJn*Twfd3ScS32WSLI_ z&rU#@h-A&(6)hfQnF87#fcHh?>qua;*SP>;3$lp5c8z!8nVp^CIH zmSDY&mCXjZcOGZsBs%$<@X;hkPa_E^iC;oME3jUs`*O$&QO{E$6;PD4fc|GP!!*mJ;1>J);A38AhwQJY8dDg1_0$O$K=QVo|o9=Ydb^qtZ`T6`D z3{2cS`*@gr{TnR$N6)*@@sRdsOwUrKlVLdJXTHlAE^zkzZa6V`nAc+JNxf(5Qq*<5YD)*uNx$zvqwWE4 z)ATLF&%hj^S5T+A024nNIY+*nY+Ga-FfwoSf_|*gNxW-Foi~s!*Kl893EEBav%X$u zxT@2YuhR4pI@uF+xW@~qBxX7IoC!RQJLsa%Z~Z{}rRBw89X_g}RHMuTz@AwjGUFcQBLa|gRStcF0^+!Z#(_&{`mD_BXCN`ifn?K@=+kE1^HVZf^?4U>i*RDjGaA^?FZ2YR@KCi*2JCflY zu;@0=BmV{bOcRL^;2q}Hm}FQ-1^SSj)WDpiBVf_hll{tPatwIb+x_dbx#Jxw!$SjE zqwV)I^ex9lTA(WUK7O`6Jln>6((%#N4bwwte@baER#sM9xPe}I9eCegM(6=~CFpnBb90MPpZ9!h3cudNIVuiO}J0B{1fr+wYLu?{G!6F)#Q ztu?Z4hHzbN^uwUD=_~E}(aPu$SR<`H{(xfnlRg0H^O87?(`m7%&PfvWBv(nX_jleFD>7Nes_W zw=kWU$|re;ztrW%b|!9>F8NHX9m3(f*)2DnS+mY>v&odpQ zo)`A#_G6?RKK_vW0l`bR7#!~+MUr20V}7+2BI;FFeDzOgg+p7;=ftsWh2=!R-W(&} z_{poqWq>ZRvcX+rPuXnn3L7bW1$G01XVNb6njID-SggpalPCcI2Pm8XF~QeNE~5}t z-*~#r>n4D82A1Pq}_e0 zUo{A^l7GvgI%H*Saabj9YwIgW>Hs}ui}YVeln0Bd0V}}eY3>BnX&qT7n$%5m7_Hpg zDaRyS|3GV=?S=&O^ov6ef|@;2bKLyI&xZ?ACS7|Awa&F0NSb71mNtqiBPlhW&F(E} zJTFYPNw^1|b)N}4$H#4qhtxAwF|4xu&Ibek#ScF}d*%5Z99Z=Jm1{TOX(?RT+l2>S zTkiPq=tq2Qn3)&`Q3IR2=J6W1dUcHfw=!&@AIxid!B!f)04Y7VbpY*uNrn!6xN)CB zzdg*Zzf4~KFY+pY&_OfqwKa3joqRfaF?Q^jZW-@q^F9GvsjG|=Kf%6Ugq3*zgKu6P zKHdXxn20>$M6Z0D6977PMS$8k(srZ5F#vdszd$1|S2N_5GC-l~fU^#k0Az<8puURa z=y?ksIPL*F{wWt`ovC{E>{fcUrg zqj$NRbL5+}@H8E&IBEvp1XhrEd;ZKq(pb92%LMg)aQwr!{?^}q*m+&l`=tP0I@%}4 zdrxWc+YCSkU3!#*#J&GZ!}|4WEKl0XD_D9#{ruIoIX&=*JRUyzXqdb9I%A$!eWi0u z9tif%*voPTZ2Jh|K7yw}8~~gQiZ0>W)d|AXXfC_tows3SJcB{~>h>dM#WVSYN&v~# zb*md2>M{jV0FLysngCEc;*12>$z~m`C$E_WZc2|@qx%IAmif+{DIV?v(tIZ8$R%BZ zH(-_ZzNiy?%@?WW*^qH%buD`4#brLi2~r-q5`+c!Gb|Ncq^|q~kN_Gflo9SZ3SL2E z0QeYnglYI`8Pl-z9;Cjg5)?3B0Krr*G)X-ZoIdml zc;#1Nr=}ksV}Ci4U??CrhnyWiXsH%uCym%+NS-qckZ&) zB%FHMWi^W1$~~vJ@|r-BCJ&42!@&*@^_jUJCej7}xfH-VH@E)eVDsUydh12{yShF) zgIX>IhTBrF-o7<_^2vJ)9tTo}#9uAbsNK!YGBnpOc_KYBTTx<5R7x}CwRF4hBK zoWRn!9(N7^@Df~bmL#YJW6tuabOxUit-!eKjzIvx$KV316OLKB>8`a%n*t_rjV?IN zGU+nw&M@MOXiBZeNN{fDJ@u>6k!n>X0G@!Q)suC@ykj4E&M)$>OU+y>?71CE*|n9J ziL}ZcDh3Y0A)`uWg2NmSmj%kH#HbX!;7Sv6tC?r@f~TBmY$N9l^0f=>O4I6>4VQu? z$SjM)l740F7)h|Ra2+h;WeEO;LFIq!`a+kY6UM#b6&PF@?0_Gnc#C(jO%!-1GYqb zs37rfe)^QRiEHmnC3Rt~mjifLZ$I9D_7i&Hx9GEsf*^~dK?#C2nJ?ZM-ur)$pcu@H zZW!pj<}b9_JJY(K@4OBirMQFpKOC-p<+s`TdUH70xlaxpY4%g%1=w`Nt99NM*1gWH zRM5MCRj{3mrt&LB6X0!(O()i(SIYa^%ge*}Kiyy_*3|%uAms#^>VzB~!&p)sYVrc6 zGv}^Q$U0sps3^yRGyj4wbw0;~MV)T{I*7VjlU!9YncDbFj`}EVj;qDzC9+XY>N5zwW z$Z$7%`J8e8w6I1Vdh6FqW1MM@;X%f?_*UOKQg@{P-WSu+=s1g4hm8mCZZBTD^LBB$ z*uR$oc;{E|eYE%V!>5e$>x?#fh#j+E!*KiF9VU1fB+O{90lfeErguF#^sYDUSDo^6 z`7<*2AHGli0HrIh@KMPR5#o5QZoNA97Fn<~g$|klNMSy;0`rEZRR&8)rTtWs*>=P zUa-rz@Bm|w0!fp47XSiWc!}QGlxusS{|0nt7f=tdu2#U#XM1=<@UujDl@A(A$sbX{ zLnh-;4fq;Edg_DSbOF>x<>4A*Lw{nc02Q>vWjbz*)`cIw~ z_9OEO9XIi0mIr}4Vb>wQ&Vlm3{OWQZ44J2cHoydN$GhD5DSy+0Nehn^r}g4Z;7z#p z#PJ>nG~Hgbs!8_f(+{5<3}5-`HSz@T@&F4xQJ|i($0Iz;R{X1EW!GP~$;C_^K@pe4ChG19%_2vwrKPKaKwd|G5;vdvfKqxA*V=!H;Om z>-IDc!nP|!-M|RF`NGXeOB=ij-MP6m=@kE3jo-Vfk!z3@o7M?Gk0-$%5_0tHqv41R zA9FX~98N!Ag3bH}9U;iQ-AKkEpPri}1yL>1_q2N4F>0ep#QYei&LAdk_(6+&tPO8J+(B|;85ghgGi<$8&7gGam1ss4#K@h4{Dd!u)X6%Q zBg8&S9AODpq*!2^h;rAE7xM1zJWt3niwVZhFu%f)bO11FHg?q`)|aXb*Y7eplz4FE z!DIH=ri-N652=x*c-7Sc1+wK?{!$Pg5ba>B!}JQ!&8*eXf!F2^pZFW6(NdRBA8?ot zdAfIRg*v4!1icnFmZ_icXzpn{+>&-D)jb`qf7a<%m%EtZrWY~6qRn6nVlqxt%5UN!T&c{E(P zb(KZkYpiwT6EuI0>ZpO!2TOIhpT*8jnTwPIyn7qN!K3#Ayv#Uc^k!fSP?+4X_Pe9} zGvT2tKp5jRKi!(d5giz{^6Fr%e>deX4ZwVL<7)*X7Wz@r6Tr_k4p}b%FVAY7N6%YlFO(E) zV`T}MOyTE>hfK`*nopqmSy|$V_*<%lWDlor_$(y4+!Av@FCn^8#QcT+Y@wbPS z-~2B*sO2g08GHK@)0ngH059X%1?}#@bC6yW#auD8u$`Ek~E7_?YF*s zb@<*#+r!fh!A&eh!W3-C+X=7OAx*_#2b2XOxA2~-e1^CbMrDG>J=bY%XPyn#`6VSrkL>kcefbq zBN!^Z7Y3Ozh%g0s+62lDyydTi8~UUNMN9XTCr0%l>ZFAg-!LqmBmddq?RPeZS6^Kn zR@qW*Ii%H`?}w?f9!R)FPW~j;RA$N^KDKqJ2rF-aKc*s&{xh-&S9x>t0X#7f zGoP{bY>OR%r=LvxFSe~U(Zw!gm2UCFy(b?aBJs+l#OwZjFO-ljqQ8FkCSRFl<{PP{ z_n*(JmGr^Z$3BndynhX{pB^bR0MzbB{|caD65{G>fC#-*sZ>DnZl`WWAT78472vH| zM?c9E9^jVNd{ka~yrPlNbQ%v?HoI}W1c0x;w3eM*>JP0fagWR@ZvWm!)$3q_*A%>_66HBv>4-JSeyRR4JGF7Fgroq})y~ zpU^cvu9bEvv&RC z9Vf1stcr-EngIZI2fz#`N!@++HiyAN$y~C63N|d%D_tHf~T+i;;(jfu}Xz?!5=>#C<1Yo zUL~AmUMfZ5ET=_0nK*{kfY@&{UpPvcZ=PXyh(RRY&>#8PP zwl-&6P)hKgSq6ZX)^Zf+0&hO@w%(og^K4%E2)eW~bz|Adh+xaZ(1oy8PwL61h^7IP zcf&lVLC}Q_z{`nXNW9xSJVc0Ipa>C#3xHCs^;shO2mCBFfF+0uxU#n2H~@h_e!pR< z3P!t9ajBwUICTI3KmbWZK~x_Kl+!fvZvdTmWuHf{{F4uNBS^gT@~XKdXS7Z3@RBE2 zcN<=QFod!7>Xq`7c=BMTq$8`^I*;@#eJYcL$isXa&kXVjsmBNGoa1d%CB2n}vHS5@ zVkz0};mL;|^S!&KDha6Mp`y!3+bi3QGoM;1p?|t!ZKx2cM zS0`ocl9JU`o%Hi6s&~NW-OtDAee<)lrp3TAYaHCZ`=kGRSbXVQ40EP&YVh6x}=?_K&Hr)bA8MxAfWH3?KSstd@;7^m~M9LCcKzRN6lehs~$pz6DW zr%oNSgRDSDsgF8SVpJj|n%hAI#{(`^69Th?9x)HvKtHiN&f{sN4knTatPLDj>o z=!M>O#@BxS+-xD(?r?0S-(~Z&Kz>oeMq5Ba_G}3CycC~hUdH923-Hdf5o2*>8CHgS zxh|JAw}7_iJ_w%CH=8|pshWti+YrMCN37I?hu|EOVI|z?n8_D-%Q+U3oDBc*Z{NrR zC{nFi0C=>!DntOz5;yW_KD`30kzR|Ar12*kxq3YPnq5B9+i@C=cRSLbes5#Ab9ag3 zEmjCelBTx`~p}L6I6>1g68G{6+gnQbNxyCDH8AP zyR2xiUZ|_|Q7hd8q2{j*4}bilr`KP6>qD#jG8k&*a+vj7Z~S2A$xq%rV%L(oI}TH& z2ViGW5u3=7cyDCuu!o5d$R+p`fQ>bDPMSS0-Hvoqmfl(Wy$97~3cWCCnVxnGec%4S z`@y$)&AmP>-1s8E*e9T>(}oDr4uoWL%!`ow`Y1fmJnZ`^k28xXonCa0*NlQ83(my zo$E}HVye9h#7erwQ?T?B*Z?cRQwdkUs2BjPs=ErazDlJ~G^1oJ3#*E7{Zwu2AZfq* z-uCe3o9k+6TDu9JW&q3p2M z+BeBtH>nHyhaHfTa!0kZaFxl~`Qh=W_usv7_l+M;(!JO=YyDD~SAXm8JU-gn`rhI8 zV_tVwXmkKJss;!0{&4-~+HmvU_2I!IPoJ_wwT^5@J7?0t?d0w1!QE|?e)X^puoJ+o zkTY?3m5i`}q<8rEJyZ^#3`?*4CjC>1ck&<*{7R}#AI_kfNVU>=8CKvKu+$AQ)MZ$w znYK^Slf8=H?~^e7traKR_Lw~KEMoz87v#+f2h+89)&n3=SJjvP0+qYSJZ90|YoJSw z|B8}&tqK&(RAC@h@3SI>;}|_IlUW!*mru=a?QmcYuhXP0h(v;8&|9Z&`Uq$R%-}D; zFLR3d+Vx>}Suk48H`N3Nfqw}-u3MS+;JeM2EanYK3HQE{XUI?_0G$3E$YWjFCGc{5|vnZX`VB}4r#m|KVWK3?dR zbkVQir<&;L6Am%LdXO* zaVJFagAqPn-C(EFo*wQD+wc9$Ve!RZBX8>gUnv;l_dtI)>?I4Lyvlq|qpLhl~ zbKc)@{me^+Rs0FPWugoY;#^2}O1Ye|V1Cr|ZXn@#n2jHx^awzuVqePzD%Y_hH%1St zbh^hm43Uf#6B&h3rxYd009}A`CfEEeF;2R8B*QhEj`jJhb zBGTR*n>9Q|tPZ%bA(@O*B4cGiz1s4fJ+~UOBTduw!EP0Xh%)Vw1_$(T7DS|7+b12s z+EMxiQ0YImtqK#>C~oA~LDjKG-#H*pk606a?>2`5aj_J5(f~YKI!qjhutK8B;fd$ zUovjybE)Gld!%N8R$w(O_X^KW#3of|gAC!1A0pTw`Fp^{&WHM-dSiJpKq^}N+bq_|+ ziTiy5m?Nm3lWIDPsRU!FhnfpMO1wvT5P(ml zkqs8a5pk+D;G#BdS2*H(DfbyM)S;ixr@#<$$kWK+3%*& zE+=kd1awaikb3#tcs-zfQ1d{xuaKu)%o7~r_Q8^}1G+q4@(_BA%Ia@^>w3-`7F3nK zv!Mf^ED4v)H9cy-N2+Z&7QHRFCZ>560MkFjIxp(J)DTuC{_yv*+|Ljme(^Hwf2QvghP<4q}l1tDgTyuy9=_ac1EzJZb#`?8ZJLz`tZT_ zaF-o?_O~oKq>eJdI)e^m`R?%HpZ)OY#>-#*4w<+##u~pgX7%2${_*C=fA)Qk2Tbn; zbQxJlQ#H_Dc=;L|DOQJ1A28VLgy&59f!G6rEv6m1o6&CPKI7jhrtij^#61%dZ}LQXk*;x@ zayP0M-h63g_{M9TDutBmgqu2Fr9Hp?>xPT0G(e}G2`B(icP7UCKl z;9+1v0lDNY6-()nl+^L6+f`2}fGE`pn0^Y#S^SmNWmE=DZ|m|YXp}6$gG^9SrFr%B z)UkXuf_t_yhfFnqx@P-Elhm`hgM2vKN7~lsA)tJun_Q|BwrnYvpsX**>khGJ8%G?l z4&0NzD>U+&9{?sl@b7Ai;2aT0Py{$f)d6(+n;+>+Aarqef5Ws_xL@M@lRsfq7VcmA z%2n>wzCGSZ*!ar3;#zJKv633VCUean`v|ZB>P7=?Ny^g6OaB%J;N3;nyur8fZn7iP z2W8bGH`;LU!2e-=xc~n9-@p0BxBi%fFO9LLFO7NqcYp8Wz0C*T-QRqI#6_nRc$Hux z#T;-b`r>f+rE9~d5BC_`XF<|FMTA^urP}f{Z0yUu59Y4FR~tldD0}y>do}^sZ%xOG z!8D8HxBd1%9Ts2s#xQr~g}i>71p(l*mtbM`7$8cz0cdF_AUz$YRx21j;YaM|ZkbSg zD}sQYV|c=&g1+|ZI_CiZyh@)$^UJ*lk^CSgvr#jUv8-xP|4F^NszDvE5G#nCMBgrR z?0{W1TtH_%1Pf$rdt_qmm}8aMvdo}1KduB=4A{YCv1CJ*!KhK%flv-q@K0MbeoXmfV3>V=a0db!M69qOYjk3>(o zHn$FjS8vS^U*=U`&Vs+~*{^`G?VC#}6}wB$;&#bcfoUEB_Mu#Yw`otVl6Z9&F9G|2 zw)o>edOZBnTUUnbx0uVYPlN&KPv7%^5lk&8U^!m8;TeCI;`OVm7MkwX`cGaaak~nl zz!!h?=T9E*QT$Vm5#>#TK9UC$ZD~8ttli@QwKr@$+WhYC{%61Uu~l_h47Gf@%-r1C zcQ!wMn^&CM_1ZYKtZaVqboj!TZ?JWk!NaSfeQ{z6I0em#DX`Hi-U6(HWU7ysG|~J* zCm0cwL| zR!31mUgH4gv<>3Kkp`eco91o#6U z2wB4mtq&NNP6_O{Zn&aBPz;t$`bBpO$Xug@i@#uIeF^-hs-q}iE)p+$SXTW&SADNp zc#ypJ&erhY{@(D-U#EXtIWP){QnPR~fm~TX8=iD>rPQQbVFjGcp7^wiGTUa_6gcH;7jM2z4Get$$LMdQr9k(nt@8PCNGy+x%1Yy zpT7UE4hEL7q}N8;YEmx){Pnl)L~nJU8R_&z!F0SP;2WvczSsKvH~^^5l4#F{IZQi^ z;hE@gU@*A6d_7HTglDB=22M}*hOHm`<6-qnzsoHAYJfmYtP4I}kE;i!`FOB4$*Xw2qC)4EOkLrf4ZBGuXS^d%%8b%sOs7VI9 zQlp^jW{Q)nr!L9U`VLH37?B*K9=?|&9vSx}2CbX~Iu9yWZ-3-Q3fA^+vg+X(p9%6a zK8O2T_&pp>ws{TbYb1wE&^>#$!L`NY&nA-D*08<13%;V677PI;CxWU>{Nm^2kSd`6 zpS|}0*XydzgxBr8=oaex5rc6Wo=5qp}OSNE}Ce=z`OSeFiGz3f(f;aqi>=e@V z7lA4p{?Sa)cpUO^KgM-kFsA3BTQwYSwXtI`j~FwB_&5o=n)io&NV1B?+QFSWd#cCH z+@xoE7X6?m&#o)CcHa87V|%yu^`hu`m}{T)Ja;q;-GNijKhve>ilJH~rDpvEr)x;2Jbq?Dslu z39`w&Isgj6K(7W(Kiu&medHhg&S;7ZKcH8XNJRfLTwV{U0QPM*B4CLw@*oIvu!%Dn z*zxfrfYl-cf-TC0QATMtE2^?_agPrsPSYbHGC9#m6sGFtq z$vSQauy(e0T75&S)$KoKuWmbFTej9=pMqmnf4ULVmD;SUrPaFHnym|JruOCrOdG7X z6DJ$60e&;KP3(l^+k>fOTs%Rk)+O3hS&^pRHVnnBB2l_`J+@1huv3LX-8Me=r$YbD za_c#QUO)-GGgof8giAlzag(2s zXB|+wT9Cv>fx{UA9SeEKkjtp{p~ZcGgi*BhVN^p#kb`=BW6e6G0^-7XN z(p(^s%fVQpBVW)okq}=N+6EG3raFU=%(LU#I(jjv<^b+9V^~xIFfzb@-UL)~!ApZ~ z{wQ45Koso6LR}&xDWucrB|e~s$(nm+^)VYYve;(LtyWzK6hWIzBMTMktduZ(n4a?u znL!MB$YflnaXK&~F~X2B8Zf=B)8RMdcX;R8;r)$PS;5&N*!vhSBxYP~3ePI1Vv3zQ z-e8@rJ?pP{@2CH-KVywGm43y?n(p_1y*;ON!kWf|+tAA}V1>5g)5$oy0UZkx*vvU2 zbTVrrHjw5(4cnRD>?nS#6{!oLH3foH=b=}mqn$h=A2!Y;ilQcNw&g^cMtr)-hhTB= zIjy=Xn79N0z|U@POpS96VWs0Y1(y=(o|>TY2`((KdJX7@IVu8naXir1GFd+=+z|t&Pn9T+9bXUQ5f1 ztO!T6cXae1Up#*giz-mp946y5xOU9T?M8l8Q<~<+9Ajl3^4SG-Mi;`RE&&Cld9Kdl zJn*Y7tkE945&|J0rkesus+Z^wz|3V?4RpgP{UBbfC?4zS?9L zEE}yd4RVfhk}%~fO0hoO%M(`y0FZ%BCg>=wN@|5az|*DWG+vZ|6B^nhU-#$qKE|V( z;l$Bq8(Ztkv02}m!;88bU_L4)+M!)Lt+Zu(>>>McY`nwA%D5OD7ZngmY14u0|EF{>S2Vhfk@TtV^*GzgDr zsF5*V1ls_xR1GA$+O#n7C&tl*=Vuf^F0TyY#EoXp(v<>4IMI0tiP?2Jjv^ z*kD!VS$GNY#f)c(y5UQis;2CUNf^+?z~n=8lv+~L*8ueU59abrp zO(dkEK|qpGM~8`SI0>WDoK?gVTC*`Aq6QDcC0jRBKpH!e$UsVWs#+7bvr*elbvyz# zZ_-D*$4?|92BMMY3}PAau1Bn7_6i8SSVoLSoVrj30TW0m;p&D5{ctf%w;Dg}jQUF? z+~EM60$gTv`0W@_2!QLtj0P^_rF6r?CVP=b>Pg$N1lOls0RXY!LLCvH%pJwr0mAKF z(9Lp{nD#p3A(NDN`Aqmca4Em^@&y?@PQ3@axOHQ7SugnafR00Qxlk?Sl;B{;Qfvc> z(`@_E!lk06J{f1laavn^Hk?b!=jqQEv&INth9C35WuLCI)4|GgapzQQf z`juoWfDNFU0Ic)zM$9-7oayg8SgpqnoVL+8VAI>2zj!sB42Le|S5LRP?K`coZ0vI^ z@7Z{TM}77cy?n~0&osQYaoa!+&Rff`08mkH8ag__V9eM8e7Y4`-C@jbK9oD zHR?EUr_8jD75w#;22ssB8cp13and_u${zVdTAG~Zly3va*8$WztaQ!_fe>0d@{NWq zfCXckx)~6|+%Es{s3VXL2iWwMaAq2$F$8!$29sn6Cmm?e2rll`KxwB3;LGI_n(ctk z_kIjQQO089i_$Sa{2}Lp9^i{R8}qAmQZLmFkXkvLqZjjSI{|pzSVG(diN6beJy0n) z2ts85y=xC8V*qYG=JXa|PHzqd;qVU702{Y~%!YKEhXog0utMp&xQM_4bqIBjcpFhq z+|H?Jcu{mAUF8a49Hi^UfE{(al+JrF8>Stg-%aL3cDzIy8@p}%r~(@^9;zVL2PDVj z<;hQcGy?hI1tl<+iCQCwLM0=h4SqhG25}HC`g3V9rFU0J0OU}XE$dF%!Mawv>e{K0 zcDXMD`~zTe@q_I63ZS|mk#3`Z8n9B05T)TP*rlrlsPfA~l5GTX#L40;2-4HU?evTT zcV3|##|b69?Jal-VaYgGHB#C|9S)-2vWsi2zhIQ@+qik#nE4k!gK9b}FSh-&@|tt) zZFOyp^=sN2v5Kv15;_hyVnGMj_Ygln&1RibX(zE;SsRWmLBAMs5j@i`N;0}=(n={- zwaYH(S0oW4qHCtyAWwHFEXIRLmI!D6&c(EWj_nUv!Q>0D*U!iRz5r^H$0#vDxs{pd z6F_=6p$A8xO^9WQ@uN93G`gt6n^Id~qsuYVW5> z@x`MhyZ}fp(Jh1;q7*vdd`_@M7*D?7xo`XuAP}%p3!wupD(120ltytVB^H7ZJGjSh zC$@)lko83sl-9W_tPL|II9SM!4W`K%8Z2)&UM9^rzWj6})gxl>&zI%m&40EBR%7}_ zH=nHnzkeLex6k|$qnOi+o!9f6b5 zEyL;Nq4YEpaHTqdFQULhG^7mx9^xua3`=-Ll|+v1f9-@-SKzc}@a0D&-+Wp$f#;uJ zGXtkhv{?PA#x>V|@E_|CdRAVn;j{KCsGRT1SA}IB49;R02+WnAVA;=G-rC)ZyYwHw<9XuZ**}c zz<|xgR|5BL=*Fiy2er6)4LdFbQvesHm$BdDEzyhbQR#pI*vY2Y@aGaJqRFNHn6lz6l|2N*fv z$i07yi;J+*tqA#p9uh}Cam8B^=Drr=E`&;=0Dz1jNxWQfN6EJXI$$meLC%p+@WK!G z0_GI9X6(#1fC$%Li4FCUr6{q+eRlaQ*%)NvArFG55(te$5^%6<;EZ-jw~>w#D+&Xk zi;Ek6{?j_tO`l!$wi(#tovY+nSlpxw_3rd&+jyf$s#O@?E&@}Rf?pShgJ^u2u}?^{ zB^Wb~-ww_xFqT>ZVU&0~u;R1+=m{HNgBLCOkW@~nd%a9?l5lR#OxwG0i&fN4{{=F9 z)?Rq3XYW-x^RksEcfRss?;wsw!GvxfNk{J_TH({E5=%a3&MLRP2QWy3v$G;VhA9FL zzTThEDDkfwKLPDhZiWT0W^h_~y4^b`g7H*5E@?fkTilS5rO0#*Q9oBSuumwJ>zR-qss^Z1IH0zE%?Z2gty696WT?v^?Fwum#k$IXARO%Qqq-mtm?Z#B zkk$>lBwl))AOSN>pzdK2kWs@*(}5Vgu$206U4s>6cVO>b=+^qY?6>9Fh3fs1& z$&McHvZ+&x019ZU>=?;KJBCscKY)wuDH;zF%qUihHk}tcsxu`euY{#gl^xRk5rV<& zP7Jg?WF>QN!hQ~WtiQ7b@zMB0WCHG)t~c^`S|*Sra;E5Me$GFYCkA0`96&c`OtC$S zd8PfO_)N!FL@thgaX`eW6_6Tz1RdQLosr<23v~o9ZqG;&mHO5m&Xa{&L7f-C-4Ah< zo1#NxSL{I&xYoM^xf~(>yCK%(qgQ ztTaw}!ZHjze?DMMeGutAM?}PIbb(kTZ_1OPQ)`7 zC{_+k)|Q^Tsul;lo|#}z(ja>#0Dq<@#An*@g5AUDAWt_%E_(7poq@P+=K)B& zOw)DxOiS~3(X9$b&$UB)58;btVC5AzoPCQXSd;NOtAUr5P%&xoV@I~W_~Gj7-!*O! z`!{5DV*?d-JOFSOMvTW|pk&n8Lfc)}X_F@wOPZn-7cXzqYMrSDuD}Su!)Qes!<uk12y&N7lElB{@_hdif-?kp z-n`tY;Mf-_ZMI-5z*8*)*dzw!1W0L@uk3uyI_T$d=afQou?PW!Wf<*(V8%)IP)|S= z(Thswdxp{^UlPh8`Zc29Wdm(7fQKp-N>K!0t}-Ji@bn1kjq?Gv1<>nKznG8DZ=|Hf z5x{a`6M;B84}+8d>^|hB3mcYm1sc<8hwhd$83rXHBPIr~cyYT(4#a84GmiE3Wn;TT zOf_uB%K>VYhPDBlH>U!dju%UpEJ>FUm3e|!sArnA27j9Vyy+*;5RSqM@kkJ8Xu(^9 zvn3wCe~+C!(P1C`>m^oHfv+{R(-b&6=s8%1Oo%tZ5f{N1x1M6+&$N}0o3fKWf-J1C z^Jz$LOt96(c(mijAm-71$E~aJl+}#ppc>ktDjlsD&o;ZL5^9F&w(YS8j*Ojl!DD9I zoyA%Dd)5Q*f?L1)(l5R+XLUzw*PoVD&a{DJFQ5^JYC-4D!;Vi27FOEI$FT0dvDZdo ziVTnQW-lHJi0&8LQ4)s6&5-1x8+XLUgboCh5}Yro$v-x5x*0yy%*RQ&y~m!k-Wh*p zMbj>{wmmNZ)G&`T?fTUcZW{3$T4Qcw9#U==j`@nEB)(0=r1{E2*Z>=Yk~Jj&K)l2_ z-76Q88FiafIdEzbSBvGs&G^~qoGf!LKrbI)%Gm|n9x{*nF@Spy)CyeWz>|4%Q7`)X zhCkQ+Q;$qO%nL+pKrQMQ0LeI-4FVCAQZV)9y<8O0#A9)=ij6vA4AgO8kkWMrW-YV< zc>5sja*y9qY!g~uQ6!ZEpG2PCXs*lV3OufOgSy#{p6}|KJ}6|8HI+O^ z_`3utPnFw$+^zgG@1Rp0mWRCXQpP~oh5@{qmw%rU$A#&c}y9IU*=;uWbi6j>3x z9yk&!CqdTzJzKPc7yabnVFG0NAsBJ}WfAg`#1FI~u7Fr}q=h)Ux9qdgl{`d%1F5cN z05_-^`mK1%Tx)FUwZnT3tp2OJR=-65v-vvfftL?Ir+EC6r*>`r(~?E=Z1CiIjiw76 z(b4z`I%7tOt*_3vU3=TH7JdZUtAj54p*LoBFZW9t6KT{a-DfDkMk+Rb#*1$9OF7(1 zw*y@&D8|XQk^<}vu>Yr4Fzfx6e|o?5;+!^3>xnE8NwJyN==U3$jLi<{c~Dd^N_f$p z%9zrsD$TZVe)Cn1|T~fE7xrIE#{lj(l18 zfFe~2ke&c?p*EEl0xj#F5-%4-P$%4h!91!SIDl4<7o!HXkS_uz(T*nxlQ-w&a!`(& z;`DLTc4!v3SfT?GHqV0VfV~j;FRaGCz5q^1$Sf?vwD$u1xbFZZUEs8}K;^&U5D37W+c%}I>FR07-Vj#7oUA!pkk2hKKiK8}S z3SWjG!*k#?OwDM3iYI^EJlp!hCM&KS|D@So#XOsTGQf+cKXU%N9zV44U)GM9f5An0 zB@=D1VJF%XMsyLz22_Zd4f7Y4+jGA-ZH>)16cdt==JtBaQv;SYxRZ{@__*Co@IeEQ z?HMkHrh`_>PJa=I22D7)-7}po8`4GD;3=!$yUI$=d55*W43z`XM4gB{*r^g`^!PO{ z=9-tAsl0$&lK)s(_<5uA!1j^}pd05eqi%)gh`6bE} z^6)87RRO;K@kvh|Di(;OA-zWJqDG zR}=~_pO)r6yXVgBS|WYJEl@F(0qF7NAOaGRo=;j4_>e-}G(gq%ko3o&Gmi93gtw>b z_TVReX?E11((nR#JhZ{rw(YgrqE0JBJ#sH*JvclBevuT8oPmRzN^JX@m)1_d?o*H3 z*PcPVv-`>bFP{IbD?WC5_5VEY@l$(tTr_U-A{%VnqmHHqinh(Uh|{J)>V2u%_U!Mp z3zlH&4*b-9^%DV#4b+>hH*9tc{7YK&Fonw+Xw|S4&7-ITM1JlcIC_I0!ry@_C%?eT zI<{C#<4Az-wbr`nr-W4JP)UsaqcVnqh=du?ydB|L`&#@vGGkGK(`a$@LXlaN+Fj*;Wjoz-%(`1z;nM zEPzE0_w&U(-qI0;Rx+a4@{5sg0C9J3SEzSL%TSGUub*eP_T~y`2OlE(u6#-ujxvGuR3*1 zUio5}1Dx`c7RGOd0*JVMgWS3?AM;#0;X``NJiyn(pi~E-p+t%Ky#yT)9K1NF+t(3709t5#HI1wbE9Uxf zQ$^9ygPO&r9+xbxLjKWCC^@rU_zzP!EH`T|RA}@^KD@d_%m}FMv^dU0ypUmA{orm} z|H4tb;oaxioW)a;m%acs(x#cHY4Br3@*y&9q=z&-Rd}8ObQver-dJXL%Y>agRK8&6 zvk^b25q53bWaZh-*c2ZxNJ_iZAK{-H3l-E(!wB|x+w$z~+ovqO>VCU(Gc$G8Um4&H zP2ik&d|~^l|1s~O#=}SE){b0c{Z0GOcG!UMi(bSL?Q`aq+P1B&wr5|LEnUowrelW+ zfTe~`hG?$pOwmp=22yPh?WAKEFE(_y$u-2`vAyBLE;>&$rp47n<)vBHb?jm59{mn0 z8jXW8kMF_vHz(Hrsw?K-GoaryA-XwCB4q1qw3= z3UIViJ`|%IqyipVKR}gA5$aYkw?Q8fR0FU}^Rr$j38O9xvCyHYyb$mQKk(@(Erf~B zSV)}x)UiV6n!_no0KWp1mkT5E@D-4aIlJ6QhhOA8HVNZpv>+~5ymjHmDmwx&)d}2p z89HX_E3%PK3fr9dpcPjD5)QiYY&kAnZo_PbQ>_EGaAAdw#S&ow4RJ2kNd#6_k^BOv zCeN6}2*Zz-1GD-e*?Ntt0zDjh?~TtLwnw4YyF`W*XiAlzv*sH{cDA;<!04)Upxt$=SnhS5I>yzn}-c`^6~XTHA5C= zOyJ8HY6)&W!)az1fI~jIAT9Sm{lTTd^({Si9QxMEszSSXK2!|IbF7QxdFi>aLa9<< zg|LEX($7tXr9vDvSf^t_MHe2HXi4KM);MsNER0aR$Um5RLqWH@WtWYx2F!TM- zW;vr4vq!m}3Yf*g6;6Sg1vLXZ?9N>s0G9|%p#!A>RRq__I|5kBMEe(DrJIqT2RILc zZOY$|1$VdR$EJmOC(g66RqfV&hpOXcnZx%W&!~b+80p?rYEql|d(@)^-fUbwXFmnFaj( z=dxo;p*-qGFA9LCW;igb1XA?-D3xYILd_|pZWdsRv8EhI{Mk4`q%RkHLRc4gVZ~uD z&R6SgfrGHr!-yX70TS96e4uH}C z^+r=~mMy=a2I?Jx5dI^us_^VmWP-K>x2A=`&U#gMgP(MxX<^PpjL3{)yVbqcWOx7T zW*dQ7G&lX}C00^dhUZB2ivyx0UxKFq6F|%5yv7@T(Nvg&Gb@gp*$8YIPCLUz?_jI2 zz@O?BhAU2>iA#nR4__9|4efSl`&Ju2f_;NuhUhYwQKFsa@D?qdc0N|J9kOHlk3H~? zPyF*%B$l~C4P=0KSW_sSbn!iP>z=~a_!FTx9gVj)m3L@V5EePLtPCA{4hB>9)OBDJ zZ9h#`eM)>B&;&|wJ7A@o>|7oY!_ooH?J0V)jG#-q7^;)gj%~`U$c**trZxw)X=_tq6Vq)6QJ*%ffb(SdZ3$?KC?8#H|3` zhJGAw2>@;!z=;$9U#?c`&4RQIJug9*uL^GF!{^S;&AH&Z=DO+|2PrV2jhkm4GI^yFJu1n1b7eD7AX;-v#$Mk}o zZs>NmZPo_bo4h0v$q0C+hF!|Dn&zNA# zFxH8i{_IGjO7k$p6(A!IN3q4@U0-<_FQjby(~nYpI2Hxtr89h^Q^Z`+@J%4Xr~itP`N zMBpn6s?0f0yor7glaW>Qx zG<*U9sMskX02g8)X2JY2+mFq2j$sc6Ev`bKgDpA~;RKB_9T4H*zb={zPooP#?$1t1 zj|k4eo$zE(;7{O6>|)G7ek^0L0?rVdQhVGQPi(WE+QpE3dGal@QH6cmJ?3l(@u1QtDTb9JsV8-#?+<-j^xhj{>^2LctCB~G^e$z&6;sH zwgPx@jC)H5R;yt^tqt2!cJk0m9`l5+?Og0kmJgkAK0%kIMdEykB0EwyP||IOgw9o0 zEgk)K@p-jYU4xgcs97+kODFB|_IlCR2y;mPQ0Iy_jE-@$FpzfiK#P6%YwM8Sfc?pT zTw&ABof;(FpcWutvJ!(DK$2(zq6E`ncaT^U^@P+Bfkyz|gqLU;<~*os;7uTops%!% z22bDKwr;(R%x%C69-zyQLjN$-9P<2;=r=XfY(1sjd2h`~yQtOS7oTG08dd{$Jh0*9 zdoHXRQ(9HCykguG>plLezs>npC-|aMR$|}T<0pFT*okhNHnjx80DvZRE&?H?K6Xm= zF}KRC{wa3=Cenmk(kkpjrCJi>Kk`F(q+`5vyStSPlh##;jbJK@TkO!$Hp{L$$BO$K z&^fT189O^@JU`?Ea;8ClrR8a+fRsVZtDB^kJJ2WkZqRrb`9n@(9Qk>AtdH>{3l+BK z2owMSHb1)zK!?tokLgpIg#hG3l`1X=yK(`xDxUxk{xB(>Dh)`^Okc+hA)aOW*?xd&sT#nq`uyvy?!ZagzV6lAKl0_38Q@h<9QuQr z%v@)xfe8!#6aE#?t&%zs>8>z5U5_s|13ou!DZmHEb^x3`x9a`H@Od!bU zX1~JC%NsEpvK%4Y>FB9pcUVk(|9O3?+LiUWIEx&rAmo?Ky9j5)sNPH(fehS#jA za27`LOF_mRx0IyE_vDcUKnf7evBOQLqeKrkz)QEv>1jtm_I$+rkQR2_GRYHhsq-cM zMRUsSg1P08EC)4Hpb1hXb-zbXcG{`a*m(^=$9-oxrH3%wH&j)U= z09CdFE}uF5k$dplwfUrd`^zt(JbCv1zqrw6FF||5i$I{O*#|C#x8Trwm z8Ku)Gt%k7S5-{D0Lms#_$mVermtg{F_oE%(7vRq{;0L{KFQ)swx@L_{ENK-d?ntJ^ z5-|C~D;kTumyWd;ANl##b1%E~M@S@douLN!gfiC|YT%pqJay{UOU71UQ|KUV;Z>fu^^##L=R3*Zm`zDaR4QBn7$5meu|EsX9q>;s}YZq zDA{;=Ax}(O>C@zjFq)(RElfm_zrZ@u$`la@ogVmWQ?S1QH;Jq}(WT|XOpj6%D};F< zpwf>U<BvJ|KH&Y4$@#J${JXxLT9EHqvcDsBG9GxU)hBbNEcv{+)5Yx)mIUh zeLJ~9M~POq1DZ?6um}Fc9o7R!{kcr{EsHAc{Mi-I@47Cv123{JEQ%1|VHQCXkNCl% zk{lH4!eAK()AFE?Er4#e0GmMMbCntRkS|vLVl^D*ftC<`R|JyeE@f{m&+~o20flt26CeNLQ7Z3Tfa-(ER z>C+`tZhoZm%_O*q}U*-Qj(RV>L%?R9809yM0LS*5C?9m8Z^%ryhzIjD-c#Z zxFPMHK6=Xbz4WY2s^I2E0CWJZOS@3(U>u};#!~CdDz}%PdV1yjtNz2CV4S($paxK* znd^;e;Euajc6{iD^SV2lj$A!v!SaIM6T7fl3cI49X{yoTb1)wx;_Up}cePo~$O6rH zkO07b$eW0eW_Lh@mw?DStosr8f;)cdGpcx`OnOAg>UHrLHjHoN$#~3HHqdDd7B%#A zHQ3IB`B)T!W6|?aCIve9`U@frY*7XQC;KDv!|+H$Jdr(Mk^?m8SZ+7;zs!ngk8nvk->YLr9PQ%o}b<$8q)omYire#}3RN=9IQ(oVV84gk#-ttPThG zuDo)Rjl{+|(q%HT^6zCMW0f`d)1ByVSx8n8!jvD@1wg<4RHyyqTd&xfr|Rsy;`Yex+3uahERudq9N0^rn!X2&_q-LO-WJ{sY)X03PZl z*z5R7$#E&&IC%IQ-AE|iw#xZ_@7z(g_`ETC(MI5lrV7Z)V7`MGgGb2j6x4_>O0nPq<)3?Lhk}>uWiI7?2v!-~u{mtH{^(wBrO? z%9maRx5pc zs3KsN6i2A$Kp<`eA`GAnxtVjGSbE0NiO2XnCct-LAdO(#)QVXQ(C0QZ@Bqs$)JKtB zzG4cNC;QoJv0hXue0Z!JWJ-07Tu3KfZkf%1~^#eB|wR z(TWQpv12a{gfZW*15KsDbnqZ#ckuMK!IJO+F+ASv&Y%erFa61vFQVjSAwSTQpK60V z9JDDlr+9^Md0r7P-QhY__E}z%`qY8xNOLQ6Xxt%u6qykMqcr+p^{^zIotqubCfbqq+w^Z1O5NZ!Xo znM2t^8k9hbptGHb6>e>Kc{Kw7n;~`f0dzSH4AhdesAAwI>O7r-Uma8z@QgNsQ64wN zLBUi{Y}o+ZKFrx2gk&qQrKF1&AM2U(eS2|tV!BxyPLgQD#^^23=hjoN+}wp1L6%*7 z$wV7Fg$GG8c@-Ka3aT5RBR}}Fa$xt*_f$ntoxu&>PabZypWM00o_TbSO`kj6ZvFFj z+l+;?@r8l78mx7IOeD=%Q8a@@%RL&XqeX4Qj}^%@qe**A*Zo8XKYtN<82zF@G97rN zncyouuXuwNK+L7nYajiol{CF-wI$q-2=$8`@S?Pvg&o>PEqkYJ-LM1uHthM@N58u2 zUJuRu{<0dNe3Q9;jT)G7ON83e1CAi||hA$H_O5f1f zZ!f*nU?VYCwY(DH?6iV0wDZ_`Lwa%tJB@UAx;-Ib=O!I)0!&C+!SrJsm%d<^6or&y zFHtOllE}jk9ALsN6fd~A$`0;tx0kW!@S&qQHh)gB6=9byzC6f-(IiQSbO@-t)JJKd z8_b=5>gA$xu-}I;x|6bz1^Yey@JBr&x7)nt;#%l_4J)6raU>7-aTu^B=v#$<*;ufG zy)w9zx4Ht7>p(tM31dL5fE%l0?l1D80Z;&QH#WKH1YI`w4?t2pu7?L|61=$y4wolm z!!evX0o^VZYEZS%3aOVfD`w3Z36R9mI9 zbkzEAx&oyfg0BNC^}TsmRMBG%*vDZC7gh+M(9i`;-kH+DC)$UbF-z(G^rJh~3EAP& zZgwh2Uy;Vc-0glt(~q4@{LpDDYKm>*q+&aIqSLnRXv4DDJRE_}lX;m2Sp!fae}O6Z zDU5-hEu~36N`YuyimQ0^BOj-wgd5$Sw-AOh6k<8Cko7ay05I?)qQKWWG4GnoeOsWnZD_*kwKk}MFjGNugYoH46-FBltZe1o z2Gs&Uw*fcvHF{KuUA%k}PI=&d#^8xOC(^A~L@cbHzof`e0o;Z%3;Yl7YqooDUoR?ttxF1r08+iv>HFK_VB%n-062ZJv+VP1kg()Fm}8U zmXbKxiJU%$$sIc=!AWU(T-w>$M2lXPj|u%#XH-}PwpiTsYK!gN+oqWsC(mSU3UAMq8}^XICHkYDg(Hk1#<u`f~eg^Z*HH@ukg&L1yXI)`|HnJ#ASQn^Gw{%lV#?n^sUXUw&sB!+PJ|wsGt1kcF#SE z0ZBKfu+&B_e~)c@Wv6XlyY-*{;`X)Qh~XLYSJwb)J9GUeHSp=r{O#tw&)q$H?EDL7 zfX=nLD$j~a z2p9yUAh9Zn1282{^<(A7fs{CKmzrSi*iyTlm%`~{E&-Ec?M+Vx3^t1p(0%Y>MVx9ACrRPF3f}n#dK~kV8+7LI=>ba3V z6^C`_fb7px8VJylkCy=^)1#kmmdoR4njPrYKKhX599w5&%BgN*xL<0!!_!TY1UmZR=3)pU>B(aqw)Xj>R)4I;=1ecawwPsDjDQ0_`IZ5tXxXRn z$A3z=(m@XcSLQh>D@m1JFd2^*{dBvN>9@9Gj_=WKJBgjvPM&VJCd@kEG_XQ0pa4LY z;V9!GNXR7^$l{V-E{x#H!ZsjwdmE>x8CI;}6k|+_q8g$Xpv=5?L-o)H6-FN7RaTcs z|2uvDNX*%-M6pmV<=5+)Wkkl5HG&`|eGKti7x-`6c-&t2`5xQ5{gh3ZI>9c#{t8=g z;X>?%jM*)CIq;>c7n_PiFyy5QgBc4>APmnoq{YO%z8J^TN2bWk-7;YfevXeGre}d5 z#T!D;a9jzWl#{es7@*v?c8%?O>IXKnvMnv&fezF0iYK09BQCnhe)_L>)%W#Pf9%h` z^zi*2n)&^8Yal#@Uza>X7i-}D&(8bs%nQ%|`t$`0icdd%m-V%sLSN$4Aa)gYD{gl< zXzR8%S~-q}Uvced=*h54e^3S!bXfV`v4%bd=^+sY{L(+cgJb1E>6t^j=)dRXL@ z`6YSGugaLD3kJj*x`SU#M-_n|k4H(<>AZNTr+_ua){Mh1scxY9 zfoh&I%*eYth8Ad+^!W0esXkrY(-SUK;Ciu8# z_$7_|yUBRz^wF8}^R$^RF1%10PMoyoessHy@85|{gnX8Xo`F+HKR)u}o2owOVwXD(84ohH)CWIWKZ4~v#20GP+S968ux8`d4OL;FrzRk_*xb1Q7x z^fKsyu}1(C00@N-0J)R0ct*jK`AAQn*@Rm-6Us1*76e`vNUpSZVX1L*W3L@P)U5fu z<&auAH<>_NjC|yBGaN{6G_$!nMBsrM_Ldc6ZPK(d>~y9sFW@;-H70QpPST)*!Y^^duIWc1ZUTIaC!)xYos3tCM_>X2eu>0IU}C;$;s&6xSD!lG zW}6`ezP9Zcjzz=%#8V1w<{X^BJFY~BQ>y1v(HbxEWYR}->J8TE{;Xuc- z3Y#&1wk^7NvCW(}*9tfvml8fz-MV60Zh9U)EoCy6H<~dHNm$3cUKhrCBS8$0CcK6L ztzI68PikIz_HfAup58WMC@Ema%Y_S4o_+9#mbLFGn^cKud-Nw64e;YJ?Iq*qTJ=RY z+aq_~(_VkF@2~#+8&7|S95UCxuLfAXnd`T#fuH>C+`pf`Wa;N-E?sJ;pS#C;P9H)) zfpn$I2cL)!dk%Hj3GC^x;<~XmdTfbKQy`EDFp@m5wbPOIXoA!_wBrysoW|pOJnw8C z-`TLE23|B02{`%(KB2>VCk3JKHN=BTLa><@*OPV~Xchq&qw1YF_PlO)y=~oi$c|tm z?1G$rn>?l1rp+j`@#C>O80N*|%pULtH-ZM4@+LDnX~+%>J!t3$7FM8~Gy^yTjFLEd z83dY07s}-IgfImM6CkS@6a-sV1p+&;Qts%XR@<}fr0v*r+>RY;0ifq%z-*$;zhDtI zCqKt($Bo8nG?W9nW9Hq#P7J^yq#x@kr0)qkjqHiPr^{b|E+Ky8LsPVA;VQ6V&{H?P zctwB>l_DR}L>`fEbR(Ywkmz4}>>+E~{GiRK#I9o@?@|52y)6o=#@nb%Z?QG2*4X;h z>%R22cklj;63qPkyK5jm>3=taOhmJ7YwoPtdhb7c>!Nqv`p)XAQaka?-8RtCgbvMt z9wLi(5rX25{jJskDe3C#$J>Z%Or{?$2}bJJIpB7wHFRtFvqMI%?9dT}g<=87NfRG$ zu*>Q6Vh}o+$AW*tn}qSE)q&TiBZYJm-hrQ{Cm{|$&mjRe)_2(c-6w3v7MwDRJ%F`$=oUeBL}94mxW57@KwOY^W0E*_cV=tpK~Y zF;9A4$fp2Tb>z~r>X7Lnp9ugf9B~4j@|OT-d}at1MJRVt2F7DRFvUY2pq)BtxZGbmg=T=u%ds^)PmP#&t69)Ty)yPUwtc z?VXa~5G6s6Lx0{We`m%>0F$6%@O0>gHyH{L$)6rEFE9zfoDBh$3Ri_4KhkJ>b{@Bb zdyiRjeKYX6U-N=%u|jRsH~`(~63lnTECXyvlZzP#oR;bXPD}@Ulnzs89&vecN&3o= zq+$dRTuA`n;Bn*q0NG9~plEEsl(b`Qb{vxI@guFc+pHCvo%3w5^2$n^JZq{=!(Iv# zrcS~(jia%rFTj@RV&(*hbR~dK{;Gs%A~;dWF!Q(&_@x&at>B|)0Z>l- zL=xkGHPd2z(TGvtNB>YKN!^5SPml?uXvvqnuw~|!=byH^r~l1njcA6903PHMNcn2X z#**Pt%Wkp8u0p%#tKWEG;WZ!q3HEvjm<_kz-#|piTZJs+~y^0lK*%$!2_Qpv#ng?o$ILDW?X#ILHB$mxP zmIEcdqCbI-DaVcn2R+ilJr4Pa5dAiSCgaf0J3YfaU3b&p!9LQFly*;xe8p2~1(idv zJ4%6$ZpLA!rbLW7=*3`IV|}X~1rQ(Ee-hI0DM*dz;Gh{#jL5+ZgY*|sALjJ3et9ru2WF9UU@(kkQ$wdD?`F*VZNtHuUC`SS z*b0hEtpX=Lj2bu6CQO@X;{mj_V@6qNc{%2>a`SNHn^=nhC9fCyc)63hW!WUXdL1GX zE|ihZNK32gL>4-5vtHaHzs;so46hID%mQ&=&hl6DLXSu;nbw`us^}0|1-AqelUKar!5geX_ z2+6^Di8$63&Ex@x`1qP22*)e+QlSr}XQr3Ni{5fZzsQFHyxczp+H{8-FP1%Tj7+8?A|YbecwR#$WMRtt50N(@loCWZhrg;{cd<= zxP%(G|GzE!Sk0)iuP(jrokfi=KWgoJU(u&sdIbr5@d>+mZ>yDKQ*HrlvakJ!_j~=q*>@ zAJs4ElKNn#!c9L%D)*x|-13UgBhp4X(!_LSl?URuNiU|Q^qmns{7&*fB3wz`%ONk% zC&SzsEqc*KPx67JyL-zkw(YU++VtXMSnY@UW_nQv4jS&mP&#?BRh)Z`J$l#OoyYb! zeCn^hz3%qNIb;5AY9M)3zZ-TLF0lsg{q(#qj-55_Zx&yDoi)7lh_&w9h|Ukm7rk12 z2^NBH7k1y;R@Y&LBMR-UH%x=t0g|sU1&;>d>WpFG4<^C>g9=}Q3QUy2W{UdF^667F$8mBfo6 z8eeMS74xFHA;zWhCb}3--qK4uM~^G!seCB?;1}%)dC0rUN*YfmI$4G+yqLDHd%<=; z`9qslb{Z@8Sm!9UqB4EN!&|6i;zFxjaILMp`#yW^mEB+Zn}6GpnZdw%{vBVTb^VUH zX4u(+Kl#EJ>t5ad;LexUTGjbCSn=4IP$hJup|d*xzR==nD=NsgbEg$s4^BK-{lo$2 zB5?!{w-yAzxJ1ZLLB9n^+67w1YBJ|_Cod@}F z8eHHP>~tej@^|1vvq2aKr9`jvQ*r(C7~zZ`Zqf}><$_xqdMm%2EkT-49@2=O{%o4? zCpck%Omk)X;YVF~AKZ93=>^4?6#aCgM!kAHp7f^V!~F6_T|~aBBi0@Ln7-SU7fIj2 zJtQph;S0iVfhi_(qK1jMdH>|V0t9}5`J!Qq%ZA`nYVJ{92f^uUVw#MSov#e_2 zHTKdIPuunvw>)^`N51$)a?M=7`x@ZW$y~pu8aS}wktNT6@2|f$=aS`@%;Fs17k*-0 z$M$K5ES`v<%15VUALGFJ_PTcK#Sz(8y={h7VU(Z15&@c>RvlSggdK{RhKY+H;2qJs zHht)J>B}jir0a1!%)u?hAwZBRK_c*t9iJ4sLWg#MaoXW=1Z*N_-ketip1=f2#4u0O z-3%RCF1lm6X!m@i^5XoN506XyN&H03`0h6(uF_$E0%5=;VUjP8Lk#yi479475GTf! z$++$>HZd&t2^AGqy*E`8fOmQI;H!%ktESvM9~3}X3e1OxUHu5RO=vpecK zaYS~WU4HE>jJj6>e7Wr*xdB9IB;Wu~1&~VwFcOA4gvkxNgRI9FyCe?z1|ETT1ndNu z<HHXuD~*@R459>_Dd8zj%1nVj zgBX~q4}oU{T4l(?W8En|hT}>B7&%b#4A-!_l&=>Ggvt!OVB%kODKGx;WxMS3EAm3Bkfb?val_M3*ok#Nu^CnE+CVxV!8w-?;_A6Gl4%@uy$> z!ufB%dGQ2nh)v12yYUD<@$i|Ai$KJVK%FngdI-KPeL1%Lnwi*;yV}7w>A()6dTU)l*I!7exL5db0$Om$`gB-0Nx3H=%31b|A?8WP9BOX-BP9V_?=9@30?N_VI8 z0Ds1j1kV!0^2w7t=$T5#fzsUs+!&V}1b|8}Elv_Q=0^+>FY=(97c)V>m=?W4`hlmH zEyYKYKBFpbpiM8Qf+7zQ4&j;N=VAT=QKU%hCcx4!lrepdB0MATa_?ep8nj{M!`8Uv z5t~`tsSShpBIUDSy;0H~#59_M5o4`t$vd%9?=^euJ3o5miueBAXP3SEFII*`GRE(z z2I5ovJ+aTQjWw|8@qf8`<4?cv4;Q@sor@>WnPK$=-;+=~K%dJ_9l=+975#nRksdpE zdcZEYY`V=_Fy4EWdKMp9cx(a(*x8xn=V9tx!R??2hGI-Q2NS0WpYKT+7UD#3O28|jaVabT&zL{OV;-1qr%BS3G|L1%kHcRedO;u_DH5OyJiMF;AP@2O zy6|$ti++rY^j`;R;Ncf(crkCd9Sz;C_|c2cE6^o*rANGDn26k4Ug_bHCPoXiA&>5cR<9?B zILIJI=!blqyx}jJXc9jOsBV(R;{;khoxn@+BY(wVB=R9qG*j`?0oREl4NP6p9pk`M zS_}-}Oy)^`=}%g}U8?o`CVJKk}NisBqI~557`;>nIvw?SXCsD-S>9g_+tp3O$d+BFC zu+r9zHnE1~Mi>SW_yY7t3^!&k6pWs3BhJ0fw!FB}R(|g%>o0xZfBw76-u+h@NjJS> ze~lB=)1WcGRIS=0KTS?7_hQafnbCc7j0GC`Qz z8J=qH!$}rhRx@FwEqm)ZR#JgU{~U>9CuOIi&3hDV=xFld4{tFFb_bl4#7n?%x(IG` zr+6Vudob|8v*aNgn<;y55Vj|h5-PXI~4E96hehU_HyXWqzdczN8<0|_c{ z$MhuW(!=A51{|Dq@I%^3`9s;AF8p$o6PNQ1`Gnz2Xu&-kT$A(|?j*x3C{~CY%k2bd zzs{FWRcSB>NGHUSuZPh)qyyimYT!9?oGr3v%X-`Pu_#-GMX6H}34P{=9NqcJ;Z~z@^$H z-v~AW7=i{n8B=gOZTiF%U_?JMN5_^FOX6?~Kxk*Um>_NpC(x2x9B_go2@5odJEQ}C z0xBCw}`k}s7M(8n|whxvn%Na2i=;yo0uNXuNrJb^BPAEU&}3kTYm z9|nXxiY^k<#Qi!ydPf?@#g&$)5P_Zwav(-lqK;NPJ&d_M)0Gam>ERqF;F9UB&#$sW z*o=Q#Webi%!oV8K5Cta@<8hyTalUwHkWWo9p=SLz?Y zKCHF;0aDB)p&Hor^p9#@yzld$nYM7jUoN@sZAHC@Ua{64tI!2;FeB$yqT_1YLQr$R z8SWaeZFi>~YRILLM% zG%!x5Q@C1ANC#jR!7p8^O{C38o20|^(}6Vwydu#Hg^|eLX}vtKizz&jZ!b6bkSOLM z(9?%yOM5wy%yF0WA>3_rfnR*VC^RiC5s8L$x>Rq`AEu;Qn4SPEfiCf)+x-%fG#UgB zxxBvVmEz+B0h-~>BiP#-8?de8z1Dx|d7Cy8=f`oAdaA6LA4u?gE-V=Vx?=X_mOpB~ zJ$d(oots}+|IgQc{O`ZG^osYM9+Ggz@dv4a;ZOAsl4vH8R1N&#uNQo5z!dV3q%TGRG($Qt9Drb|jNp;fM=VQ<*2_kKOXZ!R zxgP zjju*6W^*wN9}`kQdvP_)0G3RbTKTNYt-o}NJ$mQ&_Z`}O?2G^T?(Lanz^Q8ggWKZM z{evf*NibCd_x`slZ?c|-&tLh$4=*UoZMT+Je`eNEuN6m}Vx~?csRiJRjl^492kezs z+pQ~i1dg9sY~!YmamiPzU&0uBA8zl3NQht+{M3DYs8&M6Bq)M?^oW2P!8N67NSCyo%Ih%3j42}w ztI&G7y0E3=lXh(5!#1V7)he-@8~0r!(CTDp=A9BRmiOfrS6kKm>#V7x$nN{f*Ed^M z)qnrXe|;vi;Z3S)|0uT5Z2l-|XA(`Tfk(djfvcJhym;HCxBls}u@gpE=k~{}ziA&< zA7S~h`Vl&oIurUH2Hkk5M-4pv?awUTx9-QEJOBFYZ<=%A zdDgT48S6cUaSupuT#2NF zRm;xkk2=l=m0RFJe}+fNGy*drfc~U(Q{YEjKs*O>#tnDig`6ooh`F$XFZ@WQObhtn z3Z?^$^9WSpDG-gk88^uT)0PK*SP$goZjTf4%D71w{P_8;E0!f;0^eX)8Auevq8YuA zw)m1}D8J}pNW7wC8{H|sPMsi%Kfd>~{`R;#s`zOAd*~DD6`^W!DYgvE%%w%$4 zw*KMUYc@RckDr;fc+tl%di#wfS_%l^ab;AKG-={P{K3apnG7aRK@a_cRKI{w*ZI08=;Rh9!tGC#)0X8ONIbw8jK4B z(WWafodZK~iy*u(NE`S#;1DnZojgb%+=89pj$!l*;U3@lkw*k}nWAABdGSgwultBk z3>Lx#2S7|$DuLjP#GYqHQ8cH1!{4NQNnRqUPYxTFObnFiK#ID`A65f*|IH;I$|>mj)aCDe-@KZtTQvt4_#taAJeTYTwKs~Q7kAWmuEChI=Z9UnVQfQ+038(Ii@F+2dX{Mfl8m?AvU zuX-HMOt33kqth{%> zjjuJ!FTmVf)I;*pr5&m!!*NNR0aG+~ft5~LX4}?nwa35nZ$BG7Y3V2+Cu5nMcnv)LquXkBJ$=`II`@)`KDzjt71agZ`>hWEY&}irg#3(02jpMG z4oX7sZf?Qp7O!^M$)+-!x?rJB%PlM`gUSL5U`^adgap8tR#YR95jnb_TLNGTLltb>+QRAFUPFR_8*$@bg>kJhhW_3RxBul~?iZur=3nfbZtkK;{d4=wIZ zma9y5URMJ@_?t^_&dF~1`0`tBy>i@?8XG+Nf(K-vIa zDPV#hKZAM2`M9(rPbrC-9`p+FVfd6XSY%fye-tm}83GwE?Mm@w35JFxWI^(c$CxMn zXRxHo5(CMT_Zx$1DvzY`>-BuxpA^}-P#@qrdH9I!TKBZI>|bl+%bKlb1ZK0~#mX}A zcCdwsubKfoxGcmg8HFX}lPEqbpZw06`^7Nx^QNwWH)x%2>O7yd znS1Q(9~pmW^U6;wx@N^k=3l316Il0;`C3Pj31We{3ntSVdY}>9r z%PyT{bFoLn#OYHluc%Ne2*=V0Dru&ez%8``t37~o0&0M_geJtJn^s=KCCMaHPRqEG zcw>afOOXSU^f-x~1kNL!RQBP#0-Mz8+~5J?6f}mIL-^A#(niXdCf)8Ai|8B><8?e@ zNVP$KP#yTY40L#Tk*7<g z#ZzqE6Hhlh`_o77oId}WZ@mAuI}fL)lCi&eYaq6)H*XFzIeT3VeETmK-CR`I|M6wF z-g@Q48JIqHdV>v~+yHf7Coqx{6gukgSn%%cG236)WxMtQ@CwG+?4{@1q}eky141WA z@)SwMi~tk3ptlQV0KgGgT)JdB5$w}bgdP7W36#zhT@qIyn)Mq;ZzypP2Y}$e)Hf7En?0i;<6>tEX0Kf!8UV?Ff zqJx5iOhCve@(DyeK>~+ElbgtpxHz~vjnE|cyU(zu82F{Y8@wX2hA`(#*2ou&Of#|% z=5Tim9txB(?cpXTMDqm_W2MZY@l*b1vWZrJ+h->Z9<+U%)>`Afm#w;>-o{qpWMmGU z5tNw@OrNJskcI~b&j7yp6%#RdcD{A=mfQ0WJyyT*7i+#f^@0`Oc>mvKq}(&r`J3JE z3{C3Ip5;vb(re)RpIr9N-oE;eUHJAJSIk~|u4Q-ZGdr=?2D?sy%saC{P@-OPSPVMz z0FFurR-fpzUHb>EwRfbAn>F8NE?Q)jwY2~-05^8MA_!}lt)oJcv~;_2rJ9g~5!^&7 zg5wa$G`b0eu6a4iI&#`Bv@R5FaJ?-@tJ`-=;`jX!+Tz{eH)*(zLVRmwzw5K+*~Wj$JUMbiqIkmfGgGI*px$6 z7c-GpR%4|T&Nst83)|MdVo%+B-^#rFn%h5h=Zg>g@(g4`-^?`-+t`~qkD0vviW=a| zhixl=_|cIQYu|tI&F`EuZgP!T{VO(r3HR31hCa-}HvkE6B(*;Pz4-YHYz4latnUW^ z4_JLih1E=)Xa9eDR~j2vb%oFDi#_8R?@OH6i5(m}D`9C8Af%-bsv=t2MgoDT5PynP zR3v_+RaNyzD^Url6{Tub(MnY*h@i5R9}oy6VM{_yAc^BRj*~dvxADw)Jp0z~+&j;n zkVQ@vA;mdYeskA%-@V^Fe{=bpQK&3dX`+6XLT%;k;pi^TJKZ=?0ai1#8VqUir4Tp$AJmP2T2 ziiUc-XsG)D%uG&GeOZe9@RMtW2QgMDDDYXGfcYqu0wi4Zw1SzM9i>!KyOtbv>uIoW zl-_^ol@p`=<1cQw=h454#e#zOn*J!<{nzvyWbg$9UVrw{jYCKGJl1;S`iF11|GQql zA7AhIXOs){z=K%~t?<$Y|M2WlOG$I!BGxzZGrW?vkPO2CPya}UhNnQdCCjLxwS$(o zucorfO8o|&*_)+crT#=;1*v-OdAvZ1id59Nm|%>rsE{z)81+V6RBos_=KC@Fm?z-N z6XV=P)rs?ZT3v1^B`}-0aQXh`nyG}LeqaQY4-F;Vn<Y zm&gmVFn&SC$_s6wz$yimQN*iN;Jot8O|GgoayM+C>FG4>+x6y5_o2ftHf_A???3+4 zKd^pW!eT(+{JV28%t+=y|Ju3zN8!N9$JcM$diR>Gw^OMz4(o?Qlnb4L1RMtuY69j3 z6-+$LrTPP;fIGs3f@CTSDL7C4V`d7c{8U=Kf|jgYO|?zUR8~=ez2fYOfR!|?FfY25 z3<52V6~h(UaAY($7>qBBHU{AuB&dd_`oHkQXft0^+_6!rbS!hf3r6XM=NdH&j9F4G zyvU5lW+^Z_LZhd;XsZ7hnP&&6sx*m}W_V%d(CP+-u~H-8JXkI8^)+GRJK!Han+v=B zuE5K)jTDL7sPnzO^x5vc@A|4*UU=g9_g-D#sHE97f`D=RUn9enVJ;K__W5vR&p#i} zCMON$ zVV+F&V>s6u{TZ!|e9@VzUp;70wj!Wh$cfO8VlJemMl0w5LLAGP$b0x@Mk|&oFFUO#}Z>NvkwX4WkwTfnEP4vZwpHS!S54ug{d2RhY559cY!%uf#Vq{Xh2oMnB zT?Aj^LZ)!=jpy2r?0NYIxzyynD>vS_sbkBnR0HK>Hh7X!BS$DZJEj&>s5kulrXB37 zC1D*aoi2Dz-7t{Um{{YfJOv{})3X+uNtePjtp?I?BYZkW68_SeUyoJ3Y zb9A8kp1l_}>E-XZhPVZ-3<9ckFml2=^;r(_+jT_wHhxo6PAV2<(Ll zqJQ5j_s&fB-@RgW+qc%;d3#+gys%iJgOmUPXMzKiO+`V9d~0aQQt5(`pC@8eD`8Vh z!tCoHo6b@+k*9FnM8SleqB#%c>^^dpFQKxUMo7c;ctKZ7Zf_YmT_sBQsa9jLzX=XZ zjBw-wMn{@61r>;@(8Q{Sgqll*3&<7?=gO4wn&+dXP~At4GU*J|260NnA`}S*C_Fhv zGn2y<1JP!q0di27Jhn8Ixboz7zzrwJ*39Y|9K7tN<2{rPjbgbmjD5i(d6t5?dtd@%=O%%)8DM65m?Ow8AI~sdwIl0PkczxvYRe+HFR08SP z>2hOt8!Mc=+wrIl^@n;~*Tg#~1kX+Ias*mASvG^aqYc`9*QU}uZVW48~msUljwz9LqG#8p*+Y?*{rJ7B=W z!r1MQZk-jaWUp9Gv4oj=I*-zq`#@gcI<-3_YBAwK7HWzkP`6Zoyfq?a1OgGnBWT048IXJs3ojU zyl`@o)d>Q|izkll4klw8bf`E$Xcok*FSWo?Oa`k!@^D6xO<`>KHOOFHbS9aCYsDzy z7-eAI#YaAyAagcG=1hX@lp+UjjbqJ`!-C$z$h`Nw_I$$5>&6WojVoJ}Yr=eFgc4)e4I?l} zxoC)TkR-LDK}*8SQJ^BcOG5%d6S9u^c^mYs^upXus|;{92w4+#4pwPUS0E2=rgR}r zsTk#`%kiOUTy?;CWR>DT#VU)R1s0NV5$p*{cBE~vCa_qM2SKv&1$+0>+YfML!HNm&J2B8 zUfr^9<;`1n-}UG(0ty`Yxb6|aohLyMxDbK2|GcwlpljdO`0Ui}6?NsCTGy{@U*6G1 z9*><&i4dix`YADS7H)yZDF=x%n}g>wMT}rBj+q!)AAy(!Vh%bkkgdvV@>1l>>{(!C zzA0JC)PWO)4phwTxCZ?o=3SV<&zc;$7^FBCxD(|02ZECR7rrL7G)OkMZ&TXJ$y?4sSKt{Y%O2T>{D0OW|OYPJP)$-Jf-KPY+EVu$NYT z)V%u6{ojA;nf|%)NJ0=OAb>kef*^2t1YZCB&zgpN4{puGCT_2)ui3P8)eY?|3HvMj zcx;bRIygj$@pFhrDH9E<$9^_NV;%*2f%ptE6l;s>cTtCzly9(ncN$CAn(yW#Z*J^rZUG5qD&QiI~OiR1U{&r6Ak#MzTV8 zn@l?>Fg``+j`z^nV<)=D2SyKA-Q^!OtlYf+!Jq%3pT{Rb5V#Zq>K46JrIZT-Uqyf= z;h|HVcSI)7ZE`xzH&!oQ+P18{&0F8pKwhtlEV%?_A^}QIk5DQw3Re;Q@@f_vZ>Ass z=b$cN%LNb`K9#<>Ky+HBMJeZX=KM>eTuYsWnEPNpS08*@;am_X2TjV4Y^+%T00bdP zL_t&_ePmg0%l#@dG{mZ|h-CS9K}o?_QD%YbMT^Tr))M@vcq>7&^~n370sfrGp(g%uC|(`4QuL}n^#mf)KjU?qx7tnbeyuWASFW+P)$ry8f2VJL@AHu%ehQS zFVx`07KTnj3CO(4t3Z}avV5l&NRtUvktYwvP%S8O)r8B%M*BRrb=Rr|#M~B2U=u7A z*u=}rN%j;|dHrqT*=WCQLTe5kKGZhnrlY5h2q)_y6ElM;vM*o1mb5j#AN z-_FQb+O%umwX;$#+@Xvmo4O(rUnXq3HTB6UY4@lf1(l8~R0AY;oanMW{*bD!H?`@2 zsDi?gYSskL%i7Kl9-IGv=INq#i;20Gcj3u{n=%U4u*6-mF>Bwu>&olAPt&Ha{SX#r zQd#qFQ;@t^^nt$X4~r%+vuzQZQ4y)Q(COJx#!E-%W?fosX0cKw&N+0UiEx|Anvzp* z)EVa;Sa9n^Qt|l|rB+v=4Uc;hCc0So7zZ~N6cnwpw-L3H<#zui{PBx~%7cW?{Z+g6 ztSY<_zyHmZZ^!FxYg0E*z1DQ#kRY&SWf6Aila}&^*E{EjsV;9`d+|X=vW?K1(@T*sLqII&%{>gJf~c8n$Pl#g=QTPA|EXr5Yu+ZSR|C z#!ERIL7y#u%y`l4QFHB43BUE-e}VatcNZ)^R-biza{Zh=r-CQFV`*enR5-F*VaAe+ z*E=1a-`lSBF)Ytj%Pe@hmy6BGlskQ{f@(kf4N^BU_4@9ekzuLfZX(d3yJ7iOtC-5w zSLc;m#A@z7EWELLPrrUnHC4vwKj6-*U8@%*#)`l9KV z=0e= 0; i--) { - var message = JSON.parse(msgs.getAsJson(i)) - - insertTx(message, blockNumber) - } - - var chainChanged = ethx.watch("chain") - chainChanged.changed(function() { - for(var i = 0; i < txModel.count; i++) { - var entry = txModel.get(i); - entry.confirmations++; - } - }); - } - - function onDestroy() { - filter.uninstall() - } - - ColumnLayout { - spacing: 10 - y: 40 - anchors.fill: parent - - Text { - id: balance - text: "Balance: " + eth.fromNumber(eth.storageAt(address, eth.key().address)) + " JΞF" - font.pixelSize: 24 - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top - topMargin: 20 - } - } - - Rectangle { - id: newTxPane - color: "#ececec" - border.color: "#cccccc" - border.width: 1 - anchors { - top: balance.bottom - topMargin: 10 - left: parent.left - leftMargin: 5 - right: parent.right - rightMargin: 5 - } - height: 100 - - RowLayout { - id: amountFields - spacing: 10 - anchors { - top: parent.top - topMargin: 20 - left: parent.left - leftMargin: 20 - } - - Text { - text: "JΞF " - } - - // There's something off with the row layout where textfields won't listen to the width setting - Rectangle { - width: 50 - height: 20 - TextField { - id: txValue - width: parent.width - placeholderText: "0.00" - } - } - } - - RowLayout { - id: toFields - spacing: 10 - anchors { - top: amountFields.bottom - topMargin: 5 - left: parent.left - leftMargin: 20 - } - - Text { - text: "To" - } - - Rectangle { - width: 200 - height: 20 - TextField { - id: txTo - width: parent.width - placeholderText: "Address or name" - } - } - - Button { - text: "Send" - onClicked: { - var lookup = eth.lookupAddress(address) - if(lookup.length == 0) - lookup = address - - eth.transact({from: eth.key().privateKey, to:lookup, gas: "9000", gasPrice: "10000000000000", data: ["0x"+txTo.text, txValue.text]}) - } - } - } - } - - Rectangle { - anchors { - left: parent.left - right: parent.right - top: newTxPane.bottom - topMargin: 10 - bottom: parent.bottom - } - TableView { - id: txTableView - anchors.fill : parent - TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 } - TableViewColumn{ role: "from" ; title: "From" ; width: 280 } - TableViewColumn{ role: "to" ; title: "To" ; width: 280 } - TableViewColumn{ role: "confirmations" ; title: "Confirmations" ; width: 100 } - - model: ListModel { - id: txModel - Component.onCompleted: { - } - } - } - } - } -} diff --git a/cmd/mist/assets/qml/views/miner.qml b/cmd/mist/assets/qml/views/miner.qml deleted file mode 100644 index ff2bf85ca..000000000 --- a/cmd/mist/assets/qml/views/miner.qml +++ /dev/null @@ -1,283 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - id: root - property var title: "Miner" - property var iconSource: "../mining-icon.png" - property var menuItem - - color: "#00000000" - - Label { - visible: false - id: lastBlockLabel - objectName: "lastBlockLabel" - text: "---" - onTextChanged: { - //menuItem.secondaryTitle = text - } - } - - ColumnLayout { - spacing: 10 - anchors.fill: parent - - Rectangle { - id: mainPane - color: "#00000000" - anchors { - top: parent.top - bottom: localTxPane.top - left: parent.left - right: parent.right - } - - Rectangle { - id: menu - height: 25 - anchors { - left: parent.left - } - - RowLayout { - id: tools - anchors { - left: parent.left - right: parent.right - } - - Button { - text: "Start" - onClicked: { - // eth.setGasPrice(minGasPrice.text || "10000000000000"); - // eth.setExtra(blockExtra.text) - if (eth.toggleMining()) { - this.text = "Stop"; - } else { - this.text = "Start"; - } - } - } - - // Rectangle { - // id: minGasPriceRect - // anchors.top: parent.top - // anchors.topMargin: 2 - // width: 200 - // TextField { - // id: minGasPrice - // placeholderText: "Min Gas: 10000000000000" - // width: 200 - // validator: RegExpValidator { regExp: /\d*/ } - // } - // } - - // Rectangle { - // width: 300 - // anchors { - // left: minGasPriceRect.right - // leftMargin: 5 - // top: parent.top - // topMargin: 2 - // } - - // TextField { - // id: blockExtra - // placeholderText: "Extra" - // width: parent.width - // maximumLength: 1024 - // } - // } - } - } - - Column { - anchors { - left: parent.left - right: parent.right - top: menu.bottom - topMargin: 5 - } - - Text { - text: "Merged mining options" - } - - TableView { - id: mergedMiningTable - height: 300 - anchors { - left: parent.left - right: parent.right - } - Component { - id: checkBoxDelegate - - Item { - id: test - CheckBox { - anchors.fill: parent - checked: styleData.value - - onClicked: { - var model = mergedMiningModel.get(styleData.row) - - if (this.checked) { - model.id = txModel.createLocalTx(model.address, "0", "5000", "0", "") - } else { - txModel.removeWithId(model.id); - model.id = 0; - } - } - } - } - } - TableViewColumn{ role: "checked" ; title: "" ; width: 40 ; delegate: checkBoxDelegate } - TableViewColumn{ role: "name" ; title: "Name" ; width: 480 } - model: ListModel { - objectName: "mergedMiningModel" - id: mergedMiningModel - function addMergedMiningOption(model) { - this.append(model); - } - } - Component.onCompleted: { - /* - // XXX Temp. replace with above eventually - var tmpItems = ["JEVCoin", "Some coin", "Other coin", "Etc coin"]; - var address = "e6716f9544a56c530d868e4bfbacb172315bdead"; - for (var i = 0; i < tmpItems.length; i++) { - mergedMiningModel.append({checked: false, name: tmpItems[i], address: address, id: 0, itemId: i}); - } - */ - } - } - } - } - - Rectangle { - id: localTxPane - color: "#ececec" - border.color: "#cccccc" - border.width: 1 - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - } - height: 300 - - ColumnLayout { - spacing: 10 - anchors.fill: parent - RowLayout { - id: newLocalTx - anchors { - left: parent.left - leftMargin: 5 - top: parent.top - topMargin: 5 - bottomMargin: 5 - } - - Text { - text: "Local tx" - } - - Rectangle { - width: 250 - color: "#00000000" - anchors.top: parent.top - anchors.topMargin: 2 - - TextField { - id: to - placeholderText: "To" - width: 250 - validator: RegExpValidator { regExp: /[abcdefABCDEF1234567890]*/ } - } - } - TextField { - property var defaultGas: "5000" - id: gas - placeholderText: "Gas" - text: defaultGas - validator: RegExpValidator { regExp: /\d*/ } - } - TextField { - id: gasPrice - placeholderText: "Price" - validator: RegExpValidator { regExp: /\d*/ } - } - TextField { - id: value - placeholderText: "Amount" - text: "0" - validator: RegExpValidator { regExp: /\d*/ } - } - TextField { - id: data - placeholderText: "Data" - validator: RegExpValidator { regExp: /[abcdefABCDEF1234567890]*/ } - } - Button { - text: "Create" - onClicked: { - if (to.text.length == 40 && gasPrice.text.length != 0 && value.text.length != 0 && gas.text.length != 0) { - txModel.createLocalTx(to.text, gasPrice.text, gas.text, value.text, data.text); - - to.text = ""; gasPrice.text = ""; - gas.text = gas.defaultGas; - value.text = "0" - } - } - } - } - - TableView { - id: txTableView - anchors { - top: newLocalTx.bottom - topMargin: 5 - left: parent.left - right: parent.right - bottom: parent.bottom - } - TableViewColumn{ role: "to" ; title: "To" ; width: 480 } - TableViewColumn{ role: "gas" ; title: "Gas" ; width: 100 } - TableViewColumn{ role: "gasPrice" ; title: "Gas Price" ; width: 100 } - TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 } - TableViewColumn{ role: "data" ; title: "Data" ; width: 100 } - - model: ListModel { - id: txModel - Component.onCompleted: { - } - function removeWithId(id) { - for (var i = 0; i < this.count; i++) { - if (txModel.get(i).id == id) { - this.remove(i); - eth.removeLocalTransaction(id) - break; - } - } - } - - function createLocalTx(to, gasPrice, gas, value, data) { - var id = eth.addLocalTransaction(to, data, gas, gasPrice, value) - txModel.insert(0, {to: to, gas: gas, gasPrice: gasPrice, value: value, data: data, id: id}); - - return id - } - } - } - } - } - } -} diff --git a/cmd/mist/assets/qml/views/network-health/205f39107b64acf34cb35d7edb57f47893187a12.js b/cmd/mist/assets/qml/views/network-health/205f39107b64acf34cb35d7edb57f47893187a12.js deleted file mode 100644 index a1f645ca5..000000000 --- a/cmd/mist/assets/qml/views/network-health/205f39107b64acf34cb35d7edb57f47893187a12.js +++ /dev/null @@ -1,176 +0,0 @@ -!function(){var n,t;(function(){t={}}).call(this),function(){(function(){var n=this,r=n._,e={},u=Array.prototype,i=Object.prototype,a=Function.prototype,o=u.push,c=u.slice,l=u.concat,f=i.toString,s=i.hasOwnProperty,p=u.forEach,v=u.map,h=u.reduce,d=u.reduceRight,g=u.filter,m=u.every,y=u.some,b=u.indexOf,_=u.lastIndexOf,w=Array.isArray,x=Object.keys,j=a.bind,A=function(n){return n instanceof A?n:this instanceof A?void(this._wrapped=n):new A(n)};"undefined"!=typeof t?("undefined"!=typeof module&&module.exports&&(t=module.exports=A),t._=A):n._=A,A.VERSION="1.5.2";var k=function(n){return"[object Arguments]"===f.call(n)};k(arguments)||(k=function(n){return!(!n||!s.call(n,"callee")||"function"!=typeof n.callee)});var O=function(n){return n.length===+n.length&&(k(n)||n.constructor!==Object)},E=A.each=A.forEach=function(n,t,r){if(null!=n)if(p&&n.forEach===p)n.forEach(t,r);else if(O(n)){for(var u=0,i=n.length;i>u;u++)if(t.call(r,n[u],u,n)===e)return}else for(var a=A.keys(n),u=0,i=a.length;i>u;u++)if(t.call(r,n[a[u]],a[u],n)===e)return};A.map=A.collect=function(n,t,r){var e=[];return null==n?e:v&&n.map===v?n.map(t,r):(E(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var F="Reduce of empty array with no initial value";A.reduce=A.foldl=A.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=A.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(E(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(F);return r},A.reduceRight=A.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),d&&n.reduceRight===d)return e&&(t=A.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(!O(n)){var a=A.keys(n);i=a.length}if(E(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(F);return r},A.find=A.detect=function(n,t,r){var e;return M(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},A.filter=A.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(E(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},A.reject=function(n,t,r){return A.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},A.every=A.all=function(n,t,r){t||(t=A.identity);var u=!0;return null==n?u:m&&n.every===m?n.every(t,r):(E(n,function(n,i,a){return(u=u&&t.call(r,n,i,a))?void 0:e}),!!u)};var M=A.some=A.any=function(n,t,r){t||(t=A.identity);var u=!1;return null==n?u:y&&n.some===y?n.some(t,r):(E(n,function(n,i,a){return u||(u=t.call(r,n,i,a))?e:void 0}),!!u)};A.contains=A.include=function(n,t){return null==n?!1:b&&n.indexOf===b?-1!=n.indexOf(t):M(n,function(n){return n===t})},A.invoke=function(n,t){var r=c.call(arguments,2),e=A.isFunction(t);return A.map(n,function(n){return(e?t:n[t]).apply(n,r)})},A.pluck=function(n,t){return A.map(n,function(n){return n[t]})},A.where=function(n,t,r){return A.isEmpty(t)?r?void 0:[]:A[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},A.findWhere=function(n,t){return A.where(n,t,!0)},A.max=function(n,t,r){if(!t&&A.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&A.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return E(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},A.min=function(n,t,r){if(!t&&A.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&A.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return E(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;ae||void 0===r)return 1;if(e>r||void 0===e)return-1}return n.index-t.index}),"value")};var S=function(n){return function(t,r,e){var u={},i=null==r?A.identity:R(r);return E(t,function(r,a){var o=i.call(e,r,a,t);n(u,o,r)}),u}};A.groupBy=S(function(n,t,r){(A.has(n,t)?n[t]:n[t]=[]).push(r)}),A.indexBy=S(function(n,t,r){n[t]=r}),A.countBy=S(function(n,t){A.has(n,t)?n[t]++:n[t]=1}),A.sortedIndex=function(n,t,r,e){r=null==r?A.identity:R(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])=0})})},A.difference=function(n){var t=l.apply(u,c.call(arguments,1));return A.filter(n,function(n){return!A.contains(t,n)})},A.zip=function(){for(var n=A.max(A.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=A.pluck(arguments,""+r);return t},A.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},A.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=A.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(b&&n.indexOf===b)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},A.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(_&&n.lastIndexOf===_)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},A.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var T=function(){};A.bind=function(n,t){var r,e;if(j&&n.bind===j)return j.apply(n,c.call(arguments,1));if(!A.isFunction(n))throw new TypeError;return r=c.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(c.call(arguments)));T.prototype=n.prototype;var u=new T;T.prototype=null;var i=n.apply(u,r.concat(c.call(arguments)));return Object(i)===i?i:u}},A.partial=function(n){var t=c.call(arguments,1);return function(){return n.apply(this,t.concat(c.call(arguments)))}},A.bindAll=function(n){var t=c.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return E(t,function(t){n[t]=A.bind(n[t],n)}),n},A.memoize=function(n,t){var r={};return t||(t=A.identity),function(){var e=t.apply(this,arguments);return A.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},A.delay=function(n,t){var r=c.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},A.defer=function(n){return A.delay.apply(A,[n,1].concat(c.call(arguments,1)))},A.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},A.debounce=function(n,t,r){var e,u,i,a,o;return function(){i=this,u=arguments,a=new Date;var c=function(){var l=new Date-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u)))},l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u)),o}},A.once=function(n){var t=!1,r;return function(){return t?r:(t=!0,r=n.apply(this,arguments),n=null,r)}},A.wrap=function(n,t){return function(){var r=[n];return o.apply(r,arguments),t.apply(this,r)}},A.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},A.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},A.keys=x||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)A.has(n,r)&&t.push(r);return t},A.values=function(n){for(var t=A.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},A.pairs=function(n){for(var t=A.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},A.invert=function(n){for(var t={},r=A.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},A.functions=A.methods=function(n){var t=[];for(var r in n)A.isFunction(n[r])&&t.push(r);return t.sort()},A.extend=function(n){return E(c.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},A.pick=function(n){var t={},r=l.apply(u,c.call(arguments,1));return E(r,function(r){r in n&&(t[r]=n[r])}),t},A.omit=function(n){var t={},r=l.apply(u,c.call(arguments,1));for(var e in n)A.contains(r,e)||(t[e]=n[e]);return t},A.defaults=function(n){return E(c.call(arguments,1),function(t){if(t)for(var r in t)void 0===n[r]&&(n[r]=t[r])}),n},A.clone=function(n){return A.isObject(n)?A.isArray(n)?n.slice():A.extend({},n):n},A.tap=function(n,t){return t(n),n};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof A&&(n=n._wrapped),t instanceof A&&(t=t._wrapped);var u=f.call(n);if(u!=f.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(A.isFunction(a)&&a instanceof a&&A.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,l=!0;if("[object Array]"==u){if(c=n.length,l=c==t.length)for(;c--&&(l=N(n[c],t[c],r,e)););}else{for(var s in n)if(A.has(n,s)&&(c++,!(l=A.has(t,s)&&N(n[s],t[s],r,e))))break;if(l){for(s in t)if(A.has(t,s)&&!c--)break;l=!c}}return r.pop(),e.pop(),l};A.isEqual=function(n,t){return N(n,t,[],[])},A.isEmpty=function(n){if(null==n)return!0;if(A.isArray(n)||A.isString(n))return 0===n.length;for(var t in n)if(A.has(n,t))return!1;return!0},A.isElement=function(n){return!(!n||1!==n.nodeType)},A.isArray=w||function(n){return"[object Array]"==f.call(n)},A.isObject=function(n){return n===Object(n)},E(["Arguments","Function","String","Number","Date","RegExp"],function(n){A["is"+n]=function(t){return f.call(t)=="[object "+n+"]"}}),A.isArguments(arguments)||(A.isArguments=function(n){return!(!n||!A.has(n,"callee"))}),"function"!=typeof/./&&(A.isFunction=function(n){return"function"==typeof n}),A.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},A.isNaN=function(n){return A.isNumber(n)&&n!=+n},A.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==f.call(n)},A.isNull=function(n){return null===n},A.isUndefined=function(n){return void 0===n},A.has=function(n,t){return s.call(n,t)},A.noConflict=function(){return n._=r,this},A.identity=function(n){return n},A.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},A.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var q={escape:{"&":"&","<":"<",">":">",'"':""","'":"'"}};q.unescape=A.invert(q.escape);var B={escape:new RegExp("["+A.keys(q.escape).join("")+"]","g"),unescape:new RegExp("("+A.keys(q.unescape).join("|")+")","g")};A.each(["escape","unescape"],function(n){A[n]=function(t){return null==t?"":(""+t).replace(B[n],function(t){return q[n][t]})}}),A.result=function(n,t){if(null==n)return void 0;var r=n[t];return A.isFunction(r)?r.call(n):r},A.mixin=function(n){E(A.functions(n),function(t){var r=A[t]=n[t];A.prototype[t]=function(){var n=[this._wrapped];return o.apply(n,arguments),U.call(this,r.apply(A,n))}})};var D=0;A.uniqueId=function(n){var t=++D+"";return n?n+t:t},A.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var P=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},C=/\\|'|\r|\n|\t|\u2028|\u2029/g;A.template=function(n,t,r){var e;r=A.defaults({},r,A.templateSettings);var u=new RegExp([(r.escape||P).source,(r.interpolate||P).source,(r.evaluate||P).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(C,function(n){return"\\"+z[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,A);var c=function(n){return e.call(this,n,A)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},A.chain=function(n){return A(n).chain()};var U=function(n){return this._chain?A(n).chain():n};A.mixin(A),E(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=u[n];A.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],U.call(this,r)}}),E(["concat","join","slice"],function(n){var t=u[n];A.prototype[n]=function(){return U.call(this,t.apply(this._wrapped,arguments))}}),A.extend(A.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this)}.call(this),function(){n=t._}.call(this),"undefined"==typeof Package&&(Package={}),Package.underscore={_:n}}(); - -!function(){var t=Package.underscore._,e;(function(){e={isClient:!0,isServer:!1},"object"==typeof __meteor_runtime_config__&&__meteor_runtime_config__.PUBLIC_SETTINGS&&(e.settings={"public":__meteor_runtime_config__.PUBLIC_SETTINGS})}).call(this),function(){function n(t){return t?e._debug("Exception in callback of async function",t.stack?t.stack:t):void 0}if(e.isServer)var r=Npm.require("fibers/future");"object"==typeof __meteor_runtime_config__&&__meteor_runtime_config__.meteorRelease&&(e.release=__meteor_runtime_config__.meteorRelease),t.extend(e,{_get:function(t){for(var e=1;e=0;r--){var o=arguments[r+1];if(n)n=!1;else for(var i in e[r][o])return;delete e[r][o]}},wrapAsync:function(o,i){return function(){for(var a=i||this,u=t.toArray(arguments),s,c=u.length-1;c>=0;--c){var l=u[c],f=typeof l;if("undefined"!==f){"function"===f&&(s=l);break}}if(!s){if(e.isClient)s=n;else{var _=new r;s=_.resolver()}++c}u[c]=e.bindEnvironment(s);var p=o.apply(a,u);return _?_.wait():p}},_inherits:function(e,n){for(var r in n)t.has(n,r)&&(e[r]=n[r]);var o=function(){this.constructor=e};return o.prototype=n.prototype,e.prototype=new o,e.__super__=n.prototype,e}});var o=!1;e._wrapAsync=function(t,n){return o||(e._debug("Meteor._wrapAsync has been renamed to Meteor.wrapAsync"),o=!0),e.wrapAsync.apply(e,arguments)}}.call(this),function(){"use strict";function t(){if(o.setImmediate){var t=function(t){o.setImmediate(t)};return t.implementation="setImmediate",t}return null}function n(){function t(t,e){return"string"==typeof t&&t.substring(0,e.length)===e}function e(e){if(e.source===o&&t(e.data,u)){var n=e.data.substring(u.length);try{a[n]&&a[n]()}finally{delete a[n]}}}if(!o.postMessage||o.importScripts)return null;var n=!0,r=o.onmessage;if(o.onmessage=function(){n=!1},o.postMessage("","*"),o.onmessage=r,!n)return null;var i=0,a={},u="Meteor._setImmediate."+Math.random()+".";o.addEventListener?o.addEventListener("message",e,!1):o.attachEvent("onmessage",e);var s=function(t){++i,a[i]=t,o.postMessage(u+i,"*")};return s.implementation="postMessage",s}function r(){var t=function(t){o.setTimeout(t,0)};return t.implementation="setTimeout",t}var o=this;e._setImmediate=t()||n()||r()}.call(this),function(){var n=function(t){if(Package.ddp){var e=Package.ddp.DDP._CurrentInvocation;if(e.get()&&e.get().isSimulation)throw new Error("Can't set timers inside simulations");return function(){e.withValue(null,t)}}return t},r=function(t,r){return e.bindEnvironment(n(r),t)};t.extend(e,{setTimeout:function(t,e){return setTimeout(r("setTimeout callback",t),e)},setInterval:function(t,e){return setInterval(r("setInterval callback",t),e)},clearInterval:function(t){return clearInterval(t)},clearTimeout:function(t){return clearTimeout(t)},defer:function(t){e._setImmediate(r("defer callback",t))}})}.call(this),function(){e.makeErrorType=function(t,n){var r=function(){var e=this;if(Error.captureStackTrace)Error.captureStackTrace(e,r);else{var o=new Error;o.__proto__=r.prototype,o instanceof r&&(e=o)}return n.apply(e,arguments),e.errorType=t,e};return e._inherits(r,Error),r},e.Error=e.makeErrorType("Meteor.Error",function(t,e,n){var r=this;r.error=t,r.reason=e,r.details=n,r.message=r.reason?r.reason+" ["+r.error+"]":"["+r.error+"]"}),e.Error.prototype.clone=function(){var t=this;return new e.Error(t.error,t.reason,t.details)}}.call(this),function(){e._noYieldsAllowed=function(t){return t()},e._SynchronousQueue=function(){var t=this;t._tasks=[],t._running=!1,t._runTimeout=null},t.extend(e._SynchronousQueue.prototype,{runTask:function(n){var r=this;if(!r.safeToRunTask())throw new Error("Could not synchronously run a task from a running task");r._tasks.push(n);var o=r._tasks;r._tasks=[],r._running=!0,r._runTimeout&&(clearTimeout(r._runTimeout),r._runTimeout=null);try{for(;!t.isEmpty(o);){var i=o.shift();try{i()}catch(a){if(t.isEmpty(o))throw a;e._debug("Exception in queued task: "+a.stack)}}}finally{r._running=!1}},queueTask:function(e){var n=this;n._tasks.push(e),n._runTimeout||(n._runTimeout=setTimeout(t.bind(n.flush,n),0))},flush:function(){var t=this;t.runTask(function(){})},drain:function(){var e=this;if(e.safeToRunTask())for(;!t.isEmpty(e._tasks);)e.flush()},safeToRunTask:function(){var t=this;return!t._running}})}.call(this),function(){var t=[],n=!e.isCordova&&("loaded"===document.readyState||"complete"==document.readyState),r=1,o=function(){if(r--,!(r>0)){n=!0;var o=function(){if(e.isCordova&&(!cordova.plugins||!cordova.plugins.CordovaUpdate))return void e.setTimeout(o,20);for(;t.length;)t.shift()()};o()}};document.addEventListener?(document.addEventListener("DOMContentLoaded",o,!1),e.isCordova&&(r++,document.addEventListener("deviceready",o,!1)),window.addEventListener("load",o,!1)):(document.attachEvent("onreadystatechange",function(){"complete"===document.readyState&&o()}),window.attachEvent("load",o)),e.startup=function(r){var o=!document.addEventListener&&document.documentElement.doScroll;if(o&&window===top){try{o("left")}catch(i){return void setTimeout(function(){e.startup(r)},50)}r()}else n?r():t.push(r)}}.call(this),function(){var t=0;e._debug=function(){if(t)return void t--;if("undefined"!=typeof console&&"undefined"!=typeof console.log)if(0==arguments.length)console.log("");else if("function"==typeof console.log.apply){for(var e=!0,n=0;nt?"0"+t:t}function quote(t){return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var n,r,o,f,u=gap,i,a=e[t];switch(a&&"object"==typeof a&&"function"==typeof a.toJSON&&(a=a.toJSON(t)),"function"==typeof rep&&(a=rep.call(e,t,a)),typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";if(gap+=indent,i=[],"[object Array]"===Object.prototype.toString.apply(a)){for(f=a.length,n=0;f>n;n+=1)i[n]=str(n,a)||"null";return o=0===i.length?"[]":gap?"[\n"+gap+i.join(",\n"+gap)+"\n"+u+"]":"["+i.join(",")+"]",gap=u,o}if(rep&&"object"==typeof rep)for(f=rep.length,n=0;f>n;n+=1)"string"==typeof rep[n]&&(r=rep[n],o=str(r,a),o&&i.push(quote(r)+(gap?": ":":")+o));else for(r in a)Object.prototype.hasOwnProperty.call(a,r)&&(o=str(r,a),o&&i.push(quote(r)+(gap?": ":":")+o));return o=0===i.length?"{}":gap?"{\n"+gap+i.join(",\n"+gap)+"\n"+u+"}":"{"+i.join(",")+"}",gap=u,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(t){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(t){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;"function"!=typeof JSON.stringify&&(JSON.stringify=function(t,e,n){var r;if(gap="",indent="","number"==typeof n)for(r=0;n>r;r+=1)indent+=" ";else"string"==typeof n&&(indent=n);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var n,r,o=t[e];if(o&&"object"==typeof o)for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(r=walk(o,n),void 0!==r?o[n]=r:delete o[n]);return reviver.call(t,e,o)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}()}.call(this),"undefined"==typeof Package&&(Package={}),Package.json={JSON:JSON}}(); - -!function(){var n=Package.meteor.Meteor,r;(function(){for(var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e={},a=0;a255)throw new Error("Not ascii. Base64.encode can only take ascii strings.");n[a]=l}}for(var u=[],i=null,o=null,c=null,s=null,a=0;a>2&63,o=(3&n[a])<<4;break;case 1:o|=n[a]>>4&15,c=(15&n[a])<<2;break;case 2:c|=n[a]>>6&3,s=63&n[a],u.push(t(i)),u.push(t(o)),u.push(t(c)),u.push(t(s)),i=null,o=null,c=null,s=null}return null!=i&&(u.push(t(i)),u.push(t(o)),u.push(null==c?"=":t(c)),null==s&&u.push("=")),u.join("")};var t=function(r){return n.charAt(r)},l=function(n){return"="===n?-1:e[n]};r.newBinary=function(n){if("undefined"==typeof Uint8Array||"undefined"==typeof ArrayBuffer){for(var r=[],e=0;n>e;e++)r.push(0);return r.$Uint8ArrayPolyfill=!0,r}return new Uint8Array(new ArrayBuffer(n))},r.decode=function(n){var e=Math.floor(3*n.length/4);"="==n.charAt(n.length-1)&&(e--,"="==n.charAt(n.length-2)&&e--);for(var a=r.newBinary(e),t=null,u=null,i=null,o=0,c=0;cf)throw new Error("invalid base64 string");t=f<<2;break;case 1:if(0>f)throw new Error("invalid base64 string");t|=f>>4,a[o++]=t,u=(15&f)<<4;break;case 2:f>=0&&(u|=f>>2,a[o++]=u,i=(3&f)<<6);break;case 3:f>=0&&(a[o++]=i|f)}}return a}}).call(this),"undefined"==typeof Package&&(Package={}),Package.base64={Base64:r}}(); - -!function(){var n=Package.meteor.Meteor,e=Package.json.JSON,t=Package.underscore._,r=Package.base64.Base64,u,a;(function(){u={},a={};var i={};u.addType=function(n,e){if(t.has(i,n))throw new Error("Type "+n+" already present");i[n]=e};var o=function(n){return t.isNaN(n)||1/0===n||n===-1/0},f=[{matchJSONValue:function(n){return t.has(n,"$date")&&1===t.size(n)},matchObject:function(n){return n instanceof Date},toJSONValue:function(n){return{$date:n.getTime()}},fromJSONValue:function(n){return new Date(n.$date)}},{matchJSONValue:function(n){return t.has(n,"$InfNaN")&&1===t.size(n)},matchObject:o,toJSONValue:function(n){var e;return e=t.isNaN(n)?0:1/0===n?1:-1,{$InfNaN:e}},fromJSONValue:function(n){return n.$InfNaN/0}},{matchJSONValue:function(n){return t.has(n,"$binary")&&1===t.size(n)},matchObject:function(n){return"undefined"!=typeof Uint8Array&&n instanceof Uint8Array||n&&t.has(n,"$Uint8ArrayPolyfill")},toJSONValue:function(n){return{$binary:r.encode(n)}},fromJSONValue:function(n){return r.decode(n.$binary)}},{matchJSONValue:function(n){return t.has(n,"$escape")&&1===t.size(n)},matchObject:function(n){return t.isEmpty(n)||t.size(n)>2?!1:t.any(f,function(e){return e.matchJSONValue(n)})},toJSONValue:function(n){var e={};return t.each(n,function(n,t){e[t]=u.toJSONValue(n)}),{$escape:e}},fromJSONValue:function(n){var e={};return t.each(n.$escape,function(n,t){e[t]=u.fromJSONValue(n)}),e}},{matchJSONValue:function(n){return t.has(n,"$type")&&t.has(n,"$value")&&2===t.size(n)},matchObject:function(n){return u._isCustomType(n)},toJSONValue:function(e){var t=n._noYieldsAllowed(function(){return e.toJSONValue()});return{$type:e.typeName(),$value:t}},fromJSONValue:function(e){var r=e.$type;if(!t.has(i,r))throw new Error("Custom EJSON type "+r+" is not defined");var u=i[r];return n._noYieldsAllowed(function(){return u(e.$value)})}}];u._isCustomType=function(n){return n&&"function"==typeof n.toJSONValue&&"function"==typeof n.typeName&&t.has(i,n.typeName())};var c=u._adjustTypesToJSONValue=function(n){if(null===n)return null;var e=l(n);return void 0!==e?e:"object"!=typeof n?n:(t.each(n,function(e,t){if("object"==typeof e||void 0===e||o(e)){var r=l(e);return r?void(n[t]=r):void c(e)}}),n)},l=function(n){for(var e=0;e=f.length?!1:t!==f[a]?!1:u.equals(n,e[f[a]],r)?(a++,!0):!1}),o&&a===f.length}return a=0,o=t.all(n,function(n,i){return t.has(e,i)&&u.equals(n,e[i],r)?(a++,!0):!1}),o&&t.size(e)===a},u.clone=function(n){var e;if("object"!=typeof n)return n;if(null===n)return null;if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return n;if(u.isBinary(n)){e=u.newBinary(n.length);for(var r=0;rf;f+=1)h[f]=r(f,N,a,y,o)||"null";return l=0===h.length?"[]":y?"[\n"+y+h.join(",\n"+y)+"\n"+i+"]":"["+h.join(",")+"]"}var p=t.keys(N);return o&&(p=p.sort()),t.each(p,function(e){l=r(e,N,a,y,o),l&&h.push(n(e)+(y?": ":":")+l)}),l=0===h.length?"{}":y?"{\n"+y+h.join(",\n"+y)+"\n"+i+"}":"{"+h.join(",")+"}"}};u._canonicalStringify=function(n,e){if(e=t.extend({indent:"",canonical:!1},e),e.indent===!0)e.indent=" ";else if("number"==typeof e.indent){for(var u="",a=0;ae?"0"+e:e.toString()},D=function(e){return 100>e?"0"+b(e):e.toString()},j=o.getFullYear().toString()+b(o.getMonth()+1)+b(o.getDate()),S=b(o.getHours())+":"+b(o.getMinutes())+":"+b(o.getSeconds())+"."+D(o.getMilliseconds()),k="("+-((new Date).getTimezoneOffset()/60)+")",E="";m&&(E+=m),p&&p!==m&&(E+=" via "+p),E&&(E="["+E+"] ");var x=[];h&&x.push(h),g&&x.push(g),f&&x.push(f);var y=t.isEmpty(x)?"":"("+x.join(":")+") ";d&&(y+=["[",d,"]"].join(""));var _=w?"(STDERR) ":"",C=[c.charAt(0).toUpperCase(),j,"-",S,k,a?"? ":" ",E,y,_].join(""),F=function(t,r){return i.color&&e.isServer&&r?Npm.require("cli-color")[r](t):t};return F(C,i.metaColor||l)+F(v,s[c])},n.objFromText=function(e,r){var n={message:e,level:"info",time:new Date,timeInexact:!0};return t.extend(n,r)}}).call(this),"undefined"==typeof Package&&(Package={}),Package.logging={Log:n}}(); - -!function(){var a=Package.meteor.Meteor,e=Package.underscore._,t=Package.logging.Log,o=Package.json.JSON,n;(function(){n={};var t="Meteor_Reload",r={},i,l=null;try{l=window.sessionStorage,l?(l.setItem("__dummy__","1"),l.removeItem("__dummy__")):l=null}catch(g){l=null}n._getData=function(){return l&&l.getItem(t)},l&&(i=n._getData(),l.removeItem(t)),i||(i="{}");var c={};try{c=o.parse(i),"object"!=typeof c&&(a._debug("Got bad data on reload. Ignoring."),c={})}catch(d){a._debug("Got invalid JSON on reload. Ignoring.")}c.reload&&"object"==typeof c.data&&(r=c.data);var u=[];n._onMigrate=function(a,e){e||(e=a,a=void 0),u.push({name:a,callback:e})},n._migrationData=function(a){return r[a]};var s=function(a,t){a=a||function(){},t=t||{};for(var o={},n=e.clone(u),r=!0;n.length;){var i=n.shift(),l=i.callback(a,t);l[0]||(r=!1),l.length>1&&i.name&&(o[i.name]=l[1])}return r||t.immediateMigration?o:null};n._migrate=function(e,n){var r=s(e,n);if(null===r)return!1;try{var i=o.stringify({data:r,reload:!0})}catch(g){throw a._debug("Couldn't serialize data for migration",r),g}if(l)try{l.setItem(t,i)}catch(g){a._debug("Couldn't save data for migration to sessionStorage",g)}else a._debug("Browser does not support sessionStorage. Not saving migration state.");return!0},n._withFreshProvidersForTest=function(a){var t=e.clone(u);u=[];try{a()}finally{u=t}};var f=!1;n._reload=function(a){if(a=a||{},!f){f=!0;var t=function(){e.defer(function(){n._migrate(t,a)&&window.location.reload()})};t()}}}).call(this),function(){a._reload={onMigrate:n._onMigrate,migrationData:n._migrationData,reload:n._reload}}.call(this),"undefined"==typeof Package&&(Package={}),Package.reload={Reload:n}}(); - -!function(){var t=Package.meteor.Meteor,n,e;(function(){n={},n.active=!1,n.currentComputation=null;var e=function(t){n.currentComputation=t,n.active=!!t},o=function(){return"undefined"!=typeof t?t._debug:"undefined"!=typeof console&&console.log?function(){console.log.apply(console,arguments)}:function(){}},r=function(t,n){if(p)throw n;var e;if(n.stack&&n.message){var r=n.stack.indexOf(n.message);e=r>=0&&10>=r?n.stack:n.message+("\n"===n.stack.charAt(0)?"":"\n")+n.stack}else e=n.stack||n.message;o()("Exception from Tracker "+t+" function:",e)},a=function(n){return"undefined"==typeof t||t.isClient?n:function(){var e=arguments;t._noYieldsAllowed(function(){n.apply(null,e)})}},i=1,u=[],c=!1,s=!1,f=!1,p=!1,d=[],l=function(){c||(setTimeout(n.flush,0),c=!0)},v=!1;n.Computation=function(t,n){if(!v)throw new Error("Tracker.Computation constructor is private; use Tracker.autorun");v=!1;var e=this;e.stopped=!1,e.invalidated=!1,e.firstRun=!0,e._id=i++,e._onInvalidateCallbacks=[],e._parent=n,e._func=t,e._recomputing=!1;var o=!0;try{e._compute(),o=!1}finally{e.firstRun=!1,o&&e.stop()}},n.Computation.prototype.onInvalidate=function(t){var e=this;if("function"!=typeof t)throw new Error("onInvalidate requires a function");e.invalidated?n.nonreactive(function(){a(t)(e)}):e._onInvalidateCallbacks.push(t)},n.Computation.prototype.invalidate=function(){var t=this;if(!t.invalidated){t._recomputing||t.stopped||(l(),u.push(this)),t.invalidated=!0;for(var e=0,o;o=t._onInvalidateCallbacks[e];e++)n.nonreactive(function(){a(o)(t)});t._onInvalidateCallbacks=[]}},n.Computation.prototype.stop=function(){this.stopped||(this.stopped=!0,this.invalidate())},n.Computation.prototype._compute=function(){var t=this;t.invalidated=!1;var o=n.currentComputation;e(t);var r=f;f=!0;try{a(t._func)(t)}finally{e(o),f=r}},n.Computation.prototype._recompute=function(){var t=this;t._recomputing=!0;try{for(;t.invalidated&&!t.stopped;)try{t._compute()}catch(n){r("recompute",n)}}finally{t._recomputing=!1}},n.Dependency=function(){this._dependentsById={}},n.Dependency.prototype.depend=function(t){if(!t){if(!n.active)return!1;t=n.currentComputation}var e=this,o=t._id;return o in e._dependentsById?!1:(e._dependentsById[o]=t,t.onInvalidate(function(){delete e._dependentsById[o]}),!0)},n.Dependency.prototype.changed=function(){var t=this;for(var n in t._dependentsById)t._dependentsById[n].invalidate()},n.Dependency.prototype.hasDependents=function(){var t=this;for(var n in t._dependentsById)return!0;return!1},n.flush=function(t){if(s)throw new Error("Can't call Tracker.flush while flushing");if(f)throw new Error("Can't flush inside Tracker.autorun");s=!0,c=!0,p=!(!t||!t._throwFirstError);var e=!1;try{for(;u.length||d.length;){for(;u.length;){var o=u.shift();o._recompute()}if(d.length){var a=d.shift();try{a()}catch(i){r("afterFlush",i)}}}e=!0}finally{e||(s=!1,n.flush({_throwFirstError:!1})),c=!1,s=!1}},n.autorun=function(t){if("function"!=typeof t)throw new Error("Tracker.autorun requires a function argument");v=!0;var e=new n.Computation(t,n.currentComputation);return n.active&&n.onInvalidate(function(){e.stop()}),e},n.nonreactive=function(t){var o=n.currentComputation;e(null);try{return t()}finally{e(o)}},n.onInvalidate=function(t){if(!n.active)throw new Error("Tracker.onInvalidate requires a currentComputation");n.currentComputation.onInvalidate(t)},n.afterFlush=function(t){d.push(t),l()}}).call(this),function(){t.flush=n.flush,t.autorun=n.autorun,t.autosubscribe=n.autorun,n.depend=function(t){return t.depend()},e=n}.call(this),"undefined"==typeof Package&&(Package={}),Package.tracker={Tracker:n,Deps:e}}(); - -!function(){var e=Package.meteor.Meteor,n=Package.underscore._,t;(function(){if(e.isServer)var n=Npm.require("crypto");var r=function(){function e(){var e=4022871197,n=function(n){n=n.toString();for(var t=0;t>>0,r-=e,r*=e,e=r>>>0,r-=e,e+=4294967296*r}return 2.3283064365386963e-10*(e>>>0)};return n.version="Mash 0.9",n}return function(n){var t=0,r=0,o=0,i=1;0==n.length&&(n=[+new Date]);var a=e();t=a(" "),r=a(" "),o=a(" ");for(var u=0;ut&&(t+=1),r-=a(n[u]),0>r&&(r+=1),o-=a(n[u]),0>o&&(o+=1);a=null;var d=function(){var e=2091639*t+2.3283064365386963e-10*i;return t=r,r=o,o=e-(i=0|e)};return d.uint32=function(){return 4294967296*d()},d.fract53=function(){return d()+1.1102230246251565e-16*(2097152*d()|0)},d.version="Alea 0.9",d.args=n,d}(Array.prototype.slice.call(arguments))},o="23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz",i="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_",a=function(e){var n=this;void 0!==e&&(n.alea=r.apply(null,e))};a.prototype.fraction=function(){var e=this;if(e.alea)return e.alea();if(n){var t=parseInt(e.hexString(8),16);return 2.3283064365386963e-10*t}if("undefined"!=typeof window&&window.crypto&&window.crypto.getRandomValues){var r=new Uint32Array(1);return window.crypto.getRandomValues(r),2.3283064365386963e-10*r[0]}throw new Error("No random generator available")},a.prototype.hexString=function(e){var t=this;if(n&&!t.alea){var r=Math.ceil(e/2),o;try{o=n.randomBytes(r)}catch(i){o=n.pseudoRandomBytes(r)}var a=o.toString("hex");return a.substring(0,e)}for(var u=[],d=0;e>d;++d)u.push(t.choice("0123456789abcdef"));return u.join("")},a.prototype._randomString=function(e,n){for(var t=this,r=[],o=0;e>o;o++)r[o]=t.choice(n);return r.join("")},a.prototype.id=function(e){var n=this;return void 0===e&&(e=17),n._randomString(e,o)},a.prototype.secret=function(e){var n=this;return void 0===e&&(e=43),n._randomString(e,i)},a.prototype.choice=function(e){var n=Math.floor(this.fraction()*e.length);return"string"==typeof e?e.substr(n,1):e[n]};var u="undefined"!=typeof window&&window.innerHeight||"undefined"!=typeof document&&document.documentElement&&document.documentElement.clientHeight||"undefined"!=typeof document&&document.body&&document.body.clientHeight||1,d="undefined"!=typeof window&&window.innerWidth||"undefined"!=typeof document&&document.documentElement&&document.documentElement.clientWidth||"undefined"!=typeof document&&document.body&&document.body.clientWidth||1,c="undefined"!=typeof navigator&&navigator.userAgent||"";t=n||"undefined"!=typeof window&&window.crypto&&window.crypto.getRandomValues?new a:new a([new Date,u,d,c,Math.random()]),t.createWithSeeds=function(){if(0===arguments.length)throw new Error("No seeds were provided");return new a(arguments)}}).call(this),function(){e.uuid=function(){for(var e="0123456789abcdef",n=[],r=0;36>r;r++)n[r]=t.choice(e);n[14]="4",n[19]=e.substr(3&parseInt(n[19],16)|8,1),n[8]=n[13]=n[18]=n[23]="-";var o=n.join("");return o}}.call(this),"undefined"==typeof Package&&(Package={}),Package.random={Random:t}}(); - -!function(){var e=Package.meteor.Meteor,t=Package.underscore._,r=Package.random.Random,i;(function(){i=function(e){var r=this;t.extend(r,t.defaults(t.clone(e||{}),{baseTimeout:1e3,exponent:2.2,maxTimeout:3e5,minTimeout:10,minCount:2,fuzz:.5})),r.retryTimer=null},t.extend(i.prototype,{clear:function(){var e=this;e.retryTimer&&clearTimeout(e.retryTimer),e.retryTimer=null},_timeout:function(e){var t=this;if(en!=a[e][0]>n&&t<(a[e][1]-a[r][1])*(n-a[r][0])/(a[e][0]-a[r][0])+a[r][1]&&(i=!i);return i}var a={};"undefined"!=typeof o&&o.exports&&(o.exports=a),a.lineStringsIntersect=function(t,n){for(var o=[],a=0;a<=t.coordinates.length-2;++a)for(var r=0;r<=n.coordinates.length-2;++r){var e={x:t.coordinates[a][1],y:t.coordinates[a][0]},i={x:t.coordinates[a+1][1],y:t.coordinates[a+1][0]},s={x:n.coordinates[r][1],y:n.coordinates[r][0]},c={x:n.coordinates[r+1][1],y:n.coordinates[r+1][0]},u=(c.x-s.x)*(e.y-s.y)-(c.y-s.y)*(e.x-s.x),h=(i.x-e.x)*(e.y-s.y)-(i.y-e.y)*(e.x-s.x),d=(c.y-s.y)*(i.x-e.x)-(c.x-s.x)*(i.y-e.y);if(0!=d){var l=u/d,y=h/d;l>=0&&1>=l&&y>=0&&1>=y&&o.push({type:"Point",coordinates:[e.x+l*(i.x-e.x),e.y+l*(i.y-e.y)]})}}return 0==o.length&&(o=!1),o},a.pointInBoundingBox=function(t,n){return!(t.coordinates[1]n[1][0]||t.coordinates[0]n[1][1])},a.pointInPolygon=function(o,r){for(var e="Polygon"==r.type?[r.coordinates]:r.coordinates,i=!1,s=0;sc;c++){var u=2*Math.PI*c/o,h=Math.asin(Math.sin(i[0])*Math.cos(e)+Math.cos(i[0])*Math.sin(e)*Math.cos(u)),d=i[1]+Math.atan2(Math.sin(u)*Math.sin(e)*Math.cos(i[0]),Math.cos(e)-Math.sin(i[0])*Math.sin(h));s[c]=[],s[c][1]=a.numberToDegree(h),s[c][0]=a.numberToDegree(d)}return{type:"Polygon",coordinates:[s]}},a.rectangleCentroid=function(t){var n=t.coordinates[0],o=n[0][0],a=n[0][1],r=n[2][0],e=n[2][1],i=r-o,s=e-a;return{type:"Point",coordinates:[o+i/2,a+s/2]}},a.pointDistance=function(t,n){var o=t.coordinates[0],r=t.coordinates[1],e=n.coordinates[0],i=n.coordinates[1],s=a.numberToRadius(i-r),c=a.numberToRadius(e-o),u=Math.pow(Math.sin(s/2),2)+Math.cos(a.numberToRadius(r))*Math.cos(a.numberToRadius(i))*Math.pow(Math.sin(c/2),2),h=2*Math.atan2(Math.sqrt(u),Math.sqrt(1-u));return 6371*h*1e3},a.geometryWithinRadius=function(t,n,o){if("Point"==t.type)return a.pointDistance(t,n)<=o;if("LineString"==t.type||"Polygon"==t.type){var r={},e;e="Polygon"==t.type?t.coordinates[0]:t.coordinates;for(var i in e)if(r.coordinates=e[i],a.pointDistance(r,n)>o)return!1}return!0},a.area=function(t){for(var n=0,o=t.coordinates[0],a=o.length-1,r,e,i=0;i0;)if(e=T[a-1],i=I[a-1],a--,i-e>1){for(l=t[i].lng()-t[e].lng(),y=t[i].lat()-t[e].lat(),Math.abs(l)>180&&(l=360-Math.abs(l)),l*=Math.cos(b*(t[i].lat()+t[e].lat())),M=l*l+y*y,s=e+1,c=e,h=-1;i>s;s++)f=t[s].lng()-t[e].lng(),g=t[s].lat()-t[e].lat(),Math.abs(f)>180&&(f=360-Math.abs(f)),f*=Math.cos(b*(t[s].lat()+t[e].lat())),x=f*f+g*g,p=t[s].lng()-t[i].lng(),v=t[s].lat()-t[i].lat(),Math.abs(p)>180&&(p=360-Math.abs(p)),p*=Math.cos(b*(t[s].lat()+t[i].lat())),P=p*p+v*v,u=x>=M+P?P:P>=M+x?x:(f*y-g*l)*(f*y-g*l)/M,u>h&&(c=s,h=u);d>h?(m[r]=e,r++):(a++,T[a-1]=c,I[a-1]=i,a++,T[a-1]=e,I[a-1]=c)}else m[r]=e,r++;m[r]=o-1,r++;for(var R=new Array,s=0;r>s;s++)R.push(t[m[s]]);return R.map(function(t){return{type:"Point",coordinates:[t.lng,t.lat]}})},a.destinationPoint=function(t,n,o){o/=6371,n=a.numberToRadius(n);var r=a.numberToRadius(t.coordinates[0]),e=a.numberToRadius(t.coordinates[1]),i=Math.asin(Math.sin(r)*Math.cos(o)+Math.cos(r)*Math.sin(o)*Math.cos(n)),s=e+Math.atan2(Math.sin(n)*Math.sin(o)*Math.cos(r),Math.cos(o)-Math.sin(r)*Math.sin(i));return s=(s+3*Math.PI)%(2*Math.PI)-Math.PI,{type:"Point",coordinates:[a.numberToDegree(i),a.numberToDegree(s)]}}}()}.call(this),function(){n=o.exports}.call(this),"undefined"==typeof Package&&(Package={}),Package["geojson-utils"]={GeoJSON:n}}(); - -!function(){var e=Package.meteor.Meteor,r=Package.underscore._,t=Package.json.JSON,n=Package.ejson.EJSON,o=Package["id-map"].IdMap,i=Package["ordered-dict"].OrderedDict,a=Package.tracker.Tracker,s=Package.tracker.Deps,c=Package.random.Random,u=Package["geojson-utils"].GeoJSON,d,f,l,h,p,v,_,m,y,g,w,b,$,I,E,O;(function(){d=function(r){var t=this;t.name=r,t._docs=new d._IdMap,t._observeQueue=new e._SynchronousQueue,t.next_qid=1,t.queries={},t._savedOriginals=null,t.paused=!1},f={},l={},d._applyChanges=function(e,t){r.each(t,function(r,t){void 0===r?delete e[t]:e[t]=r})},h=function(e){var r=new Error(e);return r.name="MinimongoError",r},d.prototype.find=function(e,r){return 0===arguments.length&&(e={}),new d.Cursor(this,e,r)},d.Cursor=function(e,r,t){var n=this;t||(t={}),n.collection=e,n.sorter=null,d._selectorIsId(r)?(n._selectorId=r,n.matcher=new f.Matcher(r,n)):(n._selectorId=void 0,n.matcher=new f.Matcher(r,n),(n.matcher.hasGeoQuery()||t.sort)&&(n.sorter=new f.Sorter(t.sort||[],{matcher:n.matcher}))),n.skip=t.skip,n.limit=t.limit,n.fields=t.fields,n.fields&&(n.projectionFn=d._compileProjection(n.fields)),n._transform=d.wrapTransform(t.transform),"undefined"!=typeof a&&(n.reactive=void 0===t.reactive?!0:t.reactive)},d.Cursor.prototype.rewind=function(){},d.prototype.findOne=function(e,r){return 0===arguments.length&&(e={}),r=r||{},r.limit=1,this.find(e,r).fetch()[0]},d.Cursor.prototype.forEach=function(e,t){var o=this,i=o._getRawObjects({ordered:!0});o.reactive&&o._depend({addedBefore:!0,removed:!0,changed:!0,movedBefore:!0}),r.each(i,function(r,i){r=o.projectionFn?o.projectionFn(r):n.clone(r),o._transform&&(r=o._transform(r)),e.call(t,r,i,o)})},d.Cursor.prototype.getTransform=function(){return this._transform},d.Cursor.prototype.map=function(e,r){var t=this,n=[];return t.forEach(function(o,i){n.push(e.call(r,o,i,t))}),n},d.Cursor.prototype.fetch=function(){var e=this,r=[];return e.forEach(function(e){r.push(e)}),r},d.Cursor.prototype.count=function(){var e=this;return e.reactive&&e._depend({added:!0,removed:!0},!0),e._getRawObjects({ordered:!0}).length},d.Cursor.prototype._publishCursor=function(e){var r=this;if(!r.collection.name)throw new Error("Can't publish a cursor from a collection without a name.");var t=r.collection.name;return Mongo.Collection._publishCursor(r,e,t)},d.Cursor.prototype._getCollectionName=function(){var e=this;return e.collection.name},d._observeChangesCallbacksAreOrdered=function(e){if(e.added&&e.addedBefore)throw new Error("Please specify only one of added() and addedBefore()");return!(!e.addedBefore&&!e.movedBefore)},d._observeCallbacksAreOrdered=function(e){if(e.addedAt&&e.added)throw new Error("Please specify only one of added() and addedAt()");if(e.changedAt&&e.changed)throw new Error("Please specify only one of changed() and changedAt()");if(e.removed&&e.removedAt)throw new Error("Please specify only one of removed() and removedAt()");return!!(e.addedAt||e.movedTo||e.changedAt||e.removedAt)},d.ObserveHandle=function(){},r.extend(d.Cursor.prototype,{observe:function(e){var r=this;return d._observeFromObserveChanges(r,e)},observeChanges:function(e){var t=this,o=d._observeChangesCallbacksAreOrdered(e);if(!e._allow_unordered&&!o&&(t.skip||t.limit))throw new Error("must use ordered observe (ie, 'addedBefore' instead of 'added') with skip or limit");if(t.fields&&(0===t.fields._id||t.fields._id===!1))throw Error("You may not observe a cursor with {fields: {_id: 0}}");var i={matcher:t.matcher,sorter:o&&t.sorter,distances:t.matcher.hasGeoQuery()&&o&&new d._IdMap,resultsSnapshot:null,ordered:o,cursor:t,projectionFn:t.projectionFn},s;t.reactive&&(s=t.collection.next_qid++,t.collection.queries[s]=i),i.results=t._getRawObjects({ordered:o,distances:i.distances}),t.collection.paused&&(i.resultsSnapshot=o?[]:new d._IdMap);var c=function(e,n,o){return e?function(){var i=this,a=arguments;t.collection.paused||void 0!==n&&t.projectionFn&&(a[n]=t.projectionFn(a[n]),o&&r.isEmpty(a[n]))||t.collection._observeQueue.queueTask(function(){e.apply(i,a)})}:function(){}};if(i.added=c(e.added,1),i.changed=c(e.changed,1,!0),i.removed=c(e.removed),o&&(i.addedBefore=c(e.addedBefore,1),i.movedBefore=c(e.movedBefore)),!e._suppress_initial&&!t.collection.paused){var u=o?r.bind(r.each,null,i.results):r.bind(i.results.forEach,i.results);u(function(e){var r=n.clone(e);delete r._id,o&&i.addedBefore(e._id,r,null),i.added(e._id,r)})}var f=new d.ObserveHandle;return r.extend(f,{collection:t.collection,stop:function(){t.reactive&&delete t.collection.queries[s]}}),t.reactive&&a.active&&a.onInvalidate(function(){f.stop()}),t.collection._observeQueue.drain(),f}}),d.Cursor.prototype._getRawObjects=function(e){var r=this;e=e||{};var t=e.ordered?[]:new d._IdMap;if(void 0!==r._selectorId){if(r.skip)return t;var n=r.collection._docs.get(r._selectorId);return n&&(e.ordered?t.push(n):t.set(r._selectorId,n)),t}var o;if(r.matcher.hasGeoQuery()&&e.ordered&&(e.distances?(o=e.distances,o.clear()):o=new d._IdMap),r.collection._docs.forEach(function(n,i){var a=r.matcher.documentMatches(n);return a.result&&(e.ordered?(t.push(n),o&&void 0!==a.distance&&o.set(i,a.distance)):t.set(i,n)),!r.limit||r.skip||r.sorter||t.length!==r.limit?!0:!1}),!e.ordered)return t;if(r.sorter){var i=r.sorter.getComparator({distances:o});t.sort(i)}var a=r.skip||0,s=r.limit?r.limit+a:t.length;return t.slice(a,s)},d.Cursor.prototype._depend=function(e,t){var n=this;if(a.active){var o=new a.Dependency;o.depend();var i=r.bind(o.changed,o),s={_suppress_initial:!0,_allow_unordered:t};r.each(["added","changed","removed","addedBefore","movedBefore"],function(r){e[r]&&(s[r]=i)}),n.observeChanges(s)}},d.prototype.insert=function(t,o){var i=this;t=n.clone(t),r.has(t,"_id")||(t._id=d._useOID?new d._ObjectID:c.id());var a=t._id;if(i._docs.has(a))throw h("Duplicate _id '"+a+"'");i._saveOriginal(a,void 0),i._docs.set(a,t);var s=[];for(var u in i.queries){var f=i.queries[u],l=f.matcher.documentMatches(t);l.result&&(f.distances&&void 0!==l.distance&&f.distances.set(a,l.distance),f.cursor.skip||f.cursor.limit?s.push(u):d._insertInResults(f,t))}return r.each(s,function(e){i.queries[e]&&d._recomputeResults(i.queries[e])}),i._observeQueue.drain(),o&&e.defer(function(){o(null,a)}),a},d.prototype._eachPossiblyMatchingDoc=function(e,r){var t=this,n=d._idsMatchedBySelector(e);if(n)for(var o=0;o0;){var i=Math.floor(o/2);e(t,r[n+i])>=0?(n+=i+1,o-=i+1):o=i}return n},d._insertInSortedList=function(e,r,t){if(0===r.length)return r.push(t),0;var n=d._binarySearch(e,r,t);return r.splice(n,0,t),n},d.prototype.saveOriginals=function(){var e=this;if(e._savedOriginals)throw new Error("Called saveOriginals twice without retrieveOriginals");e._savedOriginals=new d._IdMap},d.prototype.retrieveOriginals=function(){var e=this;if(!e._savedOriginals)throw new Error("Called retrieveOriginals without saveOriginals");var r=e._savedOriginals;return e._savedOriginals=null,r},d.prototype._saveOriginal=function(e,r){var t=this;t._savedOriginals&&(t._savedOriginals.has(e)||t._savedOriginals.set(e,n.clone(r)))},d.prototype.pauseObservers=function(){if(!this.paused){this.paused=!0;for(var e in this.queries){var r=this.queries[e];r.resultsSnapshot=n.clone(r.results)}}},d.prototype.resumeObservers=function(){var e=this;if(this.paused){this.paused=!1;for(var r in this.queries){var t=e.queries[r];d._diffQueryChanges(t.ordered,t.resultsSnapshot,t.results,t),t.resultsSnapshot=null}e._observeQueue.drain()}},d._idStringify=function(e){if(e instanceof d._ObjectID)return e.valueOf();if("string"==typeof e)return""===e?e:"-"===e.substr(0,1)||"~"===e.substr(0,1)||d._looksLikeObjectID(e)||"{"===e.substr(0,1)?"-"+e:e;if(void 0===e)return"-";if("object"==typeof e&&null!==e)throw new Error("Meteor does not currently support objects other than ObjectID as ids");return"~"+t.stringify(e)},d._idParse=function(e){return""===e?e:"-"===e?void 0:"-"===e.substr(0,1)?e.substr(1):"~"===e.substr(0,1)?t.parse(e.substr(1)):d._looksLikeObjectID(e)?new d._ObjectID(e):e},d._makeChangedFields=function(e,r){var t={};return d._diffObjects(r,e,{leftOnly:function(e,r){t[e]=void 0},rightOnly:function(e,r){t[e]=r},both:function(e,r,o){n.equals(r,o)||(t[e]=o)}}),t}}).call(this),function(){d.wrapTransform=function(e){return e?function(t){if(!r.has(t,"_id"))throw new Error("can only transform documents with _id");var o=t._id,i=a.nonreactive(function(){return e(t)});if(!v(i))throw new Error("transform must return object");if(r.has(i,"_id")){if(!n.equals(i._id,o))throw new Error("transformed document can't have different _id")}else i._id=o;return i}:null}}.call(this),function(){p=function(e){return r.isArray(e)&&!n.isBinary(e)},v=d._isPlainObject=function(e){return e&&3===d._f._type(e)},_=function(e){return p(e)||v(e)},m=function(e,n){if(!v(e))return!1;var o=void 0;return r.each(e,function(r,i){var a="$"===i.substr(0,1);if(void 0===o)o=a;else if(o!==a){if(!n)throw new Error("Inconsistent operator: "+t.stringify(e));o=!1}}),!!o},y=function(e){return/^[0-9]+$/.test(e)}}.call(this),function(){f.Matcher=function(e){var r=this;r._paths={},r._hasGeoQuery=!1,r._hasWhere=!1,r._isSimple=!0,r._matchingDocument=void 0,r._selector=null,r._docMatcher=r._compileSelector(e)},r.extend(f.Matcher.prototype,{documentMatches:function(e){if(!e||"object"!=typeof e)throw Error("documentMatches needs a document");return this._docMatcher(e)},hasGeoQuery:function(){return this._hasGeoQuery},hasWhere:function(){return this._hasWhere},isSimple:function(){return this._isSimple},_compileSelector:function(r){var t=this;if(r instanceof Function)return t._isSimple=!1,t._selector=r,t._recordPathUsed(""),function(e){return{result:!!r.call(e)}};if(d._selectorIsId(r))return t._selector={_id:r},t._recordPathUsed("_id"),function(e){return{result:n.equals(e._id,r)}};if(!r||"_id"in r&&!r._id)return t._isSimple=!1,k;if("boolean"==typeof r||p(r)||n.isBinary(r))throw new Error("Invalid selector: "+r);return t._selector=n.clone(r),e(r,t,{isRoot:!0})},_recordPathUsed:function(e){this._paths[e]=!0},_getPaths:function(){return r.keys(this._paths)}});var e=function(e,n,o){o=o||{};var i=[];return r.each(e,function(e,a){if("$"===a.substr(0,1)){if(!r.has(s,a))throw new Error("Unrecognized logical operator: "+a);n._isSimple=!1,i.push(s[a](e,n,o.inElemMatch))}else{o.inElemMatch||n._recordPathUsed(a);var c=$(a),u=t(e,n,o.isRoot);i.push(function(e){var r=c(e);return u(r)})}}),A(i)},t=function(e,r,t){return e instanceof RegExp?(r._isSimple=!1,o(g(e))):m(e)?i(e,r,t):o(w(e))},o=function(e,t){return t=t||{},function(n){var o=n;t.dontExpandLeafArrays||(o=I(n,t.dontIncludeLeafArrays));var i={};return i.result=r.any(o,function(r){var t=e(r.value);return"number"==typeof t&&(r.arrayIndices||(r.arrayIndices=[t]),t=!0),t&&r.arrayIndices&&(i.arrayIndices=r.arrayIndices),t}),i}};g=function(e){return function(t){return t instanceof RegExp?r.isEqual(t,e):"string"!=typeof t?!1:(e.lastIndex=0,e.test(t))}},w=function(e){if(m(e))throw Error("Can't create equalityValueSelector for operator object");return null==e?function(e){return null==e}:function(r){return d._f._equal(e,r)}};var i=function(e,t,n){var i=[];return r.each(e,function(a,s){var c=r.contains(["$lt","$lte","$gt","$gte"],s)&&r.isNumber(a),u="$ne"===s&&!r.isObject(a),d=r.contains(["$in","$nin"],s)&&r.isArray(a)&&!r.any(a,r.isObject);if("$eq"===s||c||d||u||(t._isSimple=!1),r.has(h,s))i.push(h[s](a,e,t,n));else{if(!r.has(b,s))throw new Error("Unrecognized operator: "+s);var f=b[s];i.push(o(f.compileElementSelector(a,e,t),f))}}),M(i)},a=function(t,n,o){if(!p(t)||r.isEmpty(t))throw Error("$and/$or/$nor must be nonempty array");return r.map(t,function(r){if(!v(r))throw Error("$or/$and/$nor entries need to be full objects");return e(r,n,{inElemMatch:o})})},s={$and:function(e,r,t){var n=a(e,r,t);return A(n)},$or:function(e,t,n){var o=a(e,t,n);return 1===o.length?o[0]:function(e){var t=r.any(o,function(r){return r(e).result});return{result:t}}},$nor:function(e,t,n){var o=a(e,t,n);return function(e){var t=r.all(o,function(r){return!r(e).result});return{result:t}}},$where:function(e,r){return r._recordPathUsed(""),r._hasWhere=!0,e instanceof Function||(e=Function("obj","return "+e)),function(r){return{result:e.call(r,r)}}},$comment:function(){return function(){return{result:!0}}}},c=function(e){return function(r){var t=e(r);return{result:!t.result}}},h={$not:function(e,r,n){return c(t(e,n))},$ne:function(e){return c(o(w(e)))},$nin:function(e){return c(o(b.$in.compileElementSelector(e)))},$exists:function(e){var r=o(function(e){return void 0!==e});return e?r:c(r)},$options:function(e,t){if(!r.has(t,"$regex"))throw Error("$options needs a $regex");return j},$maxDistance:function(e,r){if(!r.$near)throw Error("$maxDistance needs a $near");return j},$all:function(e,n,o){if(!p(e))throw Error("$all requires array");if(r.isEmpty(e))return k;var i=[];return r.each(e,function(e){if(m(e))throw Error("no $ expressions in $all");i.push(t(e,o))}),M(i)},$near:function(e,t,n,o){if(!o)throw Error("$near can't be inside another $ operator");n._hasGeoQuery=!0;var i,a,s;if(v(e)&&r.has(e,"$geometry"))i=e.$maxDistance,a=e.$geometry,s=function(e){return e&&e.type?"Point"===e.type?u.pointDistance(a,e):u.geometryWithinRadius(e,a,i)?0:i+1:null};else{if(i=t.$maxDistance,!p(e)&&!v(e))throw Error("$near argument must be coordinate pair or GeoJSON");a=O(e),s=function(e){return p(e)||v(e)?E(a,e):null}}return function(e){e=I(e);var t={result:!1};return r.each(e,function(e){var r=s(e.value);null===r||r>i||void 0!==t.distance&&t.distance<=r||(t.result=!0,t.distance=r,e.arrayIndices?t.arrayIndices=e.arrayIndices:delete t.arrayIndices)}),t}}},E=function(e,t){e=O(e),t=O(t);var n=e[0]-t[0],o=e[1]-t[1];return r.isNaN(n)||r.isNaN(o)?null:Math.sqrt(n*n+o*o)},O=function(e){return r.map(e,r.identity)},C=function(e){return{compileElementSelector:function(r){if(p(r))return function(){return!1};void 0===r&&(r=null);var t=d._f._type(r);return function(n){return void 0===n&&(n=null),d._f._type(n)!==t?!1:e(d._f._cmp(n,r))}}}};b={$lt:C(function(e){return 0>e}),$gt:C(function(e){return e>0}),$lte:C(function(e){return 0>=e}),$gte:C(function(e){return e>=0}),$mod:{compileElementSelector:function(e){if(!p(e)||2!==e.length||"number"!=typeof e[0]||"number"!=typeof e[1])throw Error("argument to $mod must be an array of two numbers");var r=e[0],t=e[1];return function(e){return"number"==typeof e&&e%r===t}}},$in:{compileElementSelector:function(e){if(!p(e))throw Error("$in needs an array");var t=[];return r.each(e,function(e){if(e instanceof RegExp)t.push(g(e));else{if(m(e))throw Error("cannot nest $ under $in");t.push(w(e))}}),function(e){return void 0===e&&(e=null),r.any(t,function(r){return r(e)})}}},$size:{dontExpandLeafArrays:!0,compileElementSelector:function(e){if("string"==typeof e)e=0;else if("number"!=typeof e)throw Error("$size needs a number");return function(r){return p(r)&&r.length===e}}},$type:{dontIncludeLeafArrays:!0,compileElementSelector:function(e){if("number"!=typeof e)throw Error("$type needs a number");return function(r){return void 0!==r&&d._f._type(r)===e}}},$regex:{compileElementSelector:function(e,r){if(!("string"==typeof e||e instanceof RegExp))throw Error("$regex has to be a string or RegExp");var t;if(void 0!==r.$options){if(/[^gim]/.test(r.$options))throw new Error("Only the i, m, and g regexp options are supported");var n=e instanceof RegExp?e.source:e;t=new RegExp(n,r.$options)}else t=e instanceof RegExp?e:new RegExp(e);return g(t)}},$elemMatch:{dontExpandLeafArrays:!0,compileElementSelector:function(r,n,o){if(!v(r))throw Error("$elemMatch need an object");var i,a;return m(r,!0)?(i=t(r,o),a=!1):(i=e(r,o,{inElemMatch:!0}),a=!0),function(e){if(!p(e))return!1;for(var r=0;r=2&&y(n[1]),s;n.length>1&&(s=$(n.slice(1).join(".")));var c=function(e){return e.dontIterate||delete e.dontIterate,e.arrayIndices&&!e.arrayIndices.length&&delete e.arrayIndices,e};return function(e,n){if(n||(n=[]),p(e)){if(!(i&&oo?-1:1;if(t!==n)throw Error("Missing type coercion logic in _cmp");if(7===t&&(t=n=2,e=e.toHexString(),r=r.toHexString()),9===t&&(t=n=1,e=e.getTime(),r=r.getTime()),1===t)return e-r;if(2===n)return r>e?-1:e===r?0:1;if(3===t){var a=function(e){var r=[];for(var t in e)r.push(t),r.push(e[t]);return r};return d._f._cmp(a(e),a(r))}if(4===t)for(var s=0;;s++){if(s===e.length)return s===r.length?0:-1;if(s===r.length)return 1;var c=d._f._cmp(e[s],r[s]);if(0!==c)return c}if(5===t){if(e.length!==r.length)return e.length-r.length;for(s=0;sr[s])return 1}return 0}if(8===t)return e?r?0:1:r?-1:0;if(10===t)return 0;if(11===t)throw Error("Sorting not supported on regular expression");if(13===t)throw Error("Sorting not supported on Javascript code");throw Error("Unknown type to sort")}},d._removeDollarOperators=function(e){var r={};for(var t in e)"$"!==t.substr(0,1)&&(r[t]=e[t]);return r}}.call(this),function(){f.Sorter=function(n,o){var i=this;o=o||{},i._sortSpecParts=[];var a=function(e,r){if(!e)throw Error("sort keys must be non-empty");if("$"===e.charAt(0))throw Error("unsupported sort key: "+e);i._sortSpecParts.push({path:e,lookup:$(e,{forSort:!0}),ascending:r})};if(n instanceof Array)for(var s=0;s=0)})}if(i.affectedByModifier){var c={};r.each(i._sortSpecParts,function(e){c[e.path]=1}),i._selectorForAffectedByModifier=new f.Matcher(c)}i._keyComparator=e(r.map(i._sortSpecParts,function(e,r){return i._keyFieldComparator(r)})),i._keyFilter=null,o.matcher&&i._useWithMatcher(o.matcher)},r.extend(f.Sorter.prototype,{getComparator:function(r){var t=this;if(!r||!r.distances)return t._getBaseComparator();var n=r.distances;return e([t._getBaseComparator(),function(e,r){if(!n.has(e._id))throw Error("Missing distance for "+e._id);if(!n.has(r._id))throw Error("Missing distance for "+r._id);return n.get(e._id)-n.get(r._id)}])},_getPaths:function(){var e=this;return r.pluck(e._sortSpecParts,"path")},_getMinKeyFromDoc:function(e){var r=this,t=null;if(r._generateKeysFromDoc(e,function(e){return r._keyCompatibleWithSelector(e)?null===t?void(t=e):void(r._compareKeys(e,t)<0&&(t=e)):void 0}),null===t)throw Error("sort selector found no keys in doc?");return t},_keyCompatibleWithSelector:function(e){var r=this;return!r._keyFilter||r._keyFilter(e)},_generateKeysFromDoc:function(e,t){var n=this;if(0===n._sortSpecParts.length)throw new Error("can't generate keys without a spec");var o=[],i=function(e){return e.join(",")+","},a=null;if(r.each(n._sortSpecParts,function(t,n){var s=I(t.lookup(e),!0);s.length||(s=[{value:null}]);var c=!1;if(o[n]={},r.each(s,function(e){if(!e.arrayIndices){if(s.length>1)throw Error("multiple branches but no array used?");return void(o[n][""]=e.value)}c=!0;var t=i(e.arrayIndices);if(r.has(o[n],t))throw Error("duplicate path: "+t);if(o[n][t]=e.value,a&&!r.has(a,t))throw Error("cannot index parallel arrays")}),a){if(!r.has(o[n],"")&&r.size(a)!==r.size(o[n]))throw Error("cannot index parallel arrays!")}else c&&(a={},r.each(o[n],function(e,r){a[r]=!0}))}),!a){var s=r.map(o,function(e){if(!r.has(e,""))throw Error("no value in sole key case?");return e[""]});return void t(s)}r.each(a,function(e,n){var i=r.map(o,function(e){if(r.has(e,""))return e[""];if(!r.has(e,n))throw Error("missing path?");return e[n]});t(i)})},_compareKeys:function(e,r){var t=this;if(e.length!==t._sortSpecParts.length||r.length!==t._sortSpecParts.length)throw Error("Key has wrong length");return t._keyComparator(e,r)},_keyFieldComparator:function(e){var r=this,t=!r._sortSpecParts[e].ascending;return function(r,n){var o=d._f._cmp(r[e],n[e]);return t&&(o=-o),o}},_getBaseComparator:function(){var e=this;return e._sortSpecParts.length?function(r,t){var n=e._getMinKeyFromDoc(r),o=e._getMinKeyFromDoc(t);return e._compareKeys(n,o)}:function(e,r){return 0}},_useWithMatcher:function(e){var t=this;if(t._keyFilter)throw Error("called _useWithMatcher twice?");if(!r.isEmpty(t._sortSpecParts)){var n=e._selector;if(!(n instanceof Function)){var o={};r.each(t._sortSpecParts,function(e,r){o[e.path]=[]}),r.each(n,function(e,t){var n=o[t];if(n){if(e instanceof RegExp){if(e.ignoreCase||e.multiline)return;return void n.push(g(e))}return m(e)?void r.each(e,function(t,o){r.contains(["$lt","$lte","$gt","$gte"],o)&&n.push(b[o].compileElementSelector(t)),"$regex"!==o||e.$options||n.push(b.$regex.compileElementSelector(t,e))}):void n.push(w(e))}}),r.isEmpty(o[t._sortSpecParts[0].path])||(t._keyFilter=function(e){return r.all(t._sortSpecParts,function(t,n){return r.all(o[t.path],function(r){return r(e[n])})})})}}}});var e=function(e){return function(r,t){for(var n=0;n0&&(1!==t.length||"_id"!==t[0])&&(t=r.reject(t,function(e){return"_id"===e}));var n=null;r.each(t,function(r){var t=!!e[r];if(null===n&&(n=t),n!==t)throw h("You cannot currently mix including and excluding fields.")});var o=O(t,function(e){return n},function(e,r,t){var n=t,o=r;throw h("both "+n+" and "+o+" found in fields option, using both of them may trigger unexpected behavior. Did you mean to use only one of them?")});return{tree:o,including:n}},O=function(e,t,n,o){return o=o||{},r.each(e,function(e){var i=o,a=e.split("."),s=r.all(a.slice(0,-1),function(t,o){if(r.has(i,t)){if(!r.isObject(i[t])&&(i[t]=n(i[t],a.slice(0,o+1).join("."),e),!r.isObject(i[t])))return!1}else i[t]={};return i=i[t],!0});if(s){var c=r.last(a);i[c]=r.has(i,c)?n(i[c],e,e):t(e)}}),o},d._checkSupportedProjection=function(e){if(!r.isObject(e)||r.isArray(e))throw h("fields option must be an object");r.each(e,function(e,t){if(r.contains(t.split("."),"$"))throw h("Minimongo doesn't support $ operator in projections yet.");if(-1===r.indexOf([1,0,!0,!1],e))throw h("Projection values should be one of 1, 0, true, or false")})}}.call(this),function(){d._modify=function(t,a,s){if(s=s||{},!v(a))throw h("Modifier must be an object");var c=m(a),u;if(c)u=n.clone(t),r.each(a,function(t,n){var a=i[n];if(s.isInsert&&"$setOnInsert"===n&&(a=i.$set),!a)throw h("Invalid modifier specified "+n);r.each(t,function(t,i){if(i.length&&"."===i[i.length-1])throw h("Invalid mod field name, may not end in a period");if("_id"===i)throw h("Mod on _id not allowed");var c=i.split("."),d=r.has(o,n),f="$rename"===n,l=e(u,c,{noCreate:o[n],forbidArray:"$rename"===n,arrayIndices:s.arrayIndices}),p=c.pop();a(l,p,t,i,u)})});else{if(a._id&&!n.equals(t._id,a._id))throw h("Cannot change the _id of a document");for(var d in a)if(/\./.test(d))throw h("When replacing document, field name may not contain '.'");u=a}r.each(r.keys(t),function(e){("_id"!==e||s.isInsert)&&delete t[e]}),r.each(u,function(e,r){t[r]=e})};var e=function(e,r,n){n=n||{};for(var o=!1,i=0;i=e.length)return void 0;for(;e.length0)throw h("$slice in $push must be zero or negative");i=t.$slice}var a=void 0;if(t.$sort){if(void 0===i)throw h("$sort requires $slice to be present");a=new f.Sorter(t.$sort).getComparator();for(var s=0;st?n.splice(0,1):n.pop()}}},$pull:function(e,r,t){if(void 0!==e){var n=e[r];if(void 0!==n){if(!(n instanceof Array))throw h("Cannot apply $pull/pullAll modifier to non-array");var o=[];if("object"!=typeof t||t instanceof Array)for(var i=0;iv;v++)if(void 0!==s[o[v]._id]){for(var _=u;_>0&&!(p(l[_-1])u&&(u=_+1)}for(var m=0===u?-1:l[u-1];m>=0;)c.push(m),m=h[m];c.reverse(),c.push(o.length),r.each(t,function(e){a[e._id]||i.removed&&i.removed(e._id)});var y=0;r.each(c,function(e){for(var a=o[e]?o[e]._id:null,c,u,f,l=y;e>l;l++)u=o[l],r.has(s,u._id)?(c=t[s[u._id]],f=d._makeChangedFields(u,c),r.isEmpty(f)||i.changed&&i.changed(u._id,f),i.movedBefore&&i.movedBefore(u._id,a)):(f=n.clone(u),delete f._id,i.addedBefore&&i.addedBefore(u._id,f,a),i.added&&i.added(u._id,f));a&&(u=o[e],c=t[s[u._id]],f=d._makeChangedFields(u,c),r.isEmpty(f)||i.changed&&i.changed(u._id,f)),y=e+1})},d._diffObjects=function(e,t,n){r.each(e,function(e,o){r.has(t,o)?n.both&&n.both(o,e,t[o]):n.leftOnly&&n.leftOnly(o,e)}),n.rightOnly&&r.each(t,function(t,o){r.has(e,o)||n.rightOnly(o,t)})}}.call(this),function(){d._IdMap=function(){var e=this;o.call(e,d._idStringify,d._idParse)},e._inherits(d._IdMap,o)}.call(this),function(){d._CachingChangeObserver=function(e){var t=this;e=e||{};var o=e.callbacks&&d._observeChangesCallbacksAreOrdered(e.callbacks);if(r.has(e,"ordered")){if(t.ordered=e.ordered,e.callbacks&&e.ordered!==o)throw Error("ordered option doesn't match callbacks")}else{if(!e.callbacks)throw Error("must provide ordered or callbacks");t.ordered=o}var a=e.callbacks||{};t.ordered?(t.docs=new i(d._idStringify),t.applyChange={addedBefore:function(e,r,o){var i=n.clone(r);i._id=e,a.addedBefore&&a.addedBefore.call(t,e,r,o),a.added&&a.added.call(t,e,r),t.docs.putBefore(e,i,o||null)},movedBefore:function(e,r){var n=t.docs.get(e);a.movedBefore&&a.movedBefore.call(t,e,r),t.docs.moveBefore(e,r||null)}}):(t.docs=new d._IdMap,t.applyChange={added:function(e,r){var o=n.clone(r);a.added&&a.added.call(t,e,r),o._id=e,t.docs.set(e,o)}}),t.applyChange.changed=function(e,r){var o=t.docs.get(e);if(!o)throw new Error("Unknown id for changed: "+e);a.changed&&a.changed.call(t,e,n.clone(r)),d._applyChanges(o,r)},t.applyChange.removed=function(e){a.removed&&a.removed.call(t,e),t.docs.remove(e)}},d._observeFromObserveChanges=function(e,t){var o=e.getTransform()||function(e){return e},i=!!t._suppress_initial,a;if(d._observeCallbacksAreOrdered(t)){var s=!t._no_indices;a={addedBefore:function(e,n,a){var c=this;if(!i&&(t.addedAt||t.added)){var u=o(r.extend(n,{_id:e}));if(t.addedAt){var d=s?a?c.docs.indexOf(a):c.docs.size():-1;t.addedAt(u,d,a)}else t.added(u)}},changed:function(e,r){var i=this;if(t.changedAt||t.changed){var a=n.clone(i.docs.get(e));if(!a)throw new Error("Unknown id for changed: "+e);var c=o(n.clone(a));if(d._applyChanges(a,r),a=o(a),t.changedAt){var u=s?i.docs.indexOf(e):-1;t.changedAt(a,c,u)}else t.changed(a,c)}},movedBefore:function(e,r){var i=this;if(t.movedTo){var a=s?i.docs.indexOf(e):-1,c=s?r?i.docs.indexOf(r):i.docs.size():-1;c>a&&--c,t.movedTo(o(n.clone(i.docs.get(e))),a,c,r||null)}},removed:function(e){var r=this;if(t.removedAt||t.removed){var n=o(r.docs.get(e));if(t.removedAt){var i=s?r.docs.indexOf(e):-1;t.removedAt(n,i)}else t.removed(n)}}}}else a={added:function(e,n){if(!i&&t.added){var a=r.extend(n,{_id:e});t.added(o(a))}},changed:function(e,r){var i=this;if(t.changed){var a=i.docs.get(e),s=n.clone(a);d._applyChanges(s,r),t.changed(o(s),o(n.clone(a)))}},removed:function(e){var r=this;t.removed&&t.removed(o(r.docs.get(e)))}};var c=new d._CachingChangeObserver({callbacks:a}),u=e.observeChanges(c.applyChange);return i=!1,u}}.call(this),function(){d._looksLikeObjectID=function(e){return 24===e.length&&e.match(/^[0-9a-f]*$/)},d._ObjectID=function(e){var r=this;if(e){if(e=e.toLowerCase(),!d._looksLikeObjectID(e))throw new Error("Invalid hexadecimal string for creating an ObjectID");r._str=e}else r._str=c.hexString(24)},d._ObjectID.prototype.toString=function(){var e=this;return'ObjectID("'+e._str+'")'},d._ObjectID.prototype.equals=function(e){var r=this;return e instanceof d._ObjectID&&r.valueOf()===e.valueOf()},d._ObjectID.prototype.clone=function(){var e=this;return new d._ObjectID(e._str)},d._ObjectID.prototype.typeName=function(){return"oid"},d._ObjectID.prototype.getTimestamp=function(){var e=this;return parseInt(e._str.substr(0,8),16)},d._ObjectID.prototype.valueOf=d._ObjectID.prototype.toJSONValue=d._ObjectID.prototype.toHexString=function(){return this._str},d._selectorIsId=function(e){return"string"==typeof e||"number"==typeof e||e instanceof d._ObjectID},d._selectorIsIdPerhapsAsObject=function(e){return d._selectorIsId(e)||e&&"object"==typeof e&&e._id&&d._selectorIsId(e._id)&&1===r.size(e)},d._idsMatchedBySelector=function(e){if(d._selectorIsId(e))return[e];if(!e)return null;if(r.has(e,"_id"))return d._selectorIsId(e._id)?[e._id]:e._id&&e._id.$in&&r.isArray(e._id.$in)&&!r.isEmpty(e._id.$in)&&r.all(e._id.$in,d._selectorIsId)?e._id.$in:null;if(e.$and&&r.isArray(e.$and))for(var t=0;t1?this._listeners[e]=r.slice(0,o).concat(r.slice(o+1)):delete this._listeners[e]):void 0}},r.prototype.dispatchEvent=function(e){var t=e.type,n=Array.prototype.slice.call(arguments,0);if(this["on"+t]&&this["on"+t].apply(this,n),this._listeners&&t in this._listeners)for(var r=0;rn;n++)r.push(s.substr(Math.floor(Math.random()*t),1));return r.join("")},n.random_number=function(e){return Math.floor(Math.random()*e)},n.random_number_string=function(e){var t=(""+(e-1)).length,r=Array(t+1).join("0");return(r+n.random_number(e)).slice(-t)},n.getOrigin=function(e){e+="/";var t=e.split("/").slice(0,3);return t.join("/")},n.isSameOriginUrl=function(e,n){return n||(n=t.location.href),e.split("/").slice(0,3).join("/")===n.split("/").slice(0,3).join("/")},n.isSameOriginScheme=function(e,n){return n||(n=t.location.href),e.split(":")[0]===n.split(":")[0]},n.getParentDomain=function(e){if(/^[0-9.]*$/.test(e))return e;if(/^\[/.test(e))return e;if(!/[.]/.test(e))return e;var t=e.split(".").slice(1);return t.join(".")},n.objectExtend=function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e};var u="_jp";n.polluteGlobalNamespace=function(){u in t||(t[u]={})},n.closeFrame=function(e,t){return"c"+i.stringify([e,t])},n.userSetCode=function(e){return 1e3===e||e>=3e3&&4999>=e},n.countRTO=function(e){var t;return t=e>100?3*e:e+200},n.log=function(){t.console&&console.log&&console.log.apply&&console.log.apply(console,arguments)},n.bind=function(e,t){return e.bind?e.bind(t):function(){return e.apply(t,arguments)}},n.flatUrl=function(e){return-1===e.indexOf("?")&&-1===e.indexOf("#")},n.amendUrl=function(t,r){var o;if(void 0===r)o=e.location;else{var i=/^([a-z0-9.+-]+:)/i.exec(r);if(i){var a=i[0].toLowerCase(),s=r.substring(a.length),u=/[a-z0-9\.-]+(:[0-9]+)?/.exec(s);if(u)var c=u[0]}if(!a||!c)throw new Error("relativeTo must be an absolute url");o={protocol:a,host:c}}if(!t)throw new Error("Wrong url for SockJS");if(!n.flatUrl(t))throw new Error("Only basic urls are supported in SockJS");0===t.indexOf("//")&&(t=o.protocol+t),0===t.indexOf("/")&&(t=o.protocol+"//"+o.host+t),t=t.replace(/[/]+$/,"");var l=t.split("/");return("http:"===l[0]&&/:80$/.test(l[2])||"https:"===l[0]&&/:443$/.test(l[2]))&&(l[2]=l[2].replace(/:(80|443)$/,"")),t=l.join("/")},n.arrIndexOf=function(e,t){for(var n=0;n=0},n.delay=function(e,t){return"function"==typeof e&&(t=e,e=0),setTimeout(t,e)};var c=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,l={"\x00":"\\u0000","":"\\u0001","":"\\u0002","":"\\u0003","":"\\u0004","":"\\u0005","":"\\u0006","":"\\u0007","\b":"\\b"," ":"\\t","\n":"\\n"," ":"\\u000b","\f":"\\f","\r":"\\r","":"\\u000e","":"\\u000f","":"\\u0010","":"\\u0011","":"\\u0012","":"\\u0013","":"\\u0014","":"\\u0015","":"\\u0016","":"\\u0017","":"\\u0018","":"\\u0019","":"\\u001a","":"\\u001b","":"\\u001c","":"\\u001d","":"\\u001e","":"\\u001f",'"':'\\"',"\\":"\\\\","":"\\u007f","€":"\\u0080","":"\\u0081","‚":"\\u0082","ƒ":"\\u0083","„":"\\u0084","…":"\\u0085","†":"\\u0086","‡":"\\u0087","ˆ":"\\u0088","‰":"\\u0089","Š":"\\u008a","‹":"\\u008b","Œ":"\\u008c","":"\\u008d","Ž":"\\u008e","":"\\u008f","":"\\u0090","‘":"\\u0091","’":"\\u0092","“":"\\u0093","”":"\\u0094","•":"\\u0095","–":"\\u0096","—":"\\u0097","˜":"\\u0098","™":"\\u0099","š":"\\u009a","›":"\\u009b","œ":"\\u009c","":"\\u009d","ž":"\\u009e","Ÿ":"\\u009f","­":"\\u00ad","؀":"\\u0600","؁":"\\u0601","؂":"\\u0602","؃":"\\u0603","؄":"\\u0604","܏":"\\u070f","឴":"\\u17b4","឵":"\\u17b5","‌":"\\u200c","‍":"\\u200d","‎":"\\u200e","‏":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029","‪":"\\u202a","‫":"\\u202b","‬":"\\u202c","‭":"\\u202d","‮":"\\u202e"," ":"\\u202f","⁠":"\\u2060","⁡":"\\u2061","⁢":"\\u2062","⁣":"\\u2063","⁤":"\\u2064","⁥":"\\u2065","⁦":"\\u2066","⁧":"\\u2067","⁨":"\\u2068","⁩":"\\u2069","":"\\u206a","":"\\u206b","":"\\u206c","":"\\u206d","":"\\u206e","":"\\u206f","":"\\ufeff","￰":"\\ufff0","￱":"\\ufff1","￲":"\\ufff2","￳":"\\ufff3","￴":"\\ufff4","￵":"\\ufff5","￶":"\\ufff6","￷":"\\ufff7","￸":"\\ufff8","":"\\ufff9","":"\\ufffa","":"\\ufffb","":"\\ufffc","�":"\\ufffd","￾":"\\ufffe","￿":"\\uffff"},d=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,f,_=i&&i.stringify||function(e){return c.lastIndex=0,c.test(e)&&(e=e.replace(c,function(e){return l[e]})),'"'+e+'"'},p=function(e){var t,n={},r=[];for(t=0;65536>t;t++)r.push(String.fromCharCode(t));return e.lastIndex=0,r.join("").replace(e,function(e){return n[e]="\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4),""}),e.lastIndex=0,n};n.quote=function(e){var t=_(e);return d.lastIndex=0,d.test(t)?(f||(f=p(d)),t.replace(d,function(e){return f[e]})):t};var h=["websocket","xdr-streaming","xhr-streaming","iframe-eventsource","iframe-htmlfile","xdr-polling","xhr-polling","iframe-xhr-polling","jsonp-polling"];n.probeProtocols=function(){for(var e={},t=0;t0&&s(e)};return n.websocket!==!1&&s(["websocket"]),r["xhr-streaming"]&&!n.null_origin?o.push("xhr-streaming"):!r["xdr-streaming"]||n.cookie_needed||n.null_origin?s(["iframe-eventsource","iframe-htmlfile"]):o.push("xdr-streaming"),r["xhr-polling"]&&!n.null_origin?o.push("xhr-polling"):!r["xdr-polling"]||n.cookie_needed||n.null_origin?s(["iframe-xhr-polling","jsonp-polling"]):o.push("xdr-polling"),o};var v="_sockjs_global";n.createHook=function(){var e="a"+n.random_string(8);if(!(v in t)){var r={};t[v]=function(e){return e in r||(r[e]={id:e,del:function(){delete r[e]}}),r[e]}}return t[v](e)},n.attachMessage=function(e){n.attachEvent("message",e)},n.attachEvent=function(n,r){"undefined"!=typeof t.addEventListener?t.addEventListener(n,r,!1):(e.attachEvent("on"+n,r),t.attachEvent("on"+n,r))},n.detachMessage=function(e){n.detachEvent("message",e)},n.detachEvent=function(n,r){"undefined"!=typeof t.addEventListener?t.removeEventListener(n,r,!1):(e.detachEvent("on"+n,r),t.detachEvent("on"+n,r))};var m={},g=!1,b=function(){for(var e in m)m[e](),delete m[e]},y=function(){g||(g=!0,b())};n.attachEvent("unload",y),n.unload_add=function(e){var t=n.random_string(8);return m[t]=e,g&&n.delay(b),t},n.unload_del=function(e){e in m&&delete m[e]},n.createIframe=function(t,r){var o=e.createElement("iframe"),i,a,s=function(){clearTimeout(i);try{o.onload=null}catch(e){}o.onerror=null},u=function(){o&&(s(),setTimeout(function(){o&&o.parentNode.removeChild(o),o=null},0),n.unload_del(a))},c=function(e){o&&(u(),r(e))},l=function(e,t){try{o&&o.contentWindow&&o.contentWindow.postMessage(e,t)}catch(n){}};return o.src=t,o.style.display="none",o.style.position="absolute",o.onerror=function(){c("onerror")},o.onload=function(){clearTimeout(i),i=setTimeout(function(){c("onload timeout")},2e3)},e.body.appendChild(o),i=setTimeout(function(){c("timeout")},15e3),a=n.unload_add(u),{post:l,cleanup:u,loaded:s}},n.createHtmlfile=function(e,r){var o=new ActiveXObject("htmlfile"),i,a,s,c=function(){clearTimeout(i)},l=function(){o&&(c(),n.unload_del(a),s.parentNode.removeChild(s),s=o=null,CollectGarbage())},d=function(e){o&&(l(),r(e))},f=function(e,t){try{s&&s.contentWindow&&s.contentWindow.postMessage(e,t)}catch(n){}};o.open(),o.write(''),o.close(),o.parentWindow[u]=t[u];var _=o.createElement("div");return o.body.appendChild(_),s=o.createElement("iframe"),_.appendChild(s),s.src=e,i=setTimeout(function(){d("timeout")},15e3),a=n.unload_add(l),{post:f,cleanup:l,loaded:c}};var w=function(){};w.prototype=new a(["chunk","finish"]),w.prototype._start=function(e,r,o,i){var a=this;try{a.xhr=new XMLHttpRequest}catch(s){}if(!a.xhr)try{a.xhr=new t.ActiveXObject("Microsoft.XMLHTTP")}catch(s){}(t.ActiveXObject||t.XDomainRequest)&&(r+=(-1===r.indexOf("?")?"?":"&")+"t="+ +new Date),a.unload_ref=n.unload_add(function(){a._cleanup(!0)});try{a.xhr.open(e,r,!0)}catch(u){return a.emit("finish",0,""),void a._cleanup()}if(i&&i.no_credentials||(a.xhr.withCredentials="true"),i&&i.headers)for(var c in i.headers)a.xhr.setRequestHeader(c,i.headers[c]);a.xhr.onreadystatechange=function(){if(a.xhr){var e=a.xhr;switch(e.readyState){case 3:try{var t=e.status,n=e.responseText}catch(e){}1223===t&&(t=204),n&&n.length>0&&a.emit("chunk",t,n);break;case 4:var t=e.status;1223===t&&(t=204),a.emit("finish",t,e.responseText),a._cleanup(!1)}}},a.xhr.send(o)},w.prototype._cleanup=function(e){var t=this;if(t.xhr){if(n.unload_del(t.unload_ref),t.xhr.onreadystatechange=function(){},e)try{t.xhr.abort()}catch(r){}t.unload_ref=t.xhr=null}},w.prototype.close=function(){var e=this;e.nuke(),e._cleanup(!0)};var k=n.XHRCorsObject=function(){var e=this,t=arguments;n.delay(function(){e._start.apply(e,t)})};k.prototype=new w;var S=n.XHRLocalObject=function(e,t,r){var o=this;n.delay(function(){o._start(e,t,r,{no_credentials:!0})})};S.prototype=new w;var C=n.XDRObject=function(e,t,r){var o=this;n.delay(function(){o._start(e,t,r)})};C.prototype=new a(["chunk","finish"]),C.prototype._start=function(e,t,r){var o=this,i=new XDomainRequest;t+=(-1===t.indexOf("?")?"?":"&")+"t="+ +new Date;var a=i.ontimeout=i.onerror=function(){o.emit("finish",0,""),o._cleanup(!1)};i.onprogress=function(){o.emit("chunk",200,i.responseText)},i.onload=function(){o.emit("finish",200,i.responseText),o._cleanup(!1)},o.xdr=i,o.unload_ref=n.unload_add(function(){o._cleanup(!0)});try{o.xdr.open(e,t),o.xdr.send(r)}catch(s){a()}},C.prototype._cleanup=function(e){var t=this;if(t.xdr){if(n.unload_del(t.unload_ref),t.xdr.ontimeout=t.xdr.onerror=t.xdr.onprogress=t.xdr.onload=null,e)try{t.xdr.abort()}catch(r){}t.unload_ref=t.xdr=null}},C.prototype.close=function(){var e=this;e.nuke(),e._cleanup(!0)},n.isXHRCorsCapable=function(){return t.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest?1:t.XDomainRequest&&e.domain?2:B.enabled()?3:4};var T=function(e,t,r){if(!(this instanceof T))return new T(e,t,r);var o=this,i;o._options={devel:!1,debug:!1,protocols_whitelist:[],info:void 0,rtt:void 0},r&&n.objectExtend(o._options,r),o._base_url=n.amendUrl(e),o._server=o._options.server||n.random_number_string(1e3),o._options.protocols_whitelist&&o._options.protocols_whitelist.length?i=o._options.protocols_whitelist:(i="string"==typeof t&&t.length>0?[t]:n.isArray(t)?t:null,i&&o._debug('Deprecated API: Use "protocols_whitelist" option instead of supplying protocol list as a second parameter to SockJS constructor.')),o._protocols=[],o.protocol=null,o.readyState=T.CONNECTING,o._ir=q(o._base_url),o._ir.onfinish=function(e,t){o._ir=null,e?(o._options.info&&(e=n.objectExtend(e,o._options.info)),o._options.rtt&&(t=o._options.rtt),o._applyInfo(e,t,i),o._didClose()):o._didClose(1002,"Can't connect to server",!0)}};T.prototype=new r,T.version="0.3.4",T.CONNECTING=0,T.OPEN=1,T.CLOSING=2,T.CLOSED=3,T.prototype._debug=function(){this._options.debug&&n.log.apply(n,arguments)},T.prototype._dispatchOpen=function(){var e=this;e.readyState===T.CONNECTING?(e._transport_tref&&(clearTimeout(e._transport_tref),e._transport_tref=null),e.readyState=T.OPEN,e.dispatchEvent(new o("open"))):e._didClose(1006,"Server lost session")},T.prototype._dispatchMessage=function(e){var t=this;t.readyState===T.OPEN&&t.dispatchEvent(new o("message",{data:e}))},T.prototype._dispatchHeartbeat=function(e){var t=this;t.readyState===T.OPEN&&t.dispatchEvent(new o("heartbeat",{}))},T.prototype._didClose=function(e,t,r){var i=this;if(i.readyState!==T.CONNECTING&&i.readyState!==T.OPEN&&i.readyState!==T.CLOSING)throw new Error("INVALID_STATE_ERR");i._ir&&(i._ir.nuke(),i._ir=null),i._transport&&(i._transport.doCleanup(),i._transport=null);var a=new o("close",{code:e,reason:t,wasClean:n.userSetCode(e)});if(!n.userSetCode(e)&&i.readyState===T.CONNECTING&&!r){if(i._try_next_protocol(a))return;a=new o("close",{code:2e3,reason:"All transports failed",wasClean:!1,last_event:a})}i.readyState=T.CLOSED,n.delay(function(){i.dispatchEvent(a)})},T.prototype._didMessage=function(e){var t=this,n=e.slice(0,1);switch(n){case"o":t._dispatchOpen();break;case"a":for(var r=i.parse(e.slice(1)||"[]"),o=0;o0){var t="["+e.send_buffer.join(",")+"]";e.send_stop=e.sender(e.trans_url,t,function(t,n){e.send_stop=null,t===!1?e.ri._didClose(1006,"Sending error "+n):e.send_schedule_wait()}),e.send_buffer=[]}},O.prototype.send_destructor=function(){var e=this;e._send_stop&&e._send_stop(),e._send_stop=null};var x=function(t,r,o){var i=this;if(!("_send_form"in i)){var a=i._send_form=e.createElement("form"),s=i._send_area=e.createElement("textarea");s.name="d",a.style.display="none",a.style.position="absolute",a.method="POST",a.enctype="application/x-www-form-urlencoded",a.acceptCharset="UTF-8",a.appendChild(s),e.body.appendChild(a)}var a=i._send_form,s=i._send_area,u="a"+n.random_string(8);a.target=u,a.action=t+"/jsonp_send?i="+u;var c;try{c=e.createElement('')]}),Meteor.startup(Template.body.renderToDocument)}(); - -!function(){Template.__checkName("layout_main"),Template.layout_main=new Template("Template.layout_main",function(){var n=this;return[HTML.Raw(' \n '),HTML.DIV({"class":"dapp-flex-content"},"\n\n ",HTML.Raw(""),"\n ",HTML.MAIN({"class":"dapp-content"},"\n ",Spacebars.include(n.lookupTemplate("views_home")),"\n "),"\n\n ")]})}(); - -!function(){Helpers={},Helpers.rerun={"10s":new ReactiveTimer(10)},Helpers.getLocalStorageSize=function(){var e=0;return localStorage&&_.each(Object.keys(localStorage),function(n){e+=2*localStorage[n].length/1024/1024}),e},Helpers.moment=function(e){return TAPi18n.getLanguage(),_.isFinite(e)&&moment.unix(e).isValid()?moment.unix(e):moment(e)},Helpers.formatTime=function(e,n){return n instanceof Spacebars.kw&&(n=null),e?(_.isString(n)&&!_.isEmpty(n)&&("iso"===n.toLowerCase()?e=Helpers.moment(e).toISOString():"fromnow"===n.toLowerCase()?(Helpers.rerun["10s"].tick(),e=Helpers.moment(e).fromNow()):e=Helpers.moment(e).format(n)),e):""}}(); - -!function(){Template.registerHelper("debug",function(e){console.log(e)}),Template.registerHelper("username",function(e){var t=Users.findOne(e);return Whisper.getIdentity().identity===e?Whisper.getIdentity().name:t?t.name:"anonymous"}),Template.registerHelper("currentIdentity",function(e){return Whisper.getIdentity()}),Template.registerHelper("formatTime",Helpers.formatTime)}(); - -!function(){!function(){function a(e){if(!(this instanceof a))return new a(e);if("function"==typeof e)return this.random=e,this;var n;arguments.length&&(this.seed=0);for(var i=0;ii;i++)key=n[i],e[key]=a[key]||e[key]}function r(a,e){for(var n=0,i=a.length;i>n;n++)e[n]=a[n]}function o(a,e){var n=Array.isArray(a),i=e||(n?new Array(a.length):{});return n?r(a,i):t(a,i),i}var s=9007199254740992,m=-s,l="0123456789",b="abcdefghijklmnopqrstuvwxyz",h=b.toUpperCase(),c=l+"abcdef",u=Array.prototype.slice;a.prototype.VERSION="0.7.1";var d=function(){throw new Error("No Base64 encoder available.")};!function(){"function"==typeof btoa?d=btoa:"function"==typeof Buffer&&(d=function(a){return new Buffer(a).toString("base64")})}(),a.prototype.bool=function(a){return a=e(a,{likelihood:50}),n(a.likelihood<0||a.likelihood>100,"Chance: Likelihood accepts values from 0 to 100."),100*this.random()r,"Chance: Max specified is out of range with fixed. Max should be, at most, "+r),a=e(a,{min:o,max:r}),i=this.integer({min:a.min*t,max:a.max*t});var m=(i/t).toFixed(a.fixed);return parseFloat(m)},a.prototype.integer=function(a){return a=e(a,{min:m,max:s}),n(a.min>a.max,"Chance: Min cannot be greater than Max."),Math.floor(this.random()*(a.max-a.min+1)+a.min)},a.prototype.natural=function(a){return a=e(a,{min:0,max:s}),this.integer(a)},a.prototype.string=function(a){a=e(a);var n=a.length||this.natural({min:5,max:20}),i=a.pool,t=this.n(this.character,n,{pool:i});return t.join("")},a.prototype.capitalize=function(a){return a.charAt(0).toUpperCase()+a.substr(1)},a.prototype.mixin=function(e){for(var n in e)a.prototype[n]=e[n];return this},a.prototype.unique=function(a,n,i){i=e(i,{comparator:function(a,e){return-1!==a.indexOf(e)}});for(var t,r=[],o=0,s=50*n,m=u.call(arguments,2);r.lengths)throw new RangeError("Chance: num is likely too large for sample set");return r},a.prototype.n=function(a,e){var n=e||1,i=[],t=u.call(arguments,2);for(n=Math.max(0,n),null;n--;null)i.push(a.apply(this,t));return i},a.prototype.pad=function(a,e,n){return n=n||"0",a+="",a.length>=e?a:new Array(e-a.length+1).join(n)+a},a.prototype.pick=function(a,e){if(0===a.length)throw new RangeError("Chance: Cannot pick() from an empty array");return e&&1!==e?this.shuffle(a).slice(0,e):a[this.natural({max:a.length-1})]},a.prototype.shuffle=function(a){for(var e=a.slice(0),n=[],i=0,t=Number(e.length),r=0;t>r;r++)i=this.natural({max:e.length-1}),n[r]=e[i],e.splice(i,1);return n},a.prototype.weighted=function(a,e){if(a.length!==e.length)throw new RangeError("Chance: length of array and weights must match");if(e.some(function(a){return 1>a})){var n=e.reduce(function(a,e){return a>e?e:a},e[0]),i=1/n;e=e.map(function(a){return a*i})}var t,r=e.reduce(function(a,e){return a+e},0),o=this.natural({min:1,max:r}),s=0;return e.some(function(e,n){return s+e>=o?(t=a[n],!0):(s+=e,!1)}),t},a.prototype.paragraph=function(a){a=e(a);var n=a.sentences||this.natural({min:3,max:7}),i=this.n(this.sentence,n);return i.join(" ")},a.prototype.sentence=function(a){a=e(a);var n,i=a.words||this.natural({min:12,max:18}),t=this.n(this.word,i);return n=t.join(" "),n=this.capitalize(n)+"."},a.prototype.syllable=function(a){a=e(a);for(var n,i=a.length||this.natural({min:2,max:3}),t="bcdfghjklmnprstvwz",r="aeiou",o=t+r,s="",m=0;i>m;m++)n=this.character(0===m?{pool:o}:-1===t.indexOf(n)?{pool:t}:{pool:r}),s+=n;return s},a.prototype.word=function(a){a=e(a),n(a.syllables&&a.length,"Chance: Cannot specify both syllables AND length.");var i=a.syllables||this.natural({min:1,max:3}),t="";if(a.length){do t+=this.syllable();while(t.lengthr;r++)t+=this.syllable();return t},a.prototype.age=function(a){a=e(a);var n;switch(a.type){case"child":n={min:1,max:12};break;case"teen":n={min:13,max:19};break;case"adult":n={min:18,max:65};break;case"senior":n={min:65,max:100};break;case"all":n={min:1,max:100};break;default:n={min:18,max:65}}return this.natural(n)},a.prototype.birthday=function(a){return a=e(a,{year:(new Date).getFullYear()-this.age(a)}),this.date(a)},a.prototype.cpf=function(){var a=this.n(this.natural,9,{max:9}),e=2*a[8]+3*a[7]+4*a[6]+5*a[5]+6*a[4]+7*a[3]+8*a[2]+9*a[1]+10*a[0];e=11-e%11,e>=10&&(e=0);var n=2*e+3*a[8]+4*a[7]+5*a[6]+6*a[5]+7*a[4]+8*a[3]+9*a[2]+10*a[1]+11*a[0];return n=11-n%11,n>=10&&(n=0),""+a[0]+a[1]+a[2]+"."+a[3]+a[4]+a[5]+"."+a[6]+a[7]+a[8]+"-"+e+n},a.prototype.first=function(a){return a=e(a,{gender:this.gender()}),this.pick(this.get("firstNames")[a.gender.toLowerCase()])},a.prototype.gender=function(){return this.pick(["Male","Female"])},a.prototype.last=function(){return this.pick(this.get("lastNames"))},a.prototype.name=function(a){a=e(a);var n,i=this.first(a),t=this.last();return n=a.middle?i+" "+this.first(a)+" "+t:a.middle_initial?i+" "+this.character({alpha:!0,casing:"upper"})+". "+t:i+" "+t,a.prefix&&(n=this.prefix(a)+" "+n),a.suffix&&(n=n+" "+this.suffix(a)),n},a.prototype.name_prefixes=function(a){a=a||"all",a=a.toLowerCase();var e=[{name:"Doctor",abbreviation:"Dr."}];return("male"===a||"all"===a)&&e.push({name:"Mister",abbreviation:"Mr."}),("female"===a||"all"===a)&&(e.push({name:"Miss",abbreviation:"Miss"}),e.push({name:"Misses",abbreviation:"Mrs."})),e},a.prototype.prefix=function(a){return this.name_prefix(a)},a.prototype.name_prefix=function(a){return a=e(a,{gender:"all"}),a.full?this.pick(this.name_prefixes(a.gender)).name:this.pick(this.name_prefixes(a.gender)).abbreviation},a.prototype.ssn=function(a){a=e(a,{ssnFour:!1,dashes:!0});var n,i="1234567890",t=a.dashes?"-":"";return n=a.ssnFour?this.string({pool:i,length:4}):this.string({pool:i,length:3})+t+this.string({pool:i,length:2})+t+this.string({pool:i,length:4})},a.prototype.name_suffixes=function(){var a=[{name:"Doctor of Osteopathic Medicine",abbreviation:"D.O."},{name:"Doctor of Philosophy",abbreviation:"Ph.D."},{name:"Esquire",abbreviation:"Esq."},{name:"Junior",abbreviation:"Jr."},{name:"Juris Doctor",abbreviation:"J.D."},{name:"Master of Arts",abbreviation:"M.A."},{name:"Master of Business Administration",abbreviation:"M.B.A."},{name:"Master of Science",abbreviation:"M.S."},{name:"Medical Doctor",abbreviation:"M.D."},{name:"Senior",abbreviation:"Sr."},{name:"The Third",abbreviation:"III"},{name:"The Fourth",abbreviation:"IV"}];return a},a.prototype.suffix=function(a){return this.name_suffix(a)},a.prototype.name_suffix=function(a){return a=e(a),a.full?this.pick(this.name_suffixes()).name:this.pick(this.name_suffixes()).abbreviation},a.prototype.android_id=function(){return"APA91"+this.string({pool:"0123456789abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_",length:178})},a.prototype.apple_token=function(){return this.string({pool:"abcdef1234567890",length:64})},a.prototype.wp8_anid2=function(){return d(this.hash({length:32}))},a.prototype.wp7_anid=function(){return"A="+this.guid().replace(/-/g,"").toUpperCase()+"&E="+this.hash({length:3})+"&W="+this.integer({min:0,max:9})},a.prototype.bb_pin=function(){return this.hash({length:8})},a.prototype.color=function(a){function n(a,e){return[a,a,a].join(e||"")}a=e(a,{format:this.pick(["hex","shorthex","rgb","0x"]),grayscale:!1,casing:"lower"});var i,t=a.grayscale;if("hex"===a.format)i="#"+(t?n(this.hash({length:2})):this.hash({length:6}));else if("shorthex"===a.format)i="#"+(t?n(this.hash({length:1})):this.hash({length:3}));else if("rgb"===a.format)i=t?"rgb("+n(this.natural({max:255}),",")+")":"rgb("+this.natural({max:255})+","+this.natural({max:255})+","+this.natural({max:255})+")";else{if("0x"!==a.format)throw new Error('Invalid format provided. Please provide one of "hex", "shorthex", "rgb" or "0x".');i="0x"+(t?n(this.hash({length:2})):this.hash({length:6}))}return"upper"===a.casing&&(i=i.toUpperCase()),i},a.prototype.domain=function(a){return a=e(a),this.word()+"."+(a.tld||this.tld())},a.prototype.email=function(a){return a=e(a),this.word({length:a.length})+"@"+(a.domain||this.domain())},a.prototype.fbid=function(){return parseInt("10000"+this.natural({max:1e11}),10)},a.prototype.google_analytics=function(){var a=this.pad(this.natural({max:999999}),6),e=this.pad(this.natural({max:99}),2);return"UA-"+a+"-"+e},a.prototype.hashtag=function(){return"#"+this.word()},a.prototype.ip=function(){return this.natural({max:255})+"."+this.natural({max:255})+"."+this.natural({max:255})+"."+this.natural({max:255})},a.prototype.ipv6=function(){var a=this.n(this.hash,8,{length:4});return a.join(":")},a.prototype.klout=function(){return this.natural({min:1,max:99})},a.prototype.tlds=function(){return["com","org","edu","gov","co.uk","net","io"]},a.prototype.tld=function(){return this.pick(this.tlds())},a.prototype.twitter=function(){return"@"+this.word()},a.prototype.url=function(a){a=e(a,{protocol:"http",domain:this.domain(a),domain_prefix:"",path:this.word(),extensions:[]});var n=a.extensions.length>0?"."+this.pick(a.extensions):"",i=a.domain_prefix?a.domain_prefix+"."+a.domain:a.domain;return a.protocol+"://"+i+"/"+a.path+n},a.prototype.address=function(a){return a=e(a),this.natural({min:5,max:2e3})+" "+this.street(a)},a.prototype.altitude=function(a){return a=e(a,{fixed:5,max:8848}),this.floating({min:0,max:a.max,fixed:a.fixed})},a.prototype.areacode=function(a){a=e(a,{parens:!0});var n=this.natural({min:2,max:9}).toString()+this.natural({min:0,max:8}).toString()+this.natural({min:0,max:9}).toString();return a.parens?"("+n+")":n},a.prototype.city=function(){return this.capitalize(this.word({syllables:3}))},a.prototype.coordinates=function(a){return a=e(a),this.latitude(a)+", "+this.longitude(a)},a.prototype.countries=function(){return this.get("countries")},a.prototype.country=function(a){a=e(a);var n=this.pick(this.countries());return a.full?n.name:n.abbreviation},a.prototype.depth=function(a){return a=e(a,{fixed:5,min:-2550}),this.floating({min:a.min,max:0,fixed:a.fixed})},a.prototype.geohash=function(a){return a=e(a,{length:7}),this.string({length:a.length,pool:"0123456789bcdefghjkmnpqrstuvwxyz"})},a.prototype.geojson=function(a){return a=e(a),this.latitude(a)+", "+this.longitude(a)+", "+this.altitude(a)},a.prototype.latitude=function(a){return a=e(a,{fixed:5,min:-90,max:90}),this.floating({min:a.min,max:a.max,fixed:a.fixed})},a.prototype.longitude=function(a){return a=e(a,{fixed:5,min:-180,max:180}),this.floating({min:a.min,max:a.max,fixed:a.fixed})},a.prototype.phone=function(a){var n,i=this,t=function(a){var e=[];return a.sections.forEach(function(a){e.push(i.string({pool:"0123456789",length:a}))}),a.area+e.join(" ")};a=e(a,{formatted:!0,country:"us",mobile:!1}),a.formatted||(a.parens=!1);var r;switch(a.country){case"fr":a.mobile?(n=this.pick(["06","07"])+i.string({pool:"0123456789",length:8}),r=a.formatted?n.match(/../g).join(" "):n):(n=this.pick(["01"+this.pick(["30","34","39","40","41","42","43","44","45","46","47","48","49","53","55","56","58","60","64","69","70","72","73","74","75","76","77","78","79","80","81","82","83"])+i.string({pool:"0123456789",length:6}),"02"+this.pick(["14","18","22","23","28","29","30","31","32","33","34","35","36","37","38","40","41","43","44","45","46","47","48","49","50","51","52","53","54","56","57","61","62","69","72","76","77","78","85","90","96","97","98","99"])+i.string({pool:"0123456789",length:6}),"03"+this.pick(["10","20","21","22","23","24","25","26","27","28","29","39","44","45","51","52","54","55","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","80","81","82","83","84","85","86","87","88","89","90"])+i.string({pool:"0123456789",length:6}),"04"+this.pick(["11","13","15","20","22","26","27","30","32","34","37","42","43","44","50","56","57","63","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","88","89","90","91","92","93","94","95","97","98"])+i.string({pool:"0123456789",length:6}),"05"+this.pick(["08","16","17","19","24","31","32","33","34","35","40","45","46","47","49","53","55","56","57","58","59","61","62","63","64","65","67","79","81","82","86","87","90","94"])+i.string({pool:"0123456789",length:6}),"09"+i.string({pool:"0123456789",length:8})]),r=a.formatted?n.match(/../g).join(" "):n);break;case"uk":a.mobile?(n=this.pick([{area:"07"+this.pick(["4","5","7","8","9"]),sections:[2,6]},{area:"07624 ",sections:[6]}]),r=a.formatted?t(n):t(n).replace(" ","")):(n=this.pick([{area:"01"+this.character({pool:"234569"})+"1 ",sections:[3,4]},{area:"020 "+this.character({pool:"378"}),sections:[3,4]},{area:"023 "+this.character({pool:"89"}),sections:[3,4]},{area:"024 7",sections:[3,4]},{area:"028 "+this.pick(["25","28","37","71","82","90","92","95"]),sections:[2,4]},{area:"012"+this.pick(["04","08","54","76","97","98"])+" ",sections:[5]},{area:"013"+this.pick(["63","64","84","86"])+" ",sections:[5]},{area:"014"+this.pick(["04","20","60","61","80","88"])+" ",sections:[5]},{area:"015"+this.pick(["24","27","62","66"])+" ",sections:[5]},{area:"016"+this.pick(["06","29","35","47","59","95"])+" ",sections:[5]},{area:"017"+this.pick(["26","44","50","68"])+" ",sections:[5]},{area:"018"+this.pick(["27","37","84","97"])+" ",sections:[5]},{area:"019"+this.pick(["00","05","35","46","49","63","95"])+" ",sections:[5]}]),r=a.formatted?t(n):t(n).replace(" ","","g"));break;case"us":var o=this.areacode(a).toString(),s=this.natural({min:2,max:9}).toString()+this.natural({min:0,max:9}).toString()+this.natural({min:0,max:9}).toString(),m=this.natural({min:1e3,max:9999}).toString();r=a.formatted?o+" "+s+"-"+m:o+s+m}return r},a.prototype.postal=function(){var a=this.character({pool:"XVTSRPNKLMHJGECBA"}),e=a+this.natural({max:9})+this.character({alpha:!0,casing:"upper"}),n=this.natural({max:9})+this.character({alpha:!0,casing:"upper"})+this.natural({max:9});return e+" "+n},a.prototype.provinces=function(){return this.get("provinces")},a.prototype.province=function(a){return a&&a.full?this.pick(this.provinces()).name:this.pick(this.provinces()).abbreviation},a.prototype.state=function(a){return a&&a.full?this.pick(this.states(a)).name:this.pick(this.states(a)).abbreviation},a.prototype.states=function(a){a=e(a);var n,i=this.get("us_states_and_dc"),t=this.get("territories"),r=this.get("armed_forces");return n=i,a.territories&&(n=n.concat(t)),a.armed_forces&&(n=n.concat(r)),n},a.prototype.street=function(a){a=e(a);var n=this.word({syllables:2});return n=this.capitalize(n),n+=" ",n+=a.short_suffix?this.street_suffix().abbreviation:this.street_suffix().name},a.prototype.street_suffix=function(){return this.pick(this.street_suffixes())},a.prototype.street_suffixes=function(){return this.get("street_suffixes")},a.prototype.zip=function(a){var e=this.n(this.natural,5,{max:9});return a&&a.plusfour===!0&&(e.push("-"),e=e.concat(this.n(this.natural,4,{max:9}))),e.join("")},a.prototype.ampm=function(){return this.bool()?"am":"pm"},a.prototype.date=function(a){var n,i;if(a&&(a.min||a.max)){a=e(a,{american:!0,string:!1});var t="undefined"!=typeof a.min?a.min.getTime():1,r="undefined"!=typeof a.max?a.max.getTime():864e13;i=new Date(this.natural({min:t,max:r}))}else{var o=this.month({raw:!0});a=e(a,{year:parseInt(this.year(),10),month:o.numeric-1,day:this.natural({min:1,max:o.days}),hour:this.hour(),minute:this.minute(),second:this.second(),millisecond:this.millisecond(),american:!0,string:!1}),i=new Date(a.year,a.month,a.day,a.hour,a.minute,a.second,a.millisecond)}return n=a.american?i.getMonth()+1+"/"+i.getDate()+"/"+i.getFullYear():i.getDate()+"/"+(i.getMonth()+1)+"/"+i.getFullYear(),a.string?n:i},a.prototype.hammertime=function(a){return this.date(a).getTime()},a.prototype.hour=function(a){return a=e(a,{min:1,max:a&&a.twentyfour?24:12}),n(a.min<1,"Chance: Min cannot be less than 1."),n(a.twentyfour&&a.max>24,"Chance: Max cannot be greater than 24 for twentyfour option."),n(!a.twentyfour&&a.max>12,"Chance: Max cannot be greater than 12."),n(a.min>a.max,"Chance: Min cannot be greater than Max."),this.natural({min:a.min,max:a.max})},a.prototype.millisecond=function(){return this.natural({max:999})},a.prototype.minute=a.prototype.second=function(a){return a=e(a,{min:0,max:59}),n(a.min<0,"Chance: Min cannot be less than 0."),n(a.max>59,"Chance: Max cannot be greater than 59."),n(a.min>a.max,"Chance: Min cannot be greater than Max."),this.natural({min:a.min,max:a.max})},a.prototype.month=function(a){a=e(a,{min:1,max:12}),n(a.min<1,"Chance: Min cannot be less than 1."),n(a.max>12,"Chance: Max cannot be greater than 12."),n(a.min>a.max,"Chance: Min cannot be greater than Max.");var i=this.pick(this.months().slice(a.min-1,a.max));return a.raw?i:i.name},a.prototype.months=function(){return this.get("months")},a.prototype.second=function(){return this.natural({max:59})},a.prototype.timestamp=function(){return this.natural({min:1,max:parseInt((new Date).getTime()/1e3,10)})},a.prototype.year=function(a){return a=e(a,{min:(new Date).getFullYear()}),a.max="undefined"!=typeof a.max?a.max:a.min+100,this.natural(a).toString()},a.prototype.cc=function(a){a=e(a);var n,i,t;return n=this.cc_type(a.type?{name:a.type,raw:!0}:{raw:!0}),i=n.prefix.split(""),t=n.length-n.prefix.length-1,i=i.concat(this.n(this.integer,t,{min:0,max:9})),i.push(this.luhn_calculate(i.join(""))),i.join("")},a.prototype.cc_types=function(){return this.get("cc_types")},a.prototype.cc_type=function(a){a=e(a);var n=this.cc_types(),i=null;if(a.name){for(var t=0;tn?"-$"+n.replace("-",""):"$"+n},a.prototype.exp=function(a){a=e(a);var n={};return n.year=this.exp_year(),n.month=n.year===(new Date).getFullYear()?this.exp_month({future:!0}):this.exp_month(),a.raw?n:n.month+"/"+n.year},a.prototype.exp_month=function(a){a=e(a);var n,i,t=(new Date).getMonth();if(a.future){do n=this.month({raw:!0}).numeric,i=parseInt(n,10);while(t>i)}else n=this.month({raw:!0}).numeric;return n},a.prototype.exp_year=function(){return this.year({max:(new Date).getFullYear()+10})},a.prototype.d4=i({min:1,max:4}),a.prototype.d6=i({min:1,max:6}),a.prototype.d8=i({min:1,max:8}),a.prototype.d10=i({min:1,max:10}),a.prototype.d12=i({min:1,max:12}),a.prototype.d20=i({min:1,max:20}),a.prototype.d30=i({min:1,max:30}),a.prototype.d100=i({min:1,max:100}),a.prototype.rpg=function(a,n){if(n=e(n),null===a)throw new Error("A type of die roll must be included");var i=a.toLowerCase().split("d"),t=[];if(2!==i.length||!parseInt(i[0],10)||!parseInt(i[1],10))throw new Error("Invalid format provided. Please provide #d# where the first # is the number of dice to roll, the second # is the max of each die");for(var r=i[0];r>0;r--)t[r-1]=this.natural({min:1,max:i[1]});return"undefined"!=typeof n.sum&&n.sum?t.reduce(function(a,e){return a+e}):t},a.prototype.guid=function(a){a=e(a,{version:5});var n="abcdef1234567890",i="ab89",t=this.string({pool:n,length:8})+"-"+this.string({pool:n,length:4})+"-"+a.version+this.string({pool:n,length:3})+"-"+this.string({pool:i,length:1})+this.string({pool:n,length:3})+"-"+this.string({pool:n,length:12});return t},a.prototype.hash=function(a){a=e(a,{length:40,casing:"lower"});var n="upper"===a.casing?c.toUpperCase():c;return this.string({pool:n,length:a.length})},a.prototype.luhn_check=function(a){var e=a.toString(),n=+e.substring(e.length-1);return n===this.luhn_calculate(+e.substring(0,e.length-1))},a.prototype.luhn_calculate=function(a){for(var e,n=a.toString().split("").reverse(),i=0,t=0,r=n.length;r>t;++t)e=+n[t],t%2===0&&(e*=2,e>9&&(e-=9)),i+=e;return 9*i%10};var p={firstNames:{male:["James","John","Robert","Michael","William","David","Richard","Joseph","Charles","Thomas","Christopher","Daniel","Matthew","George","Donald","Anthony","Paul","Mark","Edward","Steven","Kenneth","Andrew","Brian","Joshua","Kevin","Ronald","Timothy","Jason","Jeffrey","Frank","Gary","Ryan","Nicholas","Eric","Stephen","Jacob","Larry","Jonathan","Scott","Raymond","Justin","Brandon","Gregory","Samuel","Benjamin","Patrick","Jack","Henry","Walter","Dennis","Jerry","Alexander","Peter","Tyler","Douglas","Harold","Aaron","Jose","Adam","Arthur","Zachary","Carl","Nathan","Albert","Kyle","Lawrence","Joe","Willie","Gerald","Roger","Keith","Jeremy","Terry","Harry","Ralph","Sean","Jesse","Roy","Louis","Billy","Austin","Bruce","Eugene","Christian","Bryan","Wayne","Russell","Howard","Fred","Ethan","Jordan","Philip","Alan","Juan","Randy","Vincent","Bobby","Dylan","Johnny","Phillip","Victor","Clarence","Ernest","Martin","Craig","Stanley","Shawn","Travis","Bradley","Leonard","Earl","Gabriel","Jimmy","Francis","Todd","Noah","Danny","Dale","Cody","Carlos","Allen","Frederick","Logan","Curtis","Alex","Joel","Luis","Norman","Marvin","Glenn","Tony","Nathaniel","Rodney","Melvin","Alfred","Steve","Cameron","Chad","Edwin","Caleb","Evan","Antonio","Lee","Herbert","Jeffery","Isaac","Derek","Ricky","Marcus","Theodore","Elijah","Luke","Jesus","Eddie","Troy","Mike","Dustin","Ray","Adrian","Bernard","Leroy","Angel","Randall","Wesley","Ian","Jared","Mason","Hunter","Calvin","Oscar","Clifford","Jay","Shane","Ronnie","Barry","Lucas","Corey","Manuel","Leo","Tommy","Warren","Jackson","Isaiah","Connor","Don","Dean","Jon","Julian","Miguel","Bill","Lloyd","Charlie","Mitchell","Leon","Jerome","Darrell","Jeremiah","Alvin","Brett","Seth","Floyd","Jim","Blake","Micheal","Gordon","Trevor","Lewis","Erik","Edgar","Vernon","Devin","Gavin","Jayden","Chris","Clyde","Tom","Derrick","Mario","Brent","Marc","Herman","Chase","Dominic","Ricardo","Franklin","Maurice","Max","Aiden","Owen","Lester","Gilbert","Elmer","Gene","Francisco","Glen","Cory","Garrett","Clayton","Sam","Jorge","Chester","Alejandro","Jeff","Harvey","Milton","Cole","Ivan","Andre","Duane","Landon"],female:["Mary","Emma","Elizabeth","Minnie","Margaret","Ida","Alice","Bertha","Sarah","Annie","Clara","Ella","Florence","Cora","Martha","Laura","Nellie","Grace","Carrie","Maude","Mabel","Bessie","Jennie","Gertrude","Julia","Hattie","Edith","Mattie","Rose","Catherine","Lillian","Ada","Lillie","Helen","Jessie","Louise","Ethel","Lula","Myrtle","Eva","Frances","Lena","Lucy","Edna","Maggie","Pearl","Daisy","Fannie","Josephine","Dora","Rosa","Katherine","Agnes","Marie","Nora","May","Mamie","Blanche","Stella","Ellen","Nancy","Effie","Sallie","Nettie","Della","Lizzie","Flora","Susie","Maud","Mae","Etta","Harriet","Sadie","Caroline","Katie","Lydia","Elsie","Kate","Susan","Mollie","Alma","Addie","Georgia","Eliza","Lulu","Nannie","Lottie","Amanda","Belle","Charlotte","Rebecca","Ruth","Viola","Olive","Amelia","Hannah","Jane","Virginia","Emily","Matilda","Irene","Kathryn","Esther","Willie","Henrietta","Ollie","Amy","Rachel","Sara","Estella","Theresa","Augusta","Ora","Pauline","Josie","Lola","Sophia","Leona","Anne","Mildred","Ann","Beulah","Callie","Lou","Delia","Eleanor","Barbara","Iva","Louisa","Maria","Mayme","Evelyn","Estelle","Nina","Betty","Marion","Bettie","Dorothy","Luella","Inez","Lela","Rosie","Allie","Millie","Janie","Cornelia","Victoria","Ruby","Winifred","Alta","Celia","Christine","Beatrice","Birdie","Harriett","Mable","Myra","Sophie","Tillie","Isabel","Sylvia","Carolyn","Isabelle","Leila","Sally","Ina","Essie","Bertie","Nell","Alberta","Katharine","Lora","Rena","Mina","Rhoda","Mathilda","Abbie","Eula","Dollie","Hettie","Eunice","Fanny","Ola","Lenora","Adelaide","Christina","Lelia","Nelle","Sue","Johanna","Lilly","Lucinda","Minerva","Lettie","Roxie","Cynthia","Helena","Hilda","Hulda","Bernice","Genevieve","Jean","Cordelia","Marian","Francis","Jeanette","Adeline","Gussie","Leah","Lois","Lura","Mittie","Hallie","Isabella","Olga","Phoebe","Teresa","Hester","Lida","Lina","Winnie","Claudia","Marguerite","Vera","Cecelia","Bess","Emilie","John","Rosetta","Verna","Myrtie","Cecilia","Elva","Olivia","Ophelia","Georgie","Elnora","Violet","Adele","Lily","Linnie","Loretta","Madge","Polly","Virgie","Eugenia","Lucile","Lucille","Mabelle","Rosalie"]},lastNames:["Smith","Johnson","Williams","Jones","Brown","Davis","Miller","Wilson","Moore","Taylor","Anderson","Thomas","Jackson","White","Harris","Martin","Thompson","Garcia","Martinez","Robinson","Clark","Rodriguez","Lewis","Lee","Walker","Hall","Allen","Young","Hernandez","King","Wright","Lopez","Hill","Scott","Green","Adams","Baker","Gonzalez","Nelson","Carter","Mitchell","Perez","Roberts","Turner","Phillips","Campbell","Parker","Evans","Edwards","Collins","Stewart","Sanchez","Morris","Rogers","Reed","Cook","Morgan","Bell","Murphy","Bailey","Rivera","Cooper","Richardson","Cox","Howard","Ward","Torres","Peterson","Gray","Ramirez","James","Watson","Brooks","Kelly","Sanders","Price","Bennett","Wood","Barnes","Ross","Henderson","Coleman","Jenkins","Perry","Powell","Long","Patterson","Hughes","Flores","Washington","Butler","Simmons","Foster","Gonzales","Bryant","Alexander","Russell","Griffin","Diaz","Hayes","Myers","Ford","Hamilton","Graham","Sullivan","Wallace","Woods","Cole","West","Jordan","Owens","Reynolds","Fisher","Ellis","Harrison","Gibson","McDonald","Cruz","Marshall","Ortiz","Gomez","Murray","Freeman","Wells","Webb","Simpson","Stevens","Tucker","Porter","Hunter","Hicks","Crawford","Henry","Boyd","Mason","Morales","Kennedy","Warren","Dixon","Ramos","Reyes","Burns","Gordon","Shaw","Holmes","Rice","Robertson","Hunt","Black","Daniels","Palmer","Mills","Nichols","Grant","Knight","Ferguson","Rose","Stone","Hawkins","Dunn","Perkins","Hudson","Spencer","Gardner","Stephens","Payne","Pierce","Berry","Matthews","Arnold","Wagner","Willis","Ray","Watkins","Olson","Carroll","Duncan","Snyder","Hart","Cunningham","Bradley","Lane","Andrews","Ruiz","Harper","Fox","Riley","Armstrong","Carpenter","Weaver","Greene","Lawrence","Elliott","Chavez","Sims","Austin","Peters","Kelley","Franklin","Lawson","Fields","Gutierrez","Ryan","Schmidt","Carr","Vasquez","Castillo","Wheeler","Chapman","Oliver","Montgomery","Richards","Williamson","Johnston","Banks","Meyer","Bishop","McCoy","Howell","Alvarez","Morrison","Hansen","Fernandez","Garza","Harvey","Little","Burton","Stanley","Nguyen","George","Jacobs","Reid","Kim","Fuller","Lynch","Dean","Gilbert","Garrett","Romero","Welch","Larson","Frazier","Burke","Hanson","Day","Mendoza","Moreno","Bowman","Medina","Fowler","Brewer","Hoffman","Carlson","Silva","Pearson","Holland","Douglas","Fleming","Jensen","Vargas","Byrd","Davidson","Hopkins","May","Terry","Herrera","Wade","Soto","Walters","Curtis","Neal","Caldwell","Lowe","Jennings","Barnett","Graves","Jimenez","Horton","Shelton","Barrett","Obrien","Castro","Sutton","Gregory","McKinney","Lucas","Miles","Craig","Rodriquez","Chambers","Holt","Lambert","Fletcher","Watts","Bates","Hale","Rhodes","Pena","Beck","Newman","Haynes","McDaniel","Mendez","Bush","Vaughn","Parks","Dawson","Santiago","Norris","Hardy","Love","Steele","Curry","Powers","Schultz","Barker","Guzman","Page","Munoz","Ball","Keller","Chandler","Weber","Leonard","Walsh","Lyons","Ramsey","Wolfe","Schneider","Mullins","Benson","Sharp","Bowen","Daniel","Barber","Cummings","Hines","Baldwin","Griffith","Valdez","Hubbard","Salazar","Reeves","Warner","Stevenson","Burgess","Santos","Tate","Cross","Garner","Mann","Mack","Moss","Thornton","Dennis","McGee","Farmer","Delgado","Aguilar","Vega","Glover","Manning","Cohen","Harmon","Rodgers","Robbins","Newton","Todd","Blair","Higgins","Ingram","Reese","Cannon","Strickland","Townsend","Potter","Goodwin","Walton","Rowe","Hampton","Ortega","Patton","Swanson","Joseph","Francis","Goodman","Maldonado","Yates","Becker","Erickson","Hodges","Rios","Conner","Adkins","Webster","Norman","Malone","Hammond","Flowers","Cobb","Moody","Quinn","Blake","Maxwell","Pope","Floyd","Osborne","Paul","McCarthy","Guerrero","Lindsey","Estrada","Sandoval","Gibbs","Tyler","Gross","Fitzgerald","Stokes","Doyle","Sherman","Saunders","Wise","Colon","Gill","Alvarado","Greer","Padilla","Simon","Waters","Nunez","Ballard","Schwartz","McBride","Houston","Christensen","Klein","Pratt","Briggs","Parsons","McLaughlin","Zimmerman","French","Buchanan","Moran","Copeland","Roy","Pittman","Brady","McCormick","Holloway","Brock","Poole","Frank","Logan","Owen","Bass","Marsh","Drake","Wong","Jefferson","Park","Morton","Abbott","Sparks","Patrick","Norton","Huff","Clayton","Massey","Lloyd","Figueroa","Carson","Bowers","Roberson","Barton","Tran","Lamb","Harrington","Casey","Boone","Cortez","Clarke","Mathis","Singleton","Wilkins","Cain","Bryan","Underwood","Hogan","McKenzie","Collier","Luna","Phelps","McGuire","Allison","Bridges","Wilkerson","Nash","Summers","Atkins"],countries:[{name:"Afghanistan",abbreviation:"AF"},{name:"Albania",abbreviation:"AL"},{name:"Algeria",abbreviation:"DZ"},{name:"American Samoa",abbreviation:"AS"},{name:"Andorra",abbreviation:"AD"},{name:"Angola",abbreviation:"AO"},{name:"Anguilla",abbreviation:"AI"},{name:"Antarctica",abbreviation:"AQ"},{name:"Antigua and Barbuda",abbreviation:"AG"},{name:"Argentina",abbreviation:"AR"},{name:"Armenia",abbreviation:"AM"},{name:"Aruba",abbreviation:"AW"},{name:"Australia",abbreviation:"AU"},{name:"Austria",abbreviation:"AT"},{name:"Azerbaijan",abbreviation:"AZ"},{name:"Bahamas",abbreviation:"BS"},{name:"Bahrain",abbreviation:"BH"},{name:"Bangladesh",abbreviation:"BD"},{name:"Barbados",abbreviation:"BB"},{name:"Belarus",abbreviation:"BY"},{name:"Belgium",abbreviation:"BE"},{name:"Belize",abbreviation:"BZ"},{name:"Benin",abbreviation:"BJ"},{name:"Bermuda",abbreviation:"BM"},{name:"Bhutan",abbreviation:"BT"},{name:"Bolivia",abbreviation:"BO"},{name:"Bosnia and Herzegovina",abbreviation:"BA"},{name:"Botswana",abbreviation:"BW"},{name:"Bouvet Island",abbreviation:"BV"},{name:"Brazil",abbreviation:"BR"},{name:"British Antarctic Territory",abbreviation:"BQ"},{name:"British Indian Ocean Territory",abbreviation:"IO"},{name:"British Virgin Islands",abbreviation:"VG"},{name:"Brunei",abbreviation:"BN"},{name:"Bulgaria",abbreviation:"BG"},{name:"Burkina Faso",abbreviation:"BF"},{name:"Burundi",abbreviation:"BI"},{name:"Cambodia",abbreviation:"KH"},{name:"Cameroon",abbreviation:"CM"},{name:"Canada",abbreviation:"CA"},{name:"Canton and Enderbury Islands",abbreviation:"CT"},{name:"Cape Verde",abbreviation:"CV"},{name:"Cayman Islands",abbreviation:"KY"},{name:"Central African Republic",abbreviation:"CF"},{name:"Chad",abbreviation:"TD"},{name:"Chile",abbreviation:"CL"},{name:"China",abbreviation:"CN"},{name:"Christmas Island",abbreviation:"CX"},{name:"Cocos [Keeling] Islands",abbreviation:"CC"},{name:"Colombia",abbreviation:"CO"},{name:"Comoros",abbreviation:"KM"},{name:"Congo - Brazzaville",abbreviation:"CG"},{name:"Congo - Kinshasa",abbreviation:"CD"},{name:"Cook Islands",abbreviation:"CK"},{name:"Costa Rica",abbreviation:"CR"},{name:"Croatia",abbreviation:"HR"},{name:"Cuba",abbreviation:"CU"},{name:"Cyprus",abbreviation:"CY"},{name:"Czech Republic",abbreviation:"CZ"},{name:"Côte d’Ivoire",abbreviation:"CI"},{name:"Denmark",abbreviation:"DK"},{name:"Djibouti",abbreviation:"DJ"},{name:"Dominica",abbreviation:"DM"},{name:"Dominican Republic",abbreviation:"DO"},{name:"Dronning Maud Land",abbreviation:"NQ"},{name:"East Germany",abbreviation:"DD"},{name:"Ecuador",abbreviation:"EC"},{name:"Egypt",abbreviation:"EG"},{name:"El Salvador",abbreviation:"SV"},{name:"Equatorial Guinea",abbreviation:"GQ"},{name:"Eritrea",abbreviation:"ER"},{name:"Estonia",abbreviation:"EE"},{name:"Ethiopia",abbreviation:"ET"},{name:"Falkland Islands",abbreviation:"FK"},{name:"Faroe Islands",abbreviation:"FO"},{name:"Fiji",abbreviation:"FJ"},{name:"Finland",abbreviation:"FI"},{name:"France",abbreviation:"FR"},{name:"French Guiana",abbreviation:"GF"},{name:"French Polynesia",abbreviation:"PF"},{name:"French Southern Territories",abbreviation:"TF"},{name:"French Southern and Antarctic Territories",abbreviation:"FQ"},{name:"Gabon",abbreviation:"GA"},{name:"Gambia",abbreviation:"GM"},{name:"Georgia",abbreviation:"GE"},{name:"Germany",abbreviation:"DE"},{name:"Ghana",abbreviation:"GH"},{name:"Gibraltar",abbreviation:"GI"},{name:"Greece",abbreviation:"GR"},{name:"Greenland",abbreviation:"GL"},{name:"Grenada",abbreviation:"GD"},{name:"Guadeloupe",abbreviation:"GP"},{name:"Guam",abbreviation:"GU"},{name:"Guatemala",abbreviation:"GT"},{name:"Guernsey",abbreviation:"GG"},{name:"Guinea",abbreviation:"GN"},{name:"Guinea-Bissau",abbreviation:"GW"},{name:"Guyana",abbreviation:"GY"},{name:"Haiti",abbreviation:"HT"},{name:"Heard Island and McDonald Islands",abbreviation:"HM"},{name:"Honduras",abbreviation:"HN"},{name:"Hong Kong SAR China",abbreviation:"HK"},{name:"Hungary",abbreviation:"HU"},{name:"Iceland",abbreviation:"IS"},{name:"India",abbreviation:"IN"},{name:"Indonesia",abbreviation:"ID"},{name:"Iran",abbreviation:"IR"},{name:"Iraq",abbreviation:"IQ"},{name:"Ireland",abbreviation:"IE"},{name:"Isle of Man",abbreviation:"IM"},{name:"Israel",abbreviation:"IL"},{name:"Italy",abbreviation:"IT"},{name:"Jamaica",abbreviation:"JM"},{name:"Japan",abbreviation:"JP"},{name:"Jersey",abbreviation:"JE"},{name:"Johnston Island",abbreviation:"JT"},{name:"Jordan",abbreviation:"JO"},{name:"Kazakhstan",abbreviation:"KZ"},{name:"Kenya",abbreviation:"KE"},{name:"Kiribati",abbreviation:"KI"},{name:"Kuwait",abbreviation:"KW"},{name:"Kyrgyzstan",abbreviation:"KG"},{name:"Laos",abbreviation:"LA"},{name:"Latvia",abbreviation:"LV"},{name:"Lebanon",abbreviation:"LB"},{name:"Lesotho",abbreviation:"LS"},{name:"Liberia",abbreviation:"LR"},{name:"Libya",abbreviation:"LY"},{name:"Liechtenstein",abbreviation:"LI"},{name:"Lithuania",abbreviation:"LT"},{name:"Luxembourg",abbreviation:"LU"},{name:"Macau SAR China",abbreviation:"MO"},{name:"Macedonia",abbreviation:"MK"},{name:"Madagascar",abbreviation:"MG"},{name:"Malawi",abbreviation:"MW"},{name:"Malaysia",abbreviation:"MY"},{name:"Maldives",abbreviation:"MV"},{name:"Mali",abbreviation:"ML"},{name:"Malta",abbreviation:"MT"},{name:"Marshall Islands",abbreviation:"MH"},{name:"Martinique",abbreviation:"MQ"},{name:"Mauritania",abbreviation:"MR"},{name:"Mauritius",abbreviation:"MU"},{name:"Mayotte",abbreviation:"YT"},{name:"Metropolitan France",abbreviation:"FX"},{name:"Mexico",abbreviation:"MX"},{name:"Micronesia",abbreviation:"FM"},{name:"Midway Islands",abbreviation:"MI"},{name:"Moldova",abbreviation:"MD"},{name:"Monaco",abbreviation:"MC"},{name:"Mongolia",abbreviation:"MN"},{name:"Montenegro",abbreviation:"ME"},{name:"Montserrat",abbreviation:"MS"},{name:"Morocco",abbreviation:"MA"},{name:"Mozambique",abbreviation:"MZ"},{name:"Myanmar [Burma]",abbreviation:"MM"},{name:"Namibia",abbreviation:"NA"},{name:"Nauru",abbreviation:"NR"},{name:"Nepal",abbreviation:"NP"},{name:"Netherlands",abbreviation:"NL"},{name:"Netherlands Antilles",abbreviation:"AN"},{name:"Neutral Zone",abbreviation:"NT"},{name:"New Caledonia",abbreviation:"NC"},{name:"New Zealand",abbreviation:"NZ"},{name:"Nicaragua",abbreviation:"NI"},{name:"Niger",abbreviation:"NE"},{name:"Nigeria",abbreviation:"NG"},{name:"Niue",abbreviation:"NU"},{name:"Norfolk Island",abbreviation:"NF"},{name:"North Korea",abbreviation:"KP"},{name:"North Vietnam",abbreviation:"VD"},{name:"Northern Mariana Islands",abbreviation:"MP"},{name:"Norway",abbreviation:"NO"},{name:"Oman",abbreviation:"OM"},{name:"Pacific Islands Trust Territory",abbreviation:"PC"},{name:"Pakistan",abbreviation:"PK"},{name:"Palau",abbreviation:"PW"},{name:"Palestinian Territories",abbreviation:"PS"},{name:"Panama",abbreviation:"PA"},{name:"Panama Canal Zone",abbreviation:"PZ"},{name:"Papua New Guinea",abbreviation:"PG"},{name:"Paraguay",abbreviation:"PY"},{name:"People's Democratic Republic of Yemen",abbreviation:"YD"},{name:"Peru",abbreviation:"PE"},{name:"Philippines",abbreviation:"PH"},{name:"Pitcairn Islands",abbreviation:"PN"},{name:"Poland",abbreviation:"PL"},{name:"Portugal",abbreviation:"PT"},{name:"Puerto Rico",abbreviation:"PR"},{name:"Qatar",abbreviation:"QA"},{name:"Romania",abbreviation:"RO"},{name:"Russia",abbreviation:"RU"},{name:"Rwanda",abbreviation:"RW"},{name:"Réunion",abbreviation:"RE"},{name:"Saint Barthélemy",abbreviation:"BL"},{name:"Saint Helena",abbreviation:"SH"},{name:"Saint Kitts and Nevis",abbreviation:"KN"},{name:"Saint Lucia",abbreviation:"LC"},{name:"Saint Martin",abbreviation:"MF"},{name:"Saint Pierre and Miquelon",abbreviation:"PM"},{name:"Saint Vincent and the Grenadines",abbreviation:"VC"},{name:"Samoa",abbreviation:"WS"},{name:"San Marino",abbreviation:"SM"},{name:"Saudi Arabia",abbreviation:"SA"},{name:"Senegal",abbreviation:"SN"},{name:"Serbia",abbreviation:"RS"},{name:"Serbia and Montenegro",abbreviation:"CS"},{name:"Seychelles",abbreviation:"SC"},{name:"Sierra Leone",abbreviation:"SL"},{name:"Singapore",abbreviation:"SG"},{name:"Slovakia",abbreviation:"SK"},{name:"Slovenia",abbreviation:"SI"},{name:"Solomon Islands",abbreviation:"SB"},{name:"Somalia",abbreviation:"SO"},{name:"South Africa",abbreviation:"ZA"},{name:"South Georgia and the South Sandwich Islands",abbreviation:"GS"},{name:"South Korea",abbreviation:"KR"},{name:"Spain",abbreviation:"ES"},{name:"Sri Lanka",abbreviation:"LK"},{name:"Sudan",abbreviation:"SD"},{name:"Suriname",abbreviation:"SR"},{name:"Svalbard and Jan Mayen",abbreviation:"SJ"},{name:"Swaziland",abbreviation:"SZ"},{name:"Sweden",abbreviation:"SE"},{name:"Switzerland",abbreviation:"CH"},{name:"Syria",abbreviation:"SY"},{name:"São Tomé and Príncipe",abbreviation:"ST"},{name:"Taiwan",abbreviation:"TW"},{name:"Tajikistan",abbreviation:"TJ"},{name:"Tanzania",abbreviation:"TZ"},{name:"Thailand",abbreviation:"TH"},{name:"Timor-Leste",abbreviation:"TL"},{name:"Togo",abbreviation:"TG"},{name:"Tokelau",abbreviation:"TK"},{name:"Tonga",abbreviation:"TO"},{name:"Trinidad and Tobago",abbreviation:"TT"},{name:"Tunisia",abbreviation:"TN"},{name:"Turkey",abbreviation:"TR"},{name:"Turkmenistan",abbreviation:"TM"},{name:"Turks and Caicos Islands",abbreviation:"TC"},{name:"Tuvalu",abbreviation:"TV"},{name:"U.S. Minor Outlying Islands",abbreviation:"UM"},{name:"U.S. Miscellaneous Pacific Islands",abbreviation:"PU"},{name:"U.S. Virgin Islands",abbreviation:"VI"},{name:"Uganda",abbreviation:"UG"},{name:"Ukraine",abbreviation:"UA"},{name:"Union of Soviet Socialist Republics",abbreviation:"SU"},{name:"United Arab Emirates",abbreviation:"AE"},{name:"United Kingdom",abbreviation:"GB"},{name:"United States",abbreviation:"US"},{name:"Unknown or Invalid Region",abbreviation:"ZZ"},{name:"Uruguay",abbreviation:"UY"},{name:"Uzbekistan",abbreviation:"UZ"},{name:"Vanuatu",abbreviation:"VU"},{name:"Vatican City",abbreviation:"VA"},{name:"Venezuela",abbreviation:"VE"},{name:"Vietnam",abbreviation:"VN"},{name:"Wake Island",abbreviation:"WK"},{name:"Wallis and Futuna",abbreviation:"WF"},{name:"Western Sahara",abbreviation:"EH"},{name:"Yemen",abbreviation:"YE"},{name:"Zambia",abbreviation:"ZM"},{name:"Zimbabwe",abbreviation:"ZW"},{name:"Åland Islands",abbreviation:"AX"}],provinces:[{name:"Alberta",abbreviation:"AB"},{name:"British Columbia",abbreviation:"BC"},{name:"Manitoba",abbreviation:"MB"},{name:"New Brunswick",abbreviation:"NB"},{name:"Newfoundland and Labrador",abbreviation:"NL"},{name:"Nova Scotia",abbreviation:"NS"},{name:"Ontario",abbreviation:"ON"},{name:"Prince Edward Island",abbreviation:"PE"},{name:"Quebec",abbreviation:"QC"},{name:"Saskatchewan",abbreviation:"SK"},{name:"Northwest Territories",abbreviation:"NT"},{name:"Nunavut",abbreviation:"NU"},{name:"Yukon",abbreviation:"YT"}],us_states_and_dc:[{name:"Alabama",abbreviation:"AL"},{name:"Alaska",abbreviation:"AK"},{name:"Arizona",abbreviation:"AZ"},{name:"Arkansas",abbreviation:"AR"},{name:"California",abbreviation:"CA"},{name:"Colorado",abbreviation:"CO"},{name:"Connecticut",abbreviation:"CT"},{name:"Delaware",abbreviation:"DE"},{name:"District of Columbia",abbreviation:"DC"},{name:"Florida",abbreviation:"FL"},{name:"Georgia",abbreviation:"GA"},{name:"Hawaii",abbreviation:"HI"},{name:"Idaho",abbreviation:"ID"},{name:"Illinois",abbreviation:"IL"},{name:"Indiana",abbreviation:"IN"},{name:"Iowa",abbreviation:"IA"},{name:"Kansas",abbreviation:"KS"},{name:"Kentucky",abbreviation:"KY"},{name:"Louisiana",abbreviation:"LA"},{name:"Maine",abbreviation:"ME"},{name:"Maryland",abbreviation:"MD"},{name:"Massachusetts",abbreviation:"MA"},{name:"Michigan",abbreviation:"MI"},{name:"Minnesota",abbreviation:"MN"},{name:"Mississippi",abbreviation:"MS"},{name:"Missouri",abbreviation:"MO"},{name:"Montana",abbreviation:"MT"},{name:"Nebraska",abbreviation:"NE"},{name:"Nevada",abbreviation:"NV"},{name:"New Hampshire",abbreviation:"NH"},{name:"New Jersey",abbreviation:"NJ"},{name:"New Mexico",abbreviation:"NM"},{name:"New York",abbreviation:"NY"},{name:"North Carolina",abbreviation:"NC"},{name:"North Dakota",abbreviation:"ND"},{name:"Ohio",abbreviation:"OH"},{name:"Oklahoma",abbreviation:"OK"},{name:"Oregon",abbreviation:"OR"},{name:"Pennsylvania",abbreviation:"PA"},{name:"Rhode Island",abbreviation:"RI"},{name:"South Carolina",abbreviation:"SC"},{name:"South Dakota",abbreviation:"SD"},{name:"Tennessee",abbreviation:"TN"},{name:"Texas",abbreviation:"TX"},{name:"Utah",abbreviation:"UT"},{name:"Vermont",abbreviation:"VT"},{name:"Virginia",abbreviation:"VA"},{name:"Washington",abbreviation:"WA"},{name:"West Virginia",abbreviation:"WV"},{name:"Wisconsin",abbreviation:"WI"},{name:"Wyoming",abbreviation:"WY"}],territories:[{name:"American Samoa",abbreviation:"AS"},{name:"Federated States of Micronesia",abbreviation:"FM"},{name:"Guam",abbreviation:"GU"},{name:"Marshall Islands",abbreviation:"MH"},{name:"Northern Mariana Islands",abbreviation:"MP"},{name:"Puerto Rico",abbreviation:"PR"},{name:"Virgin Islands, U.S.",abbreviation:"VI"}],armed_forces:[{name:"Armed Forces Europe",abbreviation:"AE"},{name:"Armed Forces Pacific",abbreviation:"AP"},{name:"Armed Forces the Americas",abbreviation:"AA"}],street_suffixes:[{name:"Avenue",abbreviation:"Ave"},{name:"Boulevard",abbreviation:"Blvd"},{name:"Center",abbreviation:"Ctr"},{name:"Circle",abbreviation:"Cir"},{name:"Court",abbreviation:"Ct"},{name:"Drive",abbreviation:"Dr"},{name:"Extension",abbreviation:"Ext"},{name:"Glen",abbreviation:"Gln"},{name:"Grove",abbreviation:"Grv"},{name:"Heights",abbreviation:"Hts"},{name:"Highway",abbreviation:"Hwy"},{name:"Junction",abbreviation:"Jct"},{name:"Key",abbreviation:"Key"},{name:"Lane",abbreviation:"Ln"},{name:"Loop",abbreviation:"Loop"},{name:"Manor",abbreviation:"Mnr"},{name:"Mill",abbreviation:"Mill"},{name:"Park",abbreviation:"Park"},{name:"Parkway",abbreviation:"Pkwy"},{name:"Pass",abbreviation:"Pass"},{name:"Path",abbreviation:"Path"},{name:"Pike",abbreviation:"Pike"},{name:"Place",abbreviation:"Pl"},{name:"Plaza",abbreviation:"Plz"},{name:"Point",abbreviation:"Pt"},{name:"Ridge",abbreviation:"Rdg"},{name:"River",abbreviation:"Riv"},{name:"Road",abbreviation:"Rd"},{name:"Square",abbreviation:"Sq"},{name:"Street",abbreviation:"St"},{name:"Terrace",abbreviation:"Ter"},{name:"Trail",abbreviation:"Trl"},{name:"Turnpike",abbreviation:"Tpke"},{name:"View",abbreviation:"Vw"},{name:"Way",abbreviation:"Way"}],months:[{name:"January",short_name:"Jan",numeric:"01",days:31},{name:"February",short_name:"Feb",numeric:"02",days:28},{name:"March",short_name:"Mar",numeric:"03",days:31},{name:"April",short_name:"Apr",numeric:"04",days:30},{name:"May",short_name:"May",numeric:"05",days:31},{name:"June",short_name:"Jun",numeric:"06",days:30},{name:"July",short_name:"Jul",numeric:"07",days:31},{name:"August",short_name:"Aug",numeric:"08",days:31},{name:"September",short_name:"Sep",numeric:"09",days:30},{name:"October",short_name:"Oct",numeric:"10",days:31},{name:"November",short_name:"Nov",numeric:"11",days:30},{name:"December",short_name:"Dec",numeric:"12",days:31}],cc_types:[{name:"American Express",short_name:"amex",prefix:"34",length:15},{name:"Bankcard",short_name:"bankcard",prefix:"5610",length:16},{name:"China UnionPay",short_name:"chinaunion",prefix:"62",length:16},{name:"Diners Club Carte Blanche",short_name:"dccarte",prefix:"300",length:14},{name:"Diners Club enRoute",short_name:"dcenroute",prefix:"2014",length:15},{name:"Diners Club International",short_name:"dcintl",prefix:"36",length:14},{name:"Diners Club United States & Canada",short_name:"dcusc",prefix:"54",length:16},{name:"Discover Card",short_name:"discover",prefix:"6011",length:16},{name:"InstaPayment",short_name:"instapay",prefix:"637",length:16},{name:"JCB",short_name:"jcb",prefix:"3528",length:16},{name:"Laser",short_name:"laser",prefix:"6304",length:16},{name:"Maestro",short_name:"maestro",prefix:"5018",length:16},{name:"Mastercard",short_name:"mc",prefix:"51",length:16},{name:"Solo",short_name:"solo",prefix:"6334",length:16},{name:"Switch",short_name:"switch",prefix:"4903",length:16},{name:"Visa",short_name:"visa",prefix:"4",length:16},{name:"Visa Electron",short_name:"electron",prefix:"4026",length:16}],currency_types:[{code:"AED",name:"United Arab Emirates Dirham"},{code:"AFN",name:"Afghanistan Afghani"},{code:"ALL",name:"Albania Lek"},{code:"AMD",name:"Armenia Dram"},{code:"ANG",name:"Netherlands Antilles Guilder"},{code:"AOA",name:"Angola Kwanza"},{code:"ARS",name:"Argentina Peso"},{code:"AUD",name:"Australia Dollar"},{code:"AWG",name:"Aruba Guilder"},{code:"AZN",name:"Azerbaijan New Manat"},{code:"BAM",name:"Bosnia and Herzegovina Convertible Marka"},{code:"BBD",name:"Barbados Dollar"},{code:"BDT",name:"Bangladesh Taka"},{code:"BGN",name:"Bulgaria Lev"},{code:"BHD",name:"Bahrain Dinar"},{code:"BIF",name:"Burundi Franc"},{code:"BMD",name:"Bermuda Dollar"},{code:"BND",name:"Brunei Darussalam Dollar"},{code:"BOB",name:"Bolivia Boliviano"},{code:"BRL",name:"Brazil Real"},{code:"BSD",name:"Bahamas Dollar"},{code:"BTN",name:"Bhutan Ngultrum"},{code:"BWP",name:"Botswana Pula"},{code:"BYR",name:"Belarus Ruble"},{code:"BZD",name:"Belize Dollar"},{code:"CAD",name:"Canada Dollar"},{code:"CDF",name:"Congo/Kinshasa Franc"},{code:"CHF",name:"Switzerland Franc"},{code:"CLP",name:"Chile Peso"},{code:"CNY",name:"China Yuan Renminbi"},{code:"COP",name:"Colombia Peso"},{code:"CRC",name:"Costa Rica Colon"},{code:"CUC",name:"Cuba Convertible Peso"},{code:"CUP",name:"Cuba Peso"},{code:"CVE",name:"Cape Verde Escudo"},{code:"CZK",name:"Czech Republic Koruna"},{code:"DJF",name:"Djibouti Franc"},{code:"DKK",name:"Denmark Krone"},{code:"DOP",name:"Dominican Republic Peso"},{code:"DZD",name:"Algeria Dinar"},{code:"EGP",name:"Egypt Pound"},{code:"ERN",name:"Eritrea Nakfa"},{code:"ETB",name:"Ethiopia Birr"},{code:"EUR",name:"Euro Member Countries"},{code:"FJD",name:"Fiji Dollar"},{code:"FKP",name:"Falkland Islands (Malvinas) Pound"},{code:"GBP",name:"United Kingdom Pound"},{code:"GEL",name:"Georgia Lari"},{code:"GGP",name:"Guernsey Pound"},{code:"GHS",name:"Ghana Cedi"},{code:"GIP",name:"Gibraltar Pound"},{code:"GMD",name:"Gambia Dalasi"},{code:"GNF",name:"Guinea Franc"},{code:"GTQ",name:"Guatemala Quetzal"},{code:"GYD",name:"Guyana Dollar"},{code:"HKD",name:"Hong Kong Dollar"},{code:"HNL",name:"Honduras Lempira"},{code:"HRK",name:"Croatia Kuna"},{code:"HTG",name:"Haiti Gourde"},{code:"HUF",name:"Hungary Forint"},{code:"IDR",name:"Indonesia Rupiah"},{code:"ILS",name:"Israel Shekel"},{code:"IMP",name:"Isle of Man Pound"},{code:"INR",name:"India Rupee"},{code:"IQD",name:"Iraq Dinar"},{code:"IRR",name:"Iran Rial"},{code:"ISK",name:"Iceland Krona"},{code:"JEP",name:"Jersey Pound"},{code:"JMD",name:"Jamaica Dollar"},{code:"JOD",name:"Jordan Dinar"},{code:"JPY",name:"Japan Yen"},{code:"KES",name:"Kenya Shilling"},{code:"KGS",name:"Kyrgyzstan Som"},{code:"KHR",name:"Cambodia Riel"},{code:"KMF",name:"Comoros Franc"},{code:"KPW",name:"Korea (North) Won"},{code:"KRW",name:"Korea (South) Won"},{code:"KWD",name:"Kuwait Dinar"},{code:"KYD",name:"Cayman Islands Dollar"},{code:"KZT",name:"Kazakhstan Tenge"},{code:"LAK",name:"Laos Kip"},{code:"LBP",name:"Lebanon Pound"},{code:"LKR",name:"Sri Lanka Rupee"},{code:"LRD",name:"Liberia Dollar"},{code:"LSL",name:"Lesotho Loti"},{code:"LTL",name:"Lithuania Litas"},{code:"LYD",name:"Libya Dinar"},{code:"MAD",name:"Morocco Dirham"},{code:"MDL",name:"Moldova Leu"},{code:"MGA",name:"Madagascar Ariary"},{code:"MKD",name:"Macedonia Denar"},{code:"MMK",name:"Myanmar (Burma) Kyat"},{code:"MNT",name:"Mongolia Tughrik"},{code:"MOP",name:"Macau Pataca"},{code:"MRO",name:"Mauritania Ouguiya"},{code:"MUR",name:"Mauritius Rupee"},{code:"MVR",name:"Maldives (Maldive Islands) Rufiyaa"},{code:"MWK",name:"Malawi Kwacha"},{code:"MXN",name:"Mexico Peso"},{code:"MYR",name:"Malaysia Ringgit"},{code:"MZN",name:"Mozambique Metical"},{code:"NAD",name:"Namibia Dollar"},{code:"NGN",name:"Nigeria Naira"},{code:"NIO",name:"Nicaragua Cordoba"},{code:"NOK",name:"Norway Krone"},{code:"NPR",name:"Nepal Rupee"},{code:"NZD",name:"New Zealand Dollar"},{code:"OMR",name:"Oman Rial"},{code:"PAB",name:"Panama Balboa"},{code:"PEN",name:"Peru Nuevo Sol"},{code:"PGK",name:"Papua New Guinea Kina"},{code:"PHP",name:"Philippines Peso"},{code:"PKR",name:"Pakistan Rupee"},{code:"PLN",name:"Poland Zloty"},{code:"PYG",name:"Paraguay Guarani"},{code:"QAR",name:"Qatar Riyal"},{code:"RON",name:"Romania New Leu"},{code:"RSD",name:"Serbia Dinar"},{code:"RUB",name:"Russia Ruble"},{code:"RWF",name:"Rwanda Franc"},{code:"SAR",name:"Saudi Arabia Riyal"},{code:"SBD",name:"Solomon Islands Dollar"},{code:"SCR",name:"Seychelles Rupee"},{code:"SDG",name:"Sudan Pound"},{code:"SEK",name:"Sweden Krona"},{code:"SGD",name:"Singapore Dollar"},{code:"SHP",name:"Saint Helena Pound"},{code:"SLL",name:"Sierra Leone Leone"},{code:"SOS",name:"Somalia Shilling"},{code:"SPL",name:"Seborga Luigino"},{code:"SRD",name:"Suriname Dollar"},{code:"STD",name:"São Tomé and Príncipe Dobra"},{code:"SVC",name:"El Salvador Colon"},{code:"SYP",name:"Syria Pound"},{code:"SZL",name:"Swaziland Lilangeni"},{code:"THB",name:"Thailand Baht"},{code:"TJS",name:"Tajikistan Somoni"},{code:"TMT",name:"Turkmenistan Manat"},{code:"TND",name:"Tunisia Dinar"},{code:"TOP",name:"Tonga Pa'anga"},{code:"TRY",name:"Turkey Lira"},{code:"TTD",name:"Trinidad and Tobago Dollar"},{code:"TVD",name:"Tuvalu Dollar"},{code:"TWD",name:"Taiwan New Dollar"},{code:"TZS",name:"Tanzania Shilling"},{code:"UAH",name:"Ukraine Hryvnia"},{code:"UGX",name:"Uganda Shilling"},{code:"USD",name:"United States Dollar"},{code:"UYU",name:"Uruguay Peso"},{code:"UZS",name:"Uzbekistan Som"},{code:"VEF",name:"Venezuela Bolivar"},{code:"VND",name:"Viet Nam Dong"},{code:"VUV",name:"Vanuatu Vatu"},{code:"WST",name:"Samoa Tala"},{code:"XAF",name:"Communauté Financière Africaine (BEAC) CFA Franc BEAC"},{code:"XCD",name:"East Caribbean Dollar"},{code:"XDR",name:"International Monetary Fund (IMF) Special Drawing Rights"},{code:"XOF",name:"Communauté Financière Africaine (BCEAO) Franc"},{code:"XPF",name:"Comptoirs Français du Pacifique (CFP) Franc"},{code:"YER",name:"Yemen Rial"},{code:"ZAR",name:"South Africa Rand"},{code:"ZMW",name:"Zambia Kwacha"},{code:"ZWD",name:"Zimbabwe Dollar"}]},v=Object.prototype.hasOwnProperty,y=Object.keys||function(a){var e=[]; -for(var n in a)v.call(a,n)&&e.push(n);return e};a.prototype.get=function(a){return o(p[a])},a.prototype.mac_address=function(a){a=e(a),a.separator||(a.separator=a.networkVersion?".":":");var n="ABCDEF1234567890",i="";return i=a.networkVersion?this.n(this.string,3,{pool:n,length:4}).join(a.separator):this.n(this.string,6,{pool:n,length:2}).join(a.separator)},a.prototype.normal=function(a){a=e(a,{mean:0,dev:1});var n,i,t,r,o=a.mean,s=a.dev;do i=2*this.random()-1,t=2*this.random()-1,n=i*i+t*t;while(n>=1);return r=i*Math.sqrt(-2*Math.log(n)/n),s*r+o},a.prototype.radio=function(a){a=e(a,{side:"?"});var n="";switch(a.side.toLowerCase()){case"east":case"e":n="W";break;case"west":case"w":n="K";break;default:n=this.character({pool:"KW"})}return n+this.character({alpha:!0,casing:"upper"})+this.character({alpha:!0,casing:"upper"})+this.character({alpha:!0,casing:"upper"})},a.prototype.set=function(a,e){"string"==typeof a?p[a]=e:p=o(a,p)},a.prototype.tv=function(a){return this.radio(a)},a.prototype.cnpj=function(){var a=this.n(this.natural,8,{max:9}),e=2+6*a[7]+7*a[6]+8*a[5]+9*a[4]+2*a[3]+3*a[2]+4*a[1]+5*a[0];e=11-e%11,e>=10&&(e=0);var n=2*e+3+7*a[7]+8*a[6]+9*a[5]+2*a[4]+3*a[3]+4*a[2]+5*a[1]+6*a[0];return n=11-n%11,n>=10&&(n=0),""+a[0]+a[1]+"."+a[2]+a[3]+a[4]+"."+a[5]+a[6]+a[7]+"/0001-"+e+n},a.prototype.mersenne_twister=function(a){return new g(a)};var g=function(a){void 0===a&&(a=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(a)};g.prototype.init_genrand=function(a){for(this.mt[0]=a>>>0,this.mti=1;this.mti>>30,this.mt[this.mti]=(1812433253*((4294901760&a)>>>16)<<16)+1812433253*(65535&a)+this.mti,this.mt[this.mti]>>>=0},g.prototype.init_by_array=function(a,e){var n,i,t=1,r=0;for(this.init_genrand(19650218),n=this.N>e?this.N:e;n;n--)i=this.mt[t-1]^this.mt[t-1]>>>30,this.mt[t]=(this.mt[t]^(1664525*((4294901760&i)>>>16)<<16)+1664525*(65535&i))+a[r]+r,this.mt[t]>>>=0,t++,r++,t>=this.N&&(this.mt[0]=this.mt[this.N-1],t=1),r>=e&&(r=0);for(n=this.N-1;n;n--)i=this.mt[t-1]^this.mt[t-1]>>>30,this.mt[t]=(this.mt[t]^(1566083941*((4294901760&i)>>>16)<<16)+1566083941*(65535&i))-t,this.mt[t]>>>=0,t++,t>=this.N&&(this.mt[0]=this.mt[this.N-1],t=1);this.mt[0]=2147483648},g.prototype.genrand_int32=function(){var a,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti===this.N+1&&this.init_genrand(5489),n=0;n>>1^e[1&a];for(;n>>1^e[1&a];a=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^a>>>1^e[1&a],this.mti=0}return a=this.mt[this.mti++],a^=a>>>11,a^=a<<7&2636928640,a^=a<<15&4022730752,a^=a>>>18,a>>>0},g.prototype.genrand_int31=function(){return this.genrand_int32()>>>1},g.prototype.genrand_real1=function(){return this.genrand_int32()*(1/4294967295)},g.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},g.prototype.genrand_real3=function(){return(this.genrand_int32()+.5)*(1/4294967296)},g.prototype.genrand_res53=function(){var a=this.genrand_int32()>>>5,e=this.genrand_int32()>>>6;return(67108864*a+e)*(1/9007199254740992)},"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(exports=module.exports=a),exports.Chance=a),"function"==typeof define&&define.amd&&define([],function(){return a}),"undefined"!=typeof importScripts&&(chance=new a),"object"==typeof window&&"object"==typeof window.document&&(window.Chance=a,window.chance=new a)}()}(); - -!function(){require=function t(e,n,r){function i(a,f){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!f&&u)return u(a,!0);if(o)return o(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var c=n[a]={exports:{}};e[a][0].call(c.exports,function(t){var n=e[a][1][t];return i(n?n:t)},c,c.exports,t,e,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;ad;d++)p.push(u(n.slice(0,a))),n=n.slice(a);r.push(p)}else c("string")(o.outputs[e].type)?(s=s.slice(a),r.push(u(n.slice(0,a))),n=n.slice(a)):(r.push(u(n.slice(0,a))),n=n.slice(a))}),r},D=function(t){var e=t.indexOf("(");return-1!==e?t.substr(0,e):t},C=function(t){var e=t.indexOf("(");return-1!==e?t.substr(e+1,t.length-1-(e+1)):""},q=function(t){var e={};return t.forEach(function(n){var r=D(n.name),i=C(n.name),o=function(){var e=Array.prototype.slice.call(arguments);return _(t,n.name,e)};void 0===e[r]&&(e[r]=o),e[r][i]=o}),e},I=function(t){var e={};return t.forEach(function(n){var r=D(n.name),i=C(n.name),o=function(e){return M(t,n.name,e)};void 0===e[r]&&(e[r]=o),e[r][i]=o}),e},G=function(t){return r.sha3(r.fromAscii(t)).slice(0,2+2*o)};e.exports={inputParser:q,outputParser:I,methodSignature:G,methodDisplayName:D,methodTypeName:C,getMethodWithName:u}},{"./web3":7}],2:[function(t,e,n){var r=t("./web3"),i=t("./abi"),o=function(t,e){e.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n=i.inputParser(e),o=i.outputParser(e),a={};return a.call=function(t){return a._isTransact=!1,a._options=t,a},a.transact=function(t){return a._isTransact=!0,a._options=t,a},a._options={},["gas","gasPrice","value","from"].forEach(function(t){a[t]=function(e){return a._options[t]=e,a}}),e.forEach(function(f){var u=i.methodDisplayName(f.name),s=i.methodTypeName(f.name),c=function(){var c=Array.prototype.slice.call(arguments),l=i.methodSignature(f.name),h=n[u][s].apply(null,c),p=a._options||{};p.to=t,p.data=l+h;var d=a._isTransact===!0||a._isTransact!==!1&&!f.constant,m=p.collapse!==!1;if(a._options={},a._isTransact=null,d)return r._currentContractAbi=e,r._currentContractAddress=t,r._currentContractMethodName=f.name,r._currentContractMethodParams=c,void r.eth.transact(p);var g=r.eth.call(p),v=o[u][s](g);return m&&(1===v.length?v=v[0]:0===v.length&&(v=null)),v};void 0===a[u]&&(a[u]=c),a[u][s]=c}),a};e.exports=o},{"./abi":1,"./web3":7}],3:[function(t,e,n){var r=t("./web3"),i=function(t,e){this.impl=e,this.callbacks=[],this.id=e.newFilter(t),r.provider.startPolling({call:e.changed,args:[this.id]},this.id,this.trigger.bind(this))};i.prototype.arrived=function(t){this.changed(t)},i.prototype.changed=function(t){this.callbacks.push(t)},i.prototype.trigger=function(t){for(var e=0;en;n+=2){var i=parseInt(t.substr(n,2),16);if(0===i)break;e+=String.fromCharCode(i)}return e},fromAscii:function(t,e){e=void 0===e?0:e;for(var n=this.toHex(t);n.length<2*e;)n+="00";return"0x"+n},toDecimal:function(t){return t=t.length>2?t.substring(2):"0",new BigNumber(t,16).toString(10)},fromDecimal:function(t){return"0x"+new BigNumber(t).toString(16)},toEth:function(t){for(var e="string"==typeof t?0===t.indexOf("0x")?parseInt(t.substr(2),16):parseInt(t):t,n=0,i=r;e>3e3&&n.5?l/(2-o-a):l/(o+a),o){case r:i=(s-e)/l+(e>s?6:0);break;case s:i=(e-r)/l+2;break;case e:i=(r-s)/l+4}i/=6}return{h:i,s:n,l:h}}function n(t){function r(t,r,s){return 0>s&&(s+=1),s>1&&(s-=1),1/6>s?t+6*(r-t)*s:.5>s?r:2/3>s?t+(r-t)*(2/3-s)*6:t}var s,e,i,n=t.h,o=t.s,a=t.l;if(0===o)s=e=i=a;else{var h=.5>a?a*(1+o):a+o-a*o,l=2*a-h;s=r(l,h,n+1/3),e=r(l,h,n),i=r(l,h,n-1/3)}return{r:Math.round(255*s),g:Math.round(255*e),b:Math.round(255*i)}}r.exports={hex2rgb:s,rgb2hex:e,rgb2hsl:i,hsl2rgb:n,rgb2rgbString:function(t){return"rgb("+[t.r,t.g,t.b].join(",")+")"}}},{}],3:[function(t,r){!function(s){"use strict";function e(t){return function(r,s){return"object"==typeof r&&(s=r,r=null),(null===r||void 0===r)&&(r=(new Date).toString()),s||(s={}),t.call(this,r,s)}}var i=t("./pattern"),n=r.exports={generate:e(function(t,r){return new i(t,r)})};s&&(s.fn.geopattern=e(function(t,r){return this.each(function(){var e=s(this).attr("data-title-sha");e&&(r=s.extend({hash:e},r));var i=n.generate(t,r);s(this).css("background-image",i.toDataUrl())})}))}("undefined"!=typeof jQuery?jQuery:null)},{"./pattern":4}],4:[function(t,r){(function(s){"use strict";function e(t,r,s){return parseInt(t.substr(r,s||1),16)}function i(t,r,s,e,i){var n=parseFloat(t),o=s-r,a=i-e;return(n-r)*a/o+e}function n(t){return t%2===0?C:j}function o(t){return i(t,0,15,M,W)}function a(t){var r=t,s=r/2,e=Math.sin(60*Math.PI/180)*r;return[0,e,s,0,s+r,0,2*r,e,s+r,2*e,s,2*e,0,e].join(",")}function h(t,r){var s=.66*r;return[[0,0,t/2,r-s,t/2,r,0,s,0,0],[t/2,r-s,t,0,t,s,t/2,r,t/2,r-s]].map(function(t){return t.join(",")})}function l(t){return[[t,0,t,3*t],[0,t,3*t,t]]}function c(t){var r=t,s=.33*r;return[s,0,r-s,0,r,s,r,r-s,r-s,r,s,r,0,r-s,0,s,s,0].join(",")}function f(t,r){var s=t/2;return[s,0,t,r,0,r,s,0].join(",")}function u(t,r){return[t/2,0,t,r/2,t/2,r,0,r/2].join(",")}function p(t){return[0,0,t,t,0,t,0,0].join(",")}function g(t,r,s,e,i){var a=p(e),h=o(i[0]),l=n(i[0]),c={stroke:S,"stroke-opacity":A,"fill-opacity":h,fill:l};t.polyline(a,c).transform({translate:[r+e,s],scale:[-1,1]}),t.polyline(a,c).transform({translate:[r+e,s+2*e],scale:[1,-1]}),h=o(i[1]),l=n(i[1]),c={stroke:S,"stroke-opacity":A,"fill-opacity":h,fill:l},t.polyline(a,c).transform({translate:[r+e,s+2*e],scale:[-1,-1]}),t.polyline(a,c).transform({translate:[r+e,s],scale:[1,1]})}function v(t,r,s,e,i){var a=o(i),h=n(i),l=p(e),c={stroke:S,"stroke-opacity":A,"fill-opacity":a,fill:h};t.polyline(l,c).transform({translate:[r,s+e],scale:[1,-1]}),t.polyline(l,c).transform({translate:[r+2*e,s+e],scale:[-1,-1]}),t.polyline(l,c).transform({translate:[r,s+e],scale:[1,1]}),t.polyline(l,c).transform({translate:[r+2*e,s+e],scale:[-1,1]})}function y(t,r){var s=t/2;return[0,0,r,s,0,t,0,0].join(",")}var d=t("extend"),b=t("./color"),m=t("./sha1"),k=t("./svg"),x={baseColor:"#933c3c"},w=["octogons","overlappingCircles","plusSigns","xes","sineWaves","hexagons","overlappingRings","plaid","triangles","squares","concentricCircles","diamonds","tessellation","nestedSquares","mosaicSquares","chevrons"],j="#222",C="#ddd",S="#000",A=.02,M=.02,W=.15,H=r.exports=function(t,r){return this.opts=d({},x,r),this.hash=r.hash||m(t),this.svg=new k,this.generateBackground(),this.generatePattern(),this};H.prototype.toSvg=function(){return this.svg.toString()},H.prototype.toString=function(){return this.toSvg()},H.prototype.toBase64=function(){var t,r=this.toSvg();return t="undefined"!=typeof window&&"function"==typeof window.btoa?window.btoa(r):new s(r).toString("base64")},H.prototype.toDataUri=function(){return"data:image/svg+xml;base64,"+this.toBase64()},H.prototype.toDataUrl=function(){return'url("'+this.toDataUri()+'")'},H.prototype.generateBackground=function(){var t,r,s,n;this.opts.color?s=b.hex2rgb(this.opts.color):(r=i(e(this.hash,14,3),0,4095,0,359),n=e(this.hash,17),t=b.rgb2hsl(b.hex2rgb(this.opts.baseColor)),t.h=(360*t.h-r+360)%360/360,t.s=n%2===0?Math.min(1,(100*t.s+n)/100):Math.max(0,(100*t.s-n)/100),s=b.hsl2rgb(t)),this.color=b.rgb2hex(s),this.svg.rect(0,0,"100%","100%",{fill:b.rgb2rgbString(s)})},H.prototype.generatePattern=function(){var t=this.opts.generator;if(t){if(w.indexOf(t)<0)throw new Error("The generator "+t+" does not exist.")}else t=w[e(this.hash,20)];return this["geo"+t.slice(0,1).toUpperCase()+t.slice(1)]()},H.prototype.geoHexagons=function(){var t,r,s,h,l,c,f,u,p=e(this.hash,0),g=i(p,0,15,8,60),v=g*Math.sqrt(3),y=2*g,d=a(g);for(this.svg.setWidth(3*y+3*g),this.svg.setHeight(6*v),s=0,u=0;6>u;u++)for(f=0;6>f;f++)c=e(this.hash,s),t=f%2===0?u*v:u*v+v/2,h=o(c),r=n(c),l={fill:r,"fill-opacity":h,stroke:S,"stroke-opacity":A},this.svg.polyline(d,l).transform({translate:[f*g*1.5-y/2,t-v/2]}),0===f&&this.svg.polyline(d,l).transform({translate:[6*g*1.5-y/2,t-v/2]}),0===u&&(t=f%2===0?6*v:6*v+v/2,this.svg.polyline(d,l).transform({translate:[f*g*1.5-y/2,t-v/2]})),0===f&&0===u&&this.svg.polyline(d,l).transform({translate:[6*g*1.5-y/2,5*v+v/2]}),s++},H.prototype.geoSineWaves=function(){var t,r,s,a,h,l,c,f=Math.floor(i(e(this.hash,0),0,15,100,400)),u=Math.floor(i(e(this.hash,1),0,15,30,100)),p=Math.floor(i(e(this.hash,2),0,15,3,30));for(this.svg.setWidth(f),this.svg.setHeight(36*p),r=0;36>r;r++)l=e(this.hash,r),s=o(l),t=n(l),c=f/4*.7,h={fill:"none",stroke:t,opacity:s,"stroke-width":""+p+"px"},a="M0 "+u+" C "+c+" 0, "+(f/2-c)+" 0, "+f/2+" "+u+" S "+(f-c)+" "+2*u+", "+f+" "+u+" S "+(1.5*f-c)+" 0, "+1.5*f+", "+u,this.svg.path(a,h).transform({translate:[-f/4,p*r-1.5*u]}),this.svg.path(a,h).transform({translate:[-f/4,p*r-1.5*u+36*p]})},H.prototype.geoChevrons=function(){var t,r,s,a,l,c,f,u=i(e(this.hash,0),0,15,30,80),p=i(e(this.hash,0),0,15,30,80),g=h(u,p);for(this.svg.setWidth(6*u),this.svg.setHeight(6*p*.66),r=0,f=0;6>f;f++)for(c=0;6>c;c++)l=e(this.hash,r),s=o(l),t=n(l),a={stroke:S,"stroke-opacity":A,fill:t,"fill-opacity":s,"stroke-width":1},this.svg.group(a).transform({translate:[c*u,f*p*.66-p/2]}).polyline(g).end(),0===f&&this.svg.group(a).transform({translate:[c*u,6*p*.66-p/2]}).polyline(g).end(),r+=1},H.prototype.geoPlusSigns=function(){var t,r,s,a,h,c,f,u,p=i(e(this.hash,0),0,15,10,25),g=3*p,v=l(p);for(this.svg.setWidth(12*p),this.svg.setHeight(12*p),s=0,u=0;6>u;u++)for(f=0;6>f;f++)c=e(this.hash,s),a=o(c),r=n(c),t=u%2===0?0:1,h={fill:r,stroke:S,"stroke-opacity":A,"fill-opacity":a},this.svg.group(h).transform({translate:[f*g-f*p+t*p-p,u*g-u*p-g/2]}).rect(v).end(),0===f&&this.svg.group(h).transform({translate:[4*g-f*p+t*p-p,u*g-u*p-g/2]}).rect(v).end(),0===u&&this.svg.group(h).transform({translate:[f*g-f*p+t*p-p,4*g-u*p-g/2]}).rect(v).end(),0===f&&0===u&&this.svg.group(h).transform({translate:[4*g-f*p+t*p-p,4*g-u*p-g/2]}).rect(v).end(),s++},H.prototype.geoXes=function(){var t,r,s,a,h,c,f,u,p=i(e(this.hash,0),0,15,10,25),g=l(p),v=3*p*.943;for(this.svg.setWidth(3*v),this.svg.setHeight(3*v),s=0,u=0;6>u;u++)for(f=0;6>f;f++)c=e(this.hash,s),a=o(c),t=f%2===0?u*v-.5*v:u*v-.5*v+v/4,r=n(c),h={fill:r,opacity:a},this.svg.group(h).transform({translate:[f*v/2-v/2,t-u*v/2],rotate:[45,v/2,v/2]}).rect(g).end(),0===f&&this.svg.group(h).transform({translate:[6*v/2-v/2,t-u*v/2],rotate:[45,v/2,v/2]}).rect(g).end(),0===u&&(t=f%2===0?6*v-v/2:6*v-v/2+v/4,this.svg.group(h).transform({translate:[f*v/2-v/2,t-6*v/2],rotate:[45,v/2,v/2]}).rect(g).end()),5===u&&this.svg.group(h).transform({translate:[f*v/2-v/2,t-11*v/2],rotate:[45,v/2,v/2]}).rect(g).end(),0===f&&0===u&&this.svg.group(h).transform({translate:[6*v/2-v/2,t-6*v/2],rotate:[45,v/2,v/2]}).rect(g).end(),s++},H.prototype.geoOverlappingCircles=function(){var t,r,s,a,h,l,c,f=e(this.hash,0),u=i(f,0,15,25,200),p=u/2;for(this.svg.setWidth(6*p),this.svg.setHeight(6*p),r=0,c=0;6>c;c++)for(l=0;6>l;l++)h=e(this.hash,r),s=o(h),t=n(h),a={fill:t,opacity:s},this.svg.circle(l*p,c*p,p,a),0===l&&this.svg.circle(6*p,c*p,p,a),0===c&&this.svg.circle(l*p,6*p,p,a),0===l&&0===c&&this.svg.circle(6*p,6*p,p,a),r++},H.prototype.geoOctogons=function(){var t,r,s,a,h,l,f=i(e(this.hash,0),0,15,10,60),u=c(f);for(this.svg.setWidth(6*f),this.svg.setHeight(6*f),r=0,l=0;6>l;l++)for(h=0;6>h;h++)a=e(this.hash,r),s=o(a),t=n(a),this.svg.polyline(u,{fill:t,"fill-opacity":s,stroke:S,"stroke-opacity":A}).transform({translate:[h*f,l*f]}),r+=1},H.prototype.geoSquares=function(){var t,r,s,a,h,l,c=i(e(this.hash,0),0,15,10,60);for(this.svg.setWidth(6*c),this.svg.setHeight(6*c),r=0,l=0;6>l;l++)for(h=0;6>h;h++)a=e(this.hash,r),s=o(a),t=n(a),this.svg.rect(h*c,l*c,c,c,{fill:t,"fill-opacity":s,stroke:S,"stroke-opacity":A}),r+=1},H.prototype.geoConcentricCircles=function(){var t,r,s,a,h,l,c=e(this.hash,0),f=i(c,0,15,10,60),u=f/5;for(this.svg.setWidth(6*(f+u)),this.svg.setHeight(6*(f+u)),r=0,l=0;6>l;l++)for(h=0;6>h;h++)a=e(this.hash,r),s=o(a),t=n(a),this.svg.circle(h*f+h*u+(f+u)/2,l*f+l*u+(f+u)/2,f/2,{fill:"none",stroke:t,opacity:s,"stroke-width":u+"px"}),a=e(this.hash,39-r),s=o(a),t=n(a),this.svg.circle(h*f+h*u+(f+u)/2,l*f+l*u+(f+u)/2,f/4,{fill:t,"fill-opacity":s}),r+=1},H.prototype.geoOverlappingRings=function(){var t,r,s,a,h,l,c,f=e(this.hash,0),u=i(f,0,15,10,60),p=u/4;for(this.svg.setWidth(6*u),this.svg.setHeight(6*u),r=0,c=0;6>c;c++)for(l=0;6>l;l++)h=e(this.hash,r),s=o(h),t=n(h),a={fill:"none",stroke:t,opacity:s,"stroke-width":p+"px"},this.svg.circle(l*u,c*u,u-p/2,a),0===l&&this.svg.circle(6*u,c*u,u-p/2,a),0===c&&this.svg.circle(l*u,6*u,u-p/2,a),0===l&&0===c&&this.svg.circle(6*u,6*u,u-p/2,a),r+=1},H.prototype.geoTriangles=function(){var t,r,s,a,h,l,c,u,p=e(this.hash,0),g=i(p,0,15,15,80),v=g/2*Math.sqrt(3),y=f(g,v);for(this.svg.setWidth(3*g),this.svg.setHeight(6*v),r=0,u=0;6>u;u++)for(c=0;6>c;c++)l=e(this.hash,r),s=o(l),t=n(l),h={fill:t,"fill-opacity":s,stroke:S,"stroke-opacity":A},a=u%2===0?c%2===0?180:0:c%2!==0?180:0,this.svg.polyline(y,h).transform({translate:[c*g*.5-g/2,v*u],rotate:[a,g/2,v/2]}),0===c&&this.svg.polyline(y,h).transform({translate:[6*g*.5-g/2,v*u],rotate:[a,g/2,v/2]}),r+=1},H.prototype.geoDiamonds=function(){var t,r,s,a,h,l,c,f,p=i(e(this.hash,0),0,15,10,50),g=i(e(this.hash,1),0,15,10,50),v=u(p,g);for(this.svg.setWidth(6*p),this.svg.setHeight(3*g),s=0,f=0;6>f;f++)for(c=0;6>c;c++)l=e(this.hash,s),a=o(l),r=n(l),h={fill:r,"fill-opacity":a,stroke:S,"stroke-opacity":A},t=f%2===0?0:p/2,this.svg.polyline(v,h).transform({translate:[c*p-p/2+t,g/2*f-g/2]}),0===c&&this.svg.polyline(v,h).transform({translate:[6*p-p/2+t,g/2*f-g/2]}),0===f&&this.svg.polyline(v,h).transform({translate:[c*p-p/2+t,g/2*6-g/2]}),0===c&&0===f&&this.svg.polyline(v,h).transform({translate:[6*p-p/2+t,g/2*6-g/2]}),s+=1},H.prototype.geoNestedSquares=function(){var t,r,s,a,h,l,c,f=i(e(this.hash,0),0,15,4,12),u=7*f;for(this.svg.setWidth(6*(u+f)+6*f),this.svg.setHeight(6*(u+f)+6*f),r=0,c=0;6>c;c++)for(l=0;6>l;l++)h=e(this.hash,r),s=o(h),t=n(h),a={fill:"none",stroke:t,opacity:s,"stroke-width":f+"px"},this.svg.rect(l*u+l*f*2+f/2,c*u+c*f*2+f/2,u,u,a),h=e(this.hash,39-r),s=o(h),t=n(h),a={fill:"none",stroke:t,opacity:s,"stroke-width":f+"px"},this.svg.rect(l*u+l*f*2+f/2+2*f,c*u+c*f*2+f/2+2*f,3*f,3*f,a),r+=1},H.prototype.geoMosaicSquares=function(){var t,r,s,n=i(e(this.hash,0),0,15,15,50);for(this.svg.setWidth(8*n),this.svg.setHeight(8*n),t=0,s=0;4>s;s++)for(r=0;4>r;r++)r%2===0?s%2===0?v(this.svg,r*n*2,s*n*2,n,e(this.hash,t)):g(this.svg,r*n*2,s*n*2,n,[e(this.hash,t),e(this.hash,t+1)]):s%2===0?g(this.svg,r*n*2,s*n*2,n,[e(this.hash,t),e(this.hash,t+1)]):v(this.svg,r*n*2,s*n*2,n,e(this.hash,t)),t+=1},H.prototype.geoPlaid=function(){var t,r,s,i,a,h,l,c=0,f=0;for(r=0;36>r;)i=e(this.hash,r),c+=i+5,l=e(this.hash,r+1),s=o(l),t=n(l),a=l+5,this.svg.rect(0,c,"100%",a,{opacity:s,fill:t}),c+=a,r+=2;for(r=0;36>r;)i=e(this.hash,r),f+=i+5,l=e(this.hash,r+1),s=o(l),t=n(l),h=l+5,this.svg.rect(f,0,h,"100%",{opacity:s,fill:t}),f+=h,r+=2;this.svg.setWidth(f),this.svg.setHeight(c)},H.prototype.geoTessellation=function(){var t,r,s,a,h,l=i(e(this.hash,0),0,15,5,40),c=l*Math.sqrt(3),f=2*l,u=l/2*Math.sqrt(3),p=y(l,u),g=3*l+2*u,v=2*c+2*l;for(this.svg.setWidth(g),this.svg.setHeight(v),r=0;20>r;r++)switch(h=e(this.hash,r),s=o(h),t=n(h),a={stroke:S,"stroke-opacity":A,fill:t,"fill-opacity":s,"stroke-width":1},r){case 0:this.svg.rect(-l/2,-l/2,l,l,a),this.svg.rect(g-l/2,-l/2,l,l,a),this.svg.rect(-l/2,v-l/2,l,l,a),this.svg.rect(g-l/2,v-l/2,l,l,a);break;case 1:this.svg.rect(f/2+u,c/2,l,l,a);break;case 2:this.svg.rect(-l/2,v/2-l/2,l,l,a),this.svg.rect(g-l/2,v/2-l/2,l,l,a);break;case 3:this.svg.rect(f/2+u,1.5*c+l,l,l,a);break;case 4:this.svg.polyline(p,a).transform({translate:[l/2,-l/2],rotate:[0,l/2,u/2]}),this.svg.polyline(p,a).transform({translate:[l/2,v- -l/2],rotate:[0,l/2,u/2],scale:[1,-1]});break;case 5:this.svg.polyline(p,a).transform({translate:[g-l/2,-l/2],rotate:[0,l/2,u/2],scale:[-1,1]}),this.svg.polyline(p,a).transform({translate:[g-l/2,v+l/2],rotate:[0,l/2,u/2],scale:[-1,-1]});break;case 6:this.svg.polyline(p,a).transform({translate:[g/2+l/2,c/2]});break;case 7:this.svg.polyline(p,a).transform({translate:[g-g/2-l/2,c/2],scale:[-1,1]});break;case 8:this.svg.polyline(p,a).transform({translate:[g/2+l/2,v-c/2],scale:[1,-1]});break;case 9:this.svg.polyline(p,a).transform({translate:[g-g/2-l/2,v-c/2],scale:[-1,-1]});break;case 10:this.svg.polyline(p,a).transform({translate:[l/2,v/2-l/2]});break;case 11:this.svg.polyline(p,a).transform({translate:[g-l/2,v/2-l/2],scale:[-1,1]});break;case 12:this.svg.rect(0,0,l,l,a).transform({translate:[l/2,l/2],rotate:[-30,0,0]});break;case 13:this.svg.rect(0,0,l,l,a).transform({scale:[-1,1],translate:[-g+l/2,l/2],rotate:[-30,0,0]});break;case 14:this.svg.rect(0,0,l,l,a).transform({translate:[l/2,v/2-l/2-l],rotate:[30,0,l]});break;case 15:this.svg.rect(0,0,l,l,a).transform({scale:[-1,1],translate:[-g+l/2,v/2-l/2-l],rotate:[30,0,l]});break;case 16:this.svg.rect(0,0,l,l,a).transform({scale:[1,-1],translate:[l/2,-v+v/2-l/2-l],rotate:[30,0,l]});break;case 17:this.svg.rect(0,0,l,l,a).transform({scale:[-1,-1],translate:[-g+l/2,-v+v/2-l/2-l],rotate:[30,0,l]});break;case 18:this.svg.rect(0,0,l,l,a).transform({scale:[1,-1],translate:[l/2,-v+l/2],rotate:[-30,0,0]});break;case 19:this.svg.rect(0,0,l,l,a).transform({scale:[-1,-1],translate:[-g+l/2,-v+l/2],rotate:[-30,0,0]})}}}).call(this,t("buffer").Buffer)},{"./color":2,"./sha1":5,"./svg":6,buffer:8,extend:9}],5:[function(t,r){"use strict";function s(){function t(){for(var t=16;80>t;t++){var r=f[t-3]^f[t-8]^f[t-14]^f[t-16];f[t]=r<<1|r>>>31}var s,e,i=o,n=a,p=h,g=l,v=c;for(t=0;80>t;t++){20>t?(s=g^n&(p^g),e=1518500249):40>t?(s=n^p^g,e=1859775393):60>t?(s=n&p|g&(n|p),e=2400959708):(s=n^p^g,e=3395469782);var y=(i<<5|i>>>27)+s+v+e+(0|f[t]);v=g,g=p,p=n<<30|n>>>2,n=i,i=y}for(o=o+i|0,a=a+n|0,h=h+p|0,l=l+g|0,c=c+v|0,u=0,t=0;16>t;t++)f[t]=0}function r(r){f[u]|=(255&r)<e;e++)r(t.charCodeAt(e))}function e(t){if("string"==typeof t)return s(t);var e=t.length;g+=8*e;for(var i=0;e>i;i++)r(t[i])}function i(t){for(var r="",s=28;s>=0;s-=4)r+=(t>>s&15).toString(16);return r}function n(){r(128),(u>14||14===u&&24>p)&&t(),u=14,p=24,r(0),r(0),r(g>0xffffffffff?g/1099511627776:0),r(g>4294967295?g/4294967296:0);for(var s=24;s>=0;s-=8)r(g>>s);return i(o)+i(a)+i(h)+i(l)+i(c)}var o=1732584193,a=4023233417,h=2562383102,l=271733878,c=3285377520,f=new Uint32Array(80),u=0,p=24,g=0;return{update:e,digest:n}}r.exports=function(t){if(void 0===t)return s();var r=s();return r.update(t),r.digest()}},{}],6:[function(t,r){"use strict";function s(){return this.width=100,this.height=100,this.svg=new i("svg"),this.context=[],this.setAttributes(this.svg,{xmlns:"http://www.w3.org/2000/svg",width:this.width,height:this.height}),this}var e=t("extend"),i=t("./xml");r.exports=s,s.prototype.currentContext=function(){return this.context[this.context.length-1]||this.svg},s.prototype.end=function(){return this.context.pop(),this},s.prototype.currentNode=function(){var t=this.currentContext();return t.lastChild||t},s.prototype.transform=function(t){return this.currentNode().setAttribute("transform",Object.keys(t).map(function(r){return r+"("+t[r].join(",")+")"}).join(" ")),this},s.prototype.setAttributes=function(t,r){Object.keys(r).forEach(function(s){t.setAttribute(s,r[s])})},s.prototype.setWidth=function(t){this.svg.setAttribute("width",Math.floor(t))},s.prototype.setHeight=function(t){this.svg.setAttribute("height",Math.floor(t))},s.prototype.toString=function(){return this.svg.toString()},s.prototype.rect=function(t,r,s,n,o){var a=this;if(Array.isArray(t))return t.forEach(function(t){a.rect.apply(a,t.concat(o))}),this;var h=new i("rect");return this.currentContext().appendChild(h),this.setAttributes(h,e({x:t,y:r,width:s,height:n},o)),this},s.prototype.circle=function(t,r,s,n){var o=new i("circle");return this.currentContext().appendChild(o),this.setAttributes(o,e({cx:t,cy:r,r:s},n)),this},s.prototype.path=function(t,r){var s=new i("path");return this.currentContext().appendChild(s),this.setAttributes(s,e({d:t},r)),this},s.prototype.polyline=function(t,r){var s=this;if(Array.isArray(t))return t.forEach(function(t){s.polyline(t,r)}),this;var n=new i("polyline");return this.currentContext().appendChild(n),this.setAttributes(n,e({points:t},r)),this},s.prototype.group=function(t){var r=new i("g");return this.currentContext().appendChild(r),this.context.push(r),this.setAttributes(r,e({},t)),this}},{"./xml":7,extend:9}],7:[function(t,r){"use strict";var s=r.exports=function(t){return this instanceof s?(this.tagName=t,this.attributes=Object.create(null),this.children=[],this.lastChild=null,this):new s(t)};s.prototype.appendChild=function(t){return this.children.push(t),this.lastChild=t,this},s.prototype.setAttribute=function(t,r){return this.attributes[t]=r,this},s.prototype.toString=function(){var t=this;return["<",t.tagName,Object.keys(t.attributes).map(function(r){return[" ",r,'="',t.attributes[r],'"'].join("")}).join(""),">",t.children.map(function(t){return t.toString()}).join(""),""].join("")}},{}],8:[function(){},{}],9:[function(t,r){function s(t){if(!t||"[object Object]"!==i.call(t)||t.nodeType||t.setInterval)return!1;var r=e.call(t,"constructor"),s=e.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!r&&!s)return!1;var n;for(n in t);return void 0===n||e.call(t,n)}var e=Object.prototype.hasOwnProperty,i=Object.prototype.toString;r.exports=function n(){var t,r,e,i,o,a,h=arguments[0]||{},l=1,c=arguments.length,f=!1;for("boolean"==typeof h&&(f=h,h=arguments[1]||{},l=2),"object"!=typeof h&&"function"!=typeof h&&(h={});c>l;l++)if(null!=(t=arguments[l]))for(r in t)e=h[r],i=t[r],h!==i&&(f&&i&&(s(i)||(o=Array.isArray(i)))?(o?(o=!1,a=e&&Array.isArray(e)?e:[]):a=e&&s(e)?e:{},h[r]=n(f,a,i)):void 0!==i&&(h[r]=i));return h}},{}]},{},[1])(1)})}(); - -!function(){!function(t,e,i){!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):jQuery&&!jQuery.fn.sparkline&&t(jQuery)}(function(s){"use strict";var r={},n,a,h,o,l,g,p,u,c,d,f,m,v,x,y,C,w,b,R,S,k,M,_,H,W,T,q,I,j,P,L,A,F=0;n=function(){return{common:{type:"line",lineColor:"#00f",fillColor:"#cdf",defaultPixelsPerValue:3,width:"auto",height:"auto",composite:!1,tagValuesAttribute:"values",tagOptionsPrefix:"spark",enableTagOptions:!1,enableHighlight:!0,highlightLighten:1.4,tooltipSkipNull:!0,tooltipPrefix:"",tooltipSuffix:"",disableHiddenCheck:!1,numberFormatter:!1,numberDigitGroupCount:3,numberDigitGroupSep:",",numberDecimalMark:".",disableTooltips:!1,disableInteraction:!1},line:{spotColor:"#f80",highlightSpotColor:"#5f5",highlightLineColor:"#f22",spotRadius:1.5,minSpotColor:"#f80",maxSpotColor:"#f80",lineWidth:1,normalRangeMin:i,normalRangeMax:i,normalRangeColor:"#ccc",drawNormalOnTop:!1,chartRangeMin:i,chartRangeMax:i,chartRangeMinX:i,chartRangeMaxX:i,tooltipFormat:new h(' {{prefix}}{{y}}{{suffix}}')},bar:{barColor:"#3366cc",negBarColor:"#f44",stackedBarColor:["#3366cc","#dc3912","#ff9900","#109618","#66aa00","#dd4477","#0099c6","#990099"],zeroColor:i,nullColor:i,zeroAxis:!0,barWidth:4,barSpacing:1,chartRangeMax:i,chartRangeMin:i,chartRangeClip:!1,colorMap:i,tooltipFormat:new h(' {{prefix}}{{value}}{{suffix}}')},tristate:{barWidth:4,barSpacing:1,posBarColor:"#6f6",negBarColor:"#f44",zeroBarColor:"#999",colorMap:{},tooltipFormat:new h(' {{value:map}}'),tooltipValueLookups:{map:{"-1":"Loss",0:"Draw",1:"Win"}}},discrete:{lineHeight:"auto",thresholdColor:i,thresholdValue:0,chartRangeMax:i,chartRangeMin:i,chartRangeClip:!1,tooltipFormat:new h("{{prefix}}{{value}}{{suffix}}")},bullet:{targetColor:"#f33",targetWidth:3,performanceColor:"#33f",rangeColors:["#d3dafe","#a8b6ff","#7f94ff"],base:i,tooltipFormat:new h("{{fieldkey:fields}} - {{value}}"),tooltipValueLookups:{fields:{r:"Range",p:"Performance",t:"Target"}}},pie:{offset:0,sliceColors:["#3366cc","#dc3912","#ff9900","#109618","#66aa00","#dd4477","#0099c6","#990099"],borderWidth:0,borderColor:"#000",tooltipFormat:new h(' {{value}} ({{percent.1}}%)')},box:{raw:!1,boxLineColor:"#000",boxFillColor:"#cdf",whiskerColor:"#000",outlierLineColor:"#333",outlierFillColor:"#fff",medianColor:"#f00",showOutliers:!0,outlierIQR:1.5,spotRadius:1.5,target:i,targetColor:"#4a2",chartRangeMax:i,chartRangeMin:i,tooltipFormat:new h("{{field:fields}}: {{value}}"),tooltipFormatFieldlistKey:"field",tooltipValueLookups:{fields:{lq:"Lower Quartile",med:"Median",uq:"Upper Quartile",lo:"Left Outlier",ro:"Right Outlier",lw:"Left Whisker",rw:"Right Whisker"}}}}},T='.jqstooltip { position: absolute;left: 0px;top: 0px;visibility: hidden;background: rgb(0, 0, 0) transparent;background-color: rgba(0,0,0,0.6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";color: white;font: 10px arial, san serif;text-align: left;white-space: nowrap;padding: 5px;border: 1px solid white;z-index: 10000;}.jqsfield { color: white;font: 10px arial, san serif;text-align: left;}',a=function(){var t,e;return t=function(){this.init.apply(this,arguments)},arguments.length>1?(arguments[0]?(t.prototype=s.extend(new arguments[0],arguments[arguments.length-1]),t._super=arguments[0].prototype):t.prototype=arguments[arguments.length-1],arguments.length>2&&(e=Array.prototype.slice.call(arguments,1,-1),e.unshift(t.prototype),s.extend.apply(s,e))):t.prototype=arguments[0],t.prototype.cls=t,t},s.SPFormatClass=h=a({fre:/\{\{([\w.]+?)(:(.+?))?\}\}/g,precre:/(\w+)\.(\d+)/,init:function(t,e){this.format=t,this.fclass=e},render:function(t,e,s){var r=this,n=t,a,h,o,l,g;return this.format.replace(this.fre,function(){var t;return h=arguments[1],o=arguments[3],a=r.precre.exec(h),a?(g=a[2],h=a[1]):g=!1,l=n[h],l===i?"":o&&e&&e[o]?(t=e[o],t.get?e[o].get(l)||l:e[o][l]||l):(c(l)&&(l=s.get("numberFormatter")?s.get("numberFormatter")(l):x(l,g,s.get("numberDigitGroupCount"),s.get("numberDigitGroupSep"),s.get("numberDecimalMark"))),l)})}}),s.spformat=function(t,e){return new h(t,e)},o=function(t,e,i){return e>t?e:t>i?i:t},l=function(t,i){var s;return 2===i?(s=e.floor(t.length/2),t.length%2?t[s]:(t[s-1]+t[s])/2):t.length%2?(s=(t.length*i+i)/4,s%1?(t[e.floor(s)]+t[e.floor(s)-1])/2:t[s-1]):(s=(t.length*i+2)/4,s%1?(t[e.floor(s)]+t[e.floor(s)-1])/2:t[s-1])},g=function(t){var e;switch(t){case"undefined":t=i;break;case"null":t=null;break;case"true":t=!0;break;case"false":t=!1;break;default:e=parseFloat(t),t==e&&(t=e)}return t},p=function(t){var e,i=[];for(e=t.length;e--;)i[e]=g(t[e]);return i},u=function(t,e){var i,s,r=[];for(i=0,s=t.length;s>i;i++)t[i]!==e&&r.push(t[i]);return r},c=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},x=function(t,e,i,r,n){var a,h;for(t=(e===!1?parseFloat(t).toString():t.toFixed(e)).split(""),a=(a=s.inArray(".",t))<0?t.length:a,a0;h-=i)t.splice(h,0,r);return t.join("")},d=function(t,e,i){var s;for(s=e.length;s--;)if((!i||null!==e[s])&&e[s]!==t)return!1;return!0},f=function(t){var e=0,i;for(i=t.length;i--;)e+="number"==typeof t[i]?t[i]:0;return e},v=function(t){return s.isArray(t)?t:[t]},m=function(e){var i;t.createStyleSheet?t.createStyleSheet().cssText=e:(i=t.createElement("style"),i.type="text/css",t.getElementsByTagName("head")[0].appendChild(i),i["string"==typeof t.body.style.WebkitAppearance?"innerText":"innerHTML"]=e)},s.fn.simpledraw=function(e,r,n,a){var h,o;if(n&&(h=this.data("_jqs_vcanvas")))return h;if(s.fn.sparkline.canvas===!1)return!1;if(s.fn.sparkline.canvas===i){var l=t.createElement("canvas");if(l.getContext&&l.getContext("2d"))s.fn.sparkline.canvas=function(t,e,i,s){return new P(t,e,i,s)};else{if(!t.namespaces||t.namespaces.v)return s.fn.sparkline.canvas=!1,!1;t.namespaces.add("v","urn:schemas-microsoft-com:vml","#default#VML"),s.fn.sparkline.canvas=function(t,e,i,s){return new L(t,e,i)}}}return e===i&&(e=s(this).innerWidth()),r===i&&(r=s(this).innerHeight()),h=s.fn.sparkline.canvas(e,r,this,a),o=s(this).data("_jqs_mhandler"),o&&o.registerCanvas(h),h},s.fn.cleardraw=function(){var t=this.data("_jqs_vcanvas");t&&t.reset()},s.RangeMapClass=y=a({init:function(t){var e,i,s=[];for(e in t)t.hasOwnProperty(e)&&"string"==typeof e&&e.indexOf(":")>-1&&(i=e.split(":"),i[0]=0===i[0].length?-1/0:parseFloat(i[0]),i[1]=0===i[1].length?1/0:parseFloat(i[1]),i[2]=t[e],s.push(i));this.map=t,this.rangelist=s||!1},get:function(t){var e=this.rangelist,s,r,n;if((n=this.map[t])!==i)return n;if(e)for(s=e.length;s--;)if(r=e[s],r[0]<=t&&r[1]>=t)return r[2];return i}}),s.range_map=function(t){return new y(t)},C=a({init:function(t,e){var i=s(t);this.$el=i,this.options=e,this.currentPageX=0,this.currentPageY=0,this.el=t,this.splist=[],this.tooltip=null,this.over=!1,this.displayTooltips=!e.get("disableTooltips"),this.highlightEnabled=!e.get("disableHighlight")},registerSparkline:function(t){this.splist.push(t),this.over&&this.updateDisplay()},registerCanvas:function(t){var e=s(t.canvas);this.canvas=t,this.$canvas=e,e.mouseenter(s.proxy(this.mouseenter,this)),e.mouseleave(s.proxy(this.mouseleave,this)),e.click(s.proxy(this.mouseclick,this))},reset:function(t){this.splist=[],this.tooltip&&t&&(this.tooltip.remove(),this.tooltip=i)},mouseclick:function(t){var e=s.Event("sparklineClick");e.originalEvent=t,e.sparklines=this.splist,this.$el.trigger(e)},mouseenter:function(e){s(t.body).unbind("mousemove.jqs"),s(t.body).bind("mousemove.jqs",s.proxy(this.mousemove,this)),this.over=!0,this.currentPageX=e.pageX,this.currentPageY=e.pageY,this.currentEl=e.target,!this.tooltip&&this.displayTooltips&&(this.tooltip=new w(this.options),this.tooltip.updatePosition(e.pageX,e.pageY)),this.updateDisplay()},mouseleave:function(){s(t.body).unbind("mousemove.jqs");var e=this.splist,i=e.length,r=!1,n,a;for(this.over=!1,this.currentEl=null,this.tooltip&&(this.tooltip.remove(),this.tooltip=null),a=0;i>a;a++)n=e[a],n.clearRegionHighlight()&&(r=!0);r&&this.canvas.render()},mousemove:function(t){this.currentPageX=t.pageX,this.currentPageY=t.pageY,this.currentEl=t.target,this.tooltip&&this.tooltip.updatePosition(t.pageX,t.pageY),this.updateDisplay()},updateDisplay:function(){var t=this.splist,e=t.length,i=!1,r=this.$canvas.offset(),n=this.currentPageX-r.left,a=this.currentPageY-r.top,h,o,l,g,p;if(this.over){for(l=0;e>l;l++)o=t[l],g=o.setRegionHighlight(this.currentEl,n,a),g&&(i=!0);if(i){if(p=s.Event("sparklineRegionChange"),p.sparklines=this.splist,this.$el.trigger(p),this.tooltip){for(h="",l=0;e>l;l++)o=t[l],h+=o.getCurrentRegionTooltip();this.tooltip.setContent(h)}this.disableHighlight||this.canvas.render()}null===g&&this.mouseleave()}}}),w=a({sizeStyle:"position: static !important;display: block !important;visibility: hidden !important;float: left !important;",init:function(e){var i=e.get("tooltipClassname","jqstooltip"),r=this.sizeStyle,n;this.container=e.get("tooltipContainer")||t.body,this.tooltipOffsetX=e.get("tooltipOffsetX",10),this.tooltipOffsetY=e.get("tooltipOffsetY",12),s("#jqssizetip").remove(),s("#jqstooltip").remove(),this.sizetip=s("

",{id:"jqssizetip",style:r,"class":i}),this.tooltip=s("
",{id:"jqstooltip","class":i}).appendTo(this.container),n=this.tooltip.offset(),this.offsetLeft=n.left,this.offsetTop=n.top,this.hidden=!0,s(window).unbind("resize.jqs scroll.jqs"),s(window).bind("resize.jqs scroll.jqs",s.proxy(this.updateWindowDims,this)),this.updateWindowDims()},updateWindowDims:function(){this.scrollTop=s(window).scrollTop(),this.scrollLeft=s(window).scrollLeft(),this.scrollRight=this.scrollLeft+s(window).width(),this.updatePosition()},getSize:function(t){this.sizetip.html(t).appendTo(this.container),this.width=this.sizetip.width()+1,this.height=this.sizetip.height(),this.sizetip.remove()},setContent:function(t){return t?(this.getSize(t),this.tooltip.html(t).css({width:this.width,height:this.height,visibility:"visible"}),this.hidden&&(this.hidden=!1,this.updatePosition()),void 0):(this.tooltip.css("visibility","hidden"),void(this.hidden=!0))},updatePosition:function(t,e){if(t===i){if(this.mousex===i)return;t=this.mousex-this.offsetLeft,e=this.mousey-this.offsetTop}else this.mousex=t-=this.offsetLeft,this.mousey=e-=this.offsetTop;this.height&&this.width&&!this.hidden&&(e-=this.height+this.tooltipOffsetY,t+=this.tooltipOffsetX,ethis.scrollRight&&(t=this.scrollRight-this.width),this.tooltip.css({left:t,top:e}))},remove:function(){this.tooltip.remove(),this.sizetip.remove(),this.sizetip=this.tooltip=i,s(window).unbind("resize.jqs scroll.jqs")}}),q=function(){m(T)},s(q),A=[],s.fn.sparkline=function(e,r){return this.each(function(){var n=new s.fn.sparkline.options(this,r),a=s(this),h,o;if(h=function(){var r,h,o,l,g,p,u;return"html"===e||e===i?(u=this.getAttribute(n.get("tagValuesAttribute")),(u===i||null===u)&&(u=a.html()),r=u.replace(/(^\s*\s*$)|\s+/g,"").split(",")):r=e,h="auto"===n.get("width")?r.length*n.get("defaultPixelsPerValue"):n.get("width"),"auto"===n.get("height")?n.get("composite")&&s.data(this,"_jqs_vcanvas")||(l=t.createElement("span"),l.innerHTML="a",a.html(l),o=s(l).innerHeight()||s(l).height(),s(l).remove(),l=null):o=n.get("height"),n.get("disableInteraction")?g=!1:(g=s.data(this,"_jqs_mhandler"),g?n.get("composite")||g.reset():(g=new C(this,n),s.data(this,"_jqs_mhandler",g))),n.get("composite")&&!s.data(this,"_jqs_vcanvas")?void(s.data(this,"_jqs_errnotify")||(alert("Attempted to attach a composite sparkline to an element with no existing sparkline"),s.data(this,"_jqs_errnotify",!0))):(p=new(s.fn.sparkline[n.get("type")])(this,r,n,h,o),p.render(),g&&g.registerSparkline(p),void 0)},s(this).html()&&!n.get("disableHiddenCheck")&&s(this).is(":hidden")||!s(this).parents("body").length){if(!n.get("composite")&&s.data(this,"_jqs_pending"))for(o=A.length;o;o--)A[o-1][0]==this&&A.splice(o-1,1);A.push([this,h]),s.data(this,"_jqs_pending",!0)}else h.call(this)})},s.fn.sparkline.defaults=n(),s.sparkline_display_visible=function(){var t,e,i,r=[];for(e=0,i=A.length;i>e;e++)t=A[e][0],s(t).is(":visible")&&!s(t).parents().is(":hidden")?(A[e][1].call(t),s.data(A[e][0],"_jqs_pending",!1),r.push(e)):!s(t).closest("html").length&&!s.data(t,"_jqs_pending")&&(s.data(A[e][0],"_jqs_pending",!1),r.push(e));for(e=r.length;e;e--)A.splice(r[e-1],1)},s.fn.sparkline.options=a({init:function(t,e){var i,n,a,h;this.userOptions=e=e||{},this.tag=t,this.tagValCache={},n=s.fn.sparkline.defaults,a=n.common,this.tagOptionsPrefix=e.enableTagOptions&&(e.tagOptionsPrefix||a.tagOptionsPrefix),h=this.getTagSetting("type"),i=h===r?n[e.type||a.type]:n[h],this.mergedOptions=s.extend({},a,i,e)},getTagSetting:function(t){var e=this.tagOptionsPrefix,s,n,a,h;if(e===!1||e===i)return r;if(this.tagValCache.hasOwnProperty(t))s=this.tagValCache.key;else{if(s=this.tag.getAttribute(e+t),s===i||null===s)s=r;else if("["===s.substr(0,1))for(s=s.substr(1,s.length-2).split(","),n=s.length;n--;)s[n]=g(s[n].replace(/(^\s*)|(\s*$)/g,""));else if("{"===s.substr(0,1))for(a=s.substr(1,s.length-2).split(","),s={},n=a.length;n--;)h=a[n].split(":",2),s[h[0].replace(/(^\s*)|(\s*$)/g,"")]=g(h[1].replace(/(^\s*)|(\s*$)/g,""));else s=g(s);this.tagValCache.key=s}return s},get:function(t,e){var s=this.getTagSetting(t),n;return s!==r?s:(n=this.mergedOptions[t])===i?e:n}}),s.fn.sparkline._base=a({disabled:!1,init:function(t,e,r,n,a){this.el=t,this.$el=s(t),this.values=e,this.options=r,this.width=n,this.height=a,this.currentRegion=i},initTarget:function(){var t=!this.options.get("disableInteraction");(this.target=this.$el.simpledraw(this.width,this.height,this.options.get("composite"),t))?(this.canvasWidth=this.target.pixelWidth,this.canvasHeight=this.target.pixelHeight):this.disabled=!0},render:function(){return this.disabled?(this.el.innerHTML="",!1):!0},getRegion:function(t,e){},setRegionHighlight:function(t,e,s){var r=this.currentRegion,n=!this.options.get("disableHighlight"),a;return e>this.canvasWidth||s>this.canvasHeight||0>e||0>s?null:(a=this.getRegion(t,e,s),r!==a?(r!==i&&n&&this.removeHighlight(),this.currentRegion=a,a!==i&&n&&this.renderHighlight(),!0):!1)},clearRegionHighlight:function(){return this.currentRegion!==i?(this.removeHighlight(),this.currentRegion=i,!0):!1},renderHighlight:function(){this.changeHighlight(!0)},removeHighlight:function(){this.changeHighlight(!1)},changeHighlight:function(t){},getCurrentRegionTooltip:function(){var t=this.options,e="",r=[],n,a,o,l,g,p,u,c,d,f,m,v,x,y;if(this.currentRegion===i)return"";if(n=this.getCurrentRegionFields(),m=t.get("tooltipFormatter"))return m(this,t,n);if(t.get("tooltipChartTitle")&&(e+='
'+t.get("tooltipChartTitle")+"
\n"),a=this.options.get("tooltipFormat"),!a)return"";if(s.isArray(a)||(a=[a]),s.isArray(n)||(n=[n]),u=this.options.get("tooltipFormatFieldlist"),c=this.options.get("tooltipFormatFieldlistKey"),u&&c){for(d=[],p=n.length;p--;)f=n[p][c],-1!=(y=s.inArray(f,u))&&(d[y]=n[p]);n=d}for(o=a.length,x=n.length,p=0;o>p;p++)for(v=a[p],"string"==typeof v&&(v=new h(v)),l=v.fclass||"jqsfield",y=0;x>y;y++)n[y].isNull&&t.get("tooltipSkipNull")||(s.extend(n[y],{prefix:t.get("tooltipPrefix"),suffix:t.get("tooltipSuffix")}),g=v.render(n[y],t.get("tooltipValueLookups"),t),r.push('
'+g+"
"));return r.length?e+r.join("\n"):""},getCurrentRegionFields:function(){},calcHighlightColor:function(t,i){var s=i.get("highlightColor"),r=i.get("highlightLighten"),n,a,h,l;if(s)return s;if(r&&(n=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(t)||/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(t))){for(h=[],a=4===t.length?16:1,l=0;3>l;l++)h[l]=o(e.round(parseInt(n[l+1],16)*a*r),0,255);return"rgb("+h.join(",")+")"}return t}}),b={changeHighlight:function(t){var e=this.currentRegion,i=this.target,r=this.regionShapes[e],n;r&&(n=this.renderRegion(e,t),s.isArray(n)||s.isArray(r)?(i.replaceWithShapes(r,n),this.regionShapes[e]=s.map(n,function(t){return t.id})):(i.replaceWithShape(r,n),this.regionShapes[e]=n.id))},render:function(){var t=this.values,e=this.target,i=this.regionShapes,r,n,a,h;if(this.cls._super.render.call(this)){for(a=t.length;a--;)if(r=this.renderRegion(a))if(s.isArray(r)){for(n=[],h=r.length;h--;)r[h].append(),n.push(r[h].id);i[a]=n}else r.append(),i[a]=r.id;else i[a]=null;e.render()}}},s.fn.sparkline.line=R=a(s.fn.sparkline._base,{type:"line",init:function(t,e,i,s,r){R._super.init.call(this,t,e,i,s,r),this.vertices=[],this.regionMap=[],this.xvalues=[],this.yvalues=[],this.yminmax=[],this.hightlightSpotId=null,this.lastShapeId=null,this.initTarget()},getRegion:function(t,e,s){var r,n=this.regionMap;for(r=n.length;r--;)if(null!==n[r]&&e>=n[r][0]&&e<=n[r][1])return n[r][2];return i},getCurrentRegionFields:function(){var t=this.currentRegion;return{isNull:null===this.yvalues[t],x:this.xvalues[t],y:this.yvalues[t],color:this.options.get("lineColor"),fillColor:this.options.get("fillColor"),offset:t}},renderHighlight:function(){var t=this.currentRegion,e=this.target,s=this.vertices[t],r=this.options,n=r.get("spotRadius"),a=r.get("highlightSpotColor"),h=r.get("highlightLineColor"),o,l;s&&(n&&a&&(o=e.drawCircle(s[0],s[1],n,i,a),this.highlightSpotId=o.id,e.insertAfterShape(this.lastShapeId,o)),h&&(l=e.drawLine(s[0],this.canvasTop,s[0],this.canvasTop+this.canvasHeight,h),this.highlightLineId=l.id,e.insertAfterShape(this.lastShapeId,l)))},removeHighlight:function(){var t=this.target;this.highlightSpotId&&(t.removeShapeId(this.highlightSpotId),this.highlightSpotId=null),this.highlightLineId&&(t.removeShapeId(this.highlightLineId),this.highlightLineId=null)},scanValues:function(){var t=this.values,i=t.length,s=this.xvalues,r=this.yvalues,n=this.yminmax,a,h,o,l,g;for(a=0;i>a;a++)h=t[a],o="string"==typeof t[a],l="object"==typeof t[a]&&t[a]instanceof Array,g=o&&t[a].split(":"),o&&2===g.length?(s.push(Number(g[0])),r.push(Number(g[1])),n.push(Number(g[1]))):l?(s.push(h[0]),r.push(h[1]),n.push(h[1])):(s.push(a),null===t[a]||"null"===t[a]?r.push(null):(r.push(Number(h)),n.push(Number(h))));this.options.get("xvalues")&&(s=this.options.get("xvalues")),this.maxy=this.maxyorg=e.max.apply(e,n),this.miny=this.minyorg=e.min.apply(e,n),this.maxx=e.max.apply(e,s),this.minx=e.min.apply(e,s),this.xvalues=s,this.yvalues=r,this.yminmax=n},processRangeOptions:function(){var t=this.options,e=t.get("normalRangeMin"),s=t.get("normalRangeMax");e!==i&&(ethis.maxy&&(this.maxy=s)),t.get("chartRangeMin")!==i&&(t.get("chartRangeClip")||t.get("chartRangeMin")this.maxy)&&(this.maxy=t.get("chartRangeMax")),t.get("chartRangeMinX")!==i&&(t.get("chartRangeClipX")||t.get("chartRangeMinX")this.maxx)&&(this.maxx=t.get("chartRangeMaxX"))},drawNormalRange:function(t,s,r,n,a){var h=this.options.get("normalRangeMin"),o=this.options.get("normalRangeMax"),l=s+e.round(r-r*((o-this.miny)/a)),g=e.round(r*(o-h)/a);this.target.drawRect(t,l,n,g,i,this.options.get("normalRangeColor")).append()},render:function(){var t=this.options,r=this.target,n=this.canvasWidth,a=this.canvasHeight,h=this.vertices,o=t.get("spotRadius"),l=this.regionMap,g,p,u,c,d,f,m,v,x,C,w,b,S,k,M,_,H,W,T,q,I,j,P,L,A;if(R._super.render.call(this)&&(this.scanValues(),this.processRangeOptions(),P=this.xvalues,L=this.yvalues,this.yminmax.length&&!(this.yvalues.length<2))){for(c=d=0,g=this.maxx-this.minx===0?1:this.maxx-this.minx,p=this.maxy-this.miny===0?1:this.maxy-this.miny,u=this.yvalues.length-1,o&&(4*o>n||4*o>a)&&(o=0),o&&(I=t.get("highlightSpotColor")&&!t.get("disableInteraction"),(I||t.get("minSpotColor")||t.get("spotColor")&&L[u]===this.miny)&&(a-=e.ceil(o)),(I||t.get("maxSpotColor")||t.get("spotColor")&&L[u]===this.maxy)&&(a-=e.ceil(o),c+=e.ceil(o)),(I||(t.get("minSpotColor")||t.get("maxSpotColor"))&&(L[0]===this.miny||L[0]===this.maxy))&&(d+=e.ceil(o),n-=e.ceil(o)),(I||t.get("spotColor")||t.get("minSpotColor")||t.get("maxSpotColor")&&(L[u]===this.miny||L[u]===this.maxy))&&(n-=e.ceil(o))),a--,t.get("normalRangeMin")!==i&&!t.get("drawNormalOnTop")&&this.drawNormalRange(d,c,a,n,p),m=[],v=[m],k=M=null,_=L.length,A=0;_>A;A++)x=P[A],w=P[A+1],C=L[A],b=d+e.round((x-this.minx)*(n/g)),S=_-1>A?d+e.round((w-this.minx)*(n/g)):n,M=b+(S-b)/2,l[A]=[k||0,M,A],k=M,null===C?A&&(null!==L[A-1]&&(m=[],v.push(m)),h.push(null)):(Cthis.maxy&&(C=this.maxy),m.length||m.push([b,c+a]),f=[b,c+e.round(a-a*((C-this.miny)/p))],m.push(f),h.push(f));for(H=[],W=[],T=v.length,A=0;T>A;A++)m=v[A],m.length&&(t.get("fillColor")&&(m.push([m[m.length-1][0],c+a]),W.push(m.slice(0)),m.pop()),m.length>2&&(m[0]=[m[0][0],m[1][1]]),H.push(m));for(T=W.length,A=0;T>A;A++)r.drawShape(W[A],t.get("fillColor"),t.get("fillColor")).append();for(t.get("normalRangeMin")!==i&&t.get("drawNormalOnTop")&&this.drawNormalRange(d,c,a,n,p),T=H.length,A=0;T>A;A++)r.drawShape(H[A],t.get("lineColor"),i,t.get("lineWidth")).append();if(o&&t.get("valueSpots"))for(q=t.get("valueSpots"),q.get===i&&(q=new y(q)),A=0;_>A;A++)j=q.get(L[A]),j&&r.drawCircle(d+e.round((P[A]-this.minx)*(n/g)),c+e.round(a-a*((L[A]-this.miny)/p)),o,i,j).append();o&&t.get("spotColor")&&null!==L[u]&&r.drawCircle(d+e.round((P[P.length-1]-this.minx)*(n/g)),c+e.round(a-a*((L[u]-this.miny)/p)),o,i,t.get("spotColor")).append(),this.maxy!==this.minyorg&&(o&&t.get("minSpotColor")&&(x=P[s.inArray(this.minyorg,L)],r.drawCircle(d+e.round((x-this.minx)*(n/g)),c+e.round(a-a*((this.minyorg-this.miny)/p)),o,i,t.get("minSpotColor")).append()),o&&t.get("maxSpotColor")&&(x=P[s.inArray(this.maxyorg,L)],r.drawCircle(d+e.round((x-this.minx)*(n/g)),c+e.round(a-a*((this.maxyorg-this.miny)/p)),o,i,t.get("maxSpotColor")).append())),this.lastShapeId=r.getLastShapeId(),this.canvasTop=c,r.render()}}}),s.fn.sparkline.bar=S=a(s.fn.sparkline._base,b,{type:"bar",init:function(t,r,n,a,h){var l=parseInt(n.get("barWidth"),10),c=parseInt(n.get("barSpacing"),10),d=n.get("chartRangeMin"),f=n.get("chartRangeMax"),m=n.get("chartRangeClip"),v=1/0,x=-1/0,C,w,b,R,k,M,_,H,W,T,q,I,j,P,L,A,F,B,O,V,X,z,N;for(S._super.init.call(this,t,r,n,a,h),M=0,_=r.length;_>M;M++)V=r[M],C="string"==typeof V&&V.indexOf(":")>-1,(C||s.isArray(V))&&(L=!0,C&&(V=r[M]=p(V.split(":"))),V=u(V,null),w=e.min.apply(e,V),b=e.max.apply(e,V),v>w&&(v=w),b>x&&(x=b));this.stacked=L,this.regionShapes={},this.barWidth=l,this.barSpacing=c,this.totalBarWidth=l+c,this.width=a=r.length*l+(r.length-1)*c,this.initTarget(),m&&(j=d===i?-1/0:d,P=f===i?1/0:f),k=[],R=L?[]:k;var E=[],D=[];for(M=0,_=r.length;_>M;M++)if(L)for(A=r[M],r[M]=O=[],E[M]=0,R[M]=D[M]=0,F=0,B=A.length;B>F;F++)V=O[F]=m?o(A[F],j,P):A[F],null!==V&&(V>0&&(E[M]+=V),0>v&&x>0?0>V?D[M]+=e.abs(V):R[M]+=V:R[M]+=e.abs(V-(0>V?x:v)),k.push(V));else V=m?o(r[M],j,P):r[M],V=r[M]=g(V),null!==V&&k.push(V);this.max=I=e.max.apply(e,k),this.min=q=e.min.apply(e,k),this.stackMax=x=L?e.max.apply(e,E):I,this.stackMin=v=L?e.min.apply(e,k):q,n.get("chartRangeMin")!==i&&(n.get("chartRangeClip")||n.get("chartRangeMin")I)&&(I=n.get("chartRangeMax")),this.zeroAxis=W=n.get("zeroAxis",!0),T=0>=q&&I>=0&&W?0:0==W?q:q>0?q:I,this.xaxisOffset=T,H=L?e.max.apply(e,R)+e.max.apply(e,D):I-q,this.canvasHeightEf=W&&0>q?this.canvasHeight-2:this.canvasHeight-1,T>q?(z=L&&I>=0?x:I,X=(z-T)/H*this.canvasHeight,X!==e.ceil(X)&&(this.canvasHeightEf-=2,X=e.ceil(X))):X=this.canvasHeight,this.yoffset=X,s.isArray(n.get("colorMap"))?(this.colorMapByIndex=n.get("colorMap"),this.colorMapByValue=null):(this.colorMapByIndex=null,this.colorMapByValue=n.get("colorMap"),this.colorMapByValue&&this.colorMapByValue.get===i&&(this.colorMapByValue=new y(this.colorMapByValue))),this.range=H},getRegion:function(t,s,r){var n=e.floor(s/this.totalBarWidth);return 0>n||n>=this.values.length?i:n},getCurrentRegionFields:function(){var t=this.currentRegion,e=v(this.values[t]),i=[],s,r;for(r=e.length;r--;)s=e[r],i.push({isNull:null===s,value:s,color:this.calcColor(r,s,t),offset:t});return i},calcColor:function(t,e,r){var n=this.colorMapByIndex,a=this.colorMapByValue,h=this.options,o,l;return o=h.get(this.stacked?"stackedBarColor":0>e?"negBarColor":"barColor"),0===e&&h.get("zeroColor")!==i&&(o=h.get("zeroColor")),a&&(l=a.get(e))?o=l:n&&n.length>r&&(o=n[r]),s.isArray(o)?o[t%o.length]:o},renderRegion:function(t,r){var n=this.values[t],a=this.options,h=this.xaxisOffset,o=[],l=this.range,g=this.stacked,p=this.target,u=t*this.totalBarWidth,c=this.canvasHeightEf,f=this.yoffset,m,v,x,y,C,w,b,R,S,k;if(n=s.isArray(n)?n:[n],b=n.length,R=n[0],y=d(null,n),k=d(h,n,!0),y)return a.get("nullColor")?(x=r?a.get("nullColor"):this.calcHighlightColor(a.get("nullColor"),a),m=f>0?f-1:f,p.drawRect(u,m,this.barWidth-1,0,x,x)):i;for(C=f,w=0;b>w;w++){if(R=n[w],g&&R===h){if(!k||S)continue;S=!0}v=l>0?e.floor(c*(e.abs(R-h)/l))+1:1,h>R||R===h&&0===f?(m=C,C+=v):(m=f-v,f-=v),x=this.calcColor(w,R,t),r&&(x=this.calcHighlightColor(x,a)),o.push(p.drawRect(u,m,this.barWidth-1,v-1,x,x))}return 1===o.length?o[0]:o}}),s.fn.sparkline.tristate=k=a(s.fn.sparkline._base,b,{type:"tristate",init:function(t,e,r,n,a){var h=parseInt(r.get("barWidth"),10),o=parseInt(r.get("barSpacing"),10);k._super.init.call(this,t,e,r,n,a),this.regionShapes={},this.barWidth=h,this.barSpacing=o,this.totalBarWidth=h+o,this.values=s.map(e,Number),this.width=n=e.length*h+(e.length-1)*o,s.isArray(r.get("colorMap"))?(this.colorMapByIndex=r.get("colorMap"),this.colorMapByValue=null):(this.colorMapByIndex=null,this.colorMapByValue=r.get("colorMap"),this.colorMapByValue&&this.colorMapByValue.get===i&&(this.colorMapByValue=new y(this.colorMapByValue))),this.initTarget()},getRegion:function(t,i,s){return e.floor(i/this.totalBarWidth)},getCurrentRegionFields:function(){var t=this.currentRegion;return{isNull:this.values[t]===i,value:this.values[t],color:this.calcColor(this.values[t],t),offset:t}},calcColor:function(t,e){var i=this.values,s=this.options,r=this.colorMapByIndex,n=this.colorMapByValue,a,h;return a=n&&(h=n.get(t))?h:r&&r.length>e?r[e]:s.get(i[e]<0?"negBarColor":i[e]>0?"posBarColor":"zeroBarColor")},renderRegion:function(t,i){var s=this.values,r=this.options,n=this.target,a,h,o,l,g,p;return a=n.pixelHeight,o=e.round(a/2),l=t*this.totalBarWidth,s[t]<0?(g=o,h=o-1):s[t]>0?(g=0,h=o-1):(g=o-1,h=2),p=this.calcColor(s[t],t),null!==p?(i&&(p=this.calcHighlightColor(p,r)),n.drawRect(l,g,this.barWidth-1,h-1,p,p)):void 0}}),s.fn.sparkline.discrete=M=a(s.fn.sparkline._base,b,{type:"discrete",init:function(t,r,n,a,h){M._super.init.call(this,t,r,n,a,h),this.regionShapes={},this.values=r=s.map(r,Number),this.min=e.min.apply(e,r),this.max=e.max.apply(e,r),this.range=this.max-this.min,this.width=a="auto"===n.get("width")?2*r.length:this.width,this.interval=e.floor(a/r.length),this.itemWidth=a/r.length,n.get("chartRangeMin")!==i&&(n.get("chartRangeClip")||n.get("chartRangeMin")this.max)&&(this.max=n.get("chartRangeMax")),this.initTarget(),this.target&&(this.lineHeight="auto"===n.get("lineHeight")?e.round(.3*this.canvasHeight):n.get("lineHeight"))},getRegion:function(t,i,s){return e.floor(i/this.itemWidth)},getCurrentRegionFields:function(){var t=this.currentRegion;return{isNull:this.values[t]===i,value:this.values[t],offset:t}},renderRegion:function(t,i){var s=this.values,r=this.options,n=this.min,a=this.max,h=this.range,l=this.interval,g=this.target,p=this.canvasHeight,u=this.lineHeight,c=p-u,d,f,m,v;return f=o(s[t],n,a),v=t*l,d=e.round(c-c*((f-n)/h)),m=r.get(r.get("thresholdColor")&&fh?h:0:r.get("base"),this.min=h,this.max=o,this.range=o-h,this.shapes={},this.valueShapes={},this.regiondata={},this.width=n="auto"===r.get("width")?"4.0em":n,this.target=this.$el.simpledraw(n,a,r.get("composite")),s.length||(this.disabled=!0),this.initTarget()},getRegion:function(t,e,s){var r=this.target.getShapeAt(t,e,s);return r!==i&&this.shapes[r]!==i?this.shapes[r]:i},getCurrentRegionFields:function(){var t=this.currentRegion;return{fieldkey:t.substr(0,1),value:this.values[t.substr(1)],region:t}},changeHighlight:function(t){var e=this.currentRegion,i=this.valueShapes[e],s;switch(delete this.shapes[i],e.substr(0,1)){case"r":s=this.renderRange(e.substr(1),t);break;case"p":s=this.renderPerformance(t);break;case"t":s=this.renderTarget(t)}this.valueShapes[e]=s.id,this.shapes[s.id]=e,this.target.replaceWithShape(i,s)},renderRange:function(t,i){var s=this.values[t],r=e.round(this.canvasWidth*((s-this.min)/this.range)),n=this.options.get("rangeColors")[t-2];return i&&(n=this.calcHighlightColor(n,this.options)),this.target.drawRect(0,0,r-1,this.canvasHeight-1,n,n)},renderPerformance:function(t){var i=this.values[1],s=e.round(this.canvasWidth*((i-this.min)/this.range)),r=this.options.get("performanceColor");return t&&(r=this.calcHighlightColor(r,this.options)),this.target.drawRect(0,e.round(.3*this.canvasHeight),s-1,e.round(.4*this.canvasHeight)-1,r,r)},renderTarget:function(t){var i=this.values[0],s=e.round(this.canvasWidth*((i-this.min)/this.range)-this.options.get("targetWidth")/2),r=e.round(.1*this.canvasHeight),n=this.canvasHeight-2*r,a=this.options.get("targetColor");return t&&(a=this.calcHighlightColor(a,this.options)),this.target.drawRect(s,r,this.options.get("targetWidth")-1,n-1,a,a)},render:function(){var t=this.values.length,e=this.target,i,s;if(_._super.render.call(this)){for(i=2;t>i;i++)s=this.renderRange(i).append(),this.shapes[s.id]="r"+i,this.valueShapes["r"+i]=s.id;null!==this.values[1]&&(s=this.renderPerformance().append(),this.shapes[s.id]="p1",this.valueShapes.p1=s.id),null!==this.values[0]&&(s=this.renderTarget().append(),this.shapes[s.id]="t0",this.valueShapes.t0=s.id),e.render()}}}),s.fn.sparkline.pie=H=a(s.fn.sparkline._base,{type:"pie",init:function(t,i,r,n,a){var h=0,o;if(H._super.init.call(this,t,i,r,n,a),this.shapes={},this.valueShapes={},this.values=i=s.map(i,Number),"auto"===r.get("width")&&(this.width=this.height),i.length>0)for(o=i.length;o--;)h+=i[o];this.total=h,this.initTarget(),this.radius=e.floor(e.min(this.canvasWidth,this.canvasHeight)/2)},getRegion:function(t,e,s){var r=this.target.getShapeAt(t,e,s);return r!==i&&this.shapes[r]!==i?this.shapes[r]:i},getCurrentRegionFields:function(){var t=this.currentRegion;return{isNull:this.values[t]===i,value:this.values[t],percent:this.values[t]/this.total*100,color:this.options.get("sliceColors")[t%this.options.get("sliceColors").length],offset:t}},changeHighlight:function(t){var e=this.currentRegion,i=this.renderSlice(e,t),s=this.valueShapes[e];delete this.shapes[s],this.target.replaceWithShape(s,i),this.valueShapes[e]=i.id,this.shapes[i.id]=e},renderSlice:function(t,s){var r=this.target,n=this.options,a=this.radius,h=n.get("borderWidth"),o=n.get("offset"),l=2*e.PI,g=this.values,p=this.total,u=o?2*e.PI*(o/360):0,c,d,f,m,v;for(m=g.length,f=0;m>f;f++){if(c=u,d=u,p>0&&(d=u+l*(g[f]/p)),t===f)return v=n.get("sliceColors")[f%n.get("sliceColors").length],s&&(v=this.calcHighlightColor(v,n)),r.drawPieSlice(a,a,a-h,c,d,i,v);u=d}},render:function(){var t=this.target,s=this.values,r=this.options,n=this.radius,a=r.get("borderWidth"),h,o; -if(H._super.render.call(this)){for(a&&t.drawCircle(n,n,e.floor(n-a/2),r.get("borderColor"),i,a).append(),o=s.length;o--;)s[o]&&(h=this.renderSlice(o).append(),this.valueShapes[o]=h.id,this.shapes[h.id]=o);t.render()}}}),s.fn.sparkline.box=W=a(s.fn.sparkline._base,{type:"box",init:function(t,e,i,r,n){W._super.init.call(this,t,e,i,r,n),this.values=s.map(e,Number),this.width="auto"===i.get("width")?"4.0em":r,this.initTarget(),this.values.length||(this.disabled=1)},getRegion:function(){return 1},getCurrentRegionFields:function(){var t=[{field:"lq",value:this.quartiles[0]},{field:"med",value:this.quartiles[1]},{field:"uq",value:this.quartiles[2]}];return this.loutlier!==i&&t.push({field:"lo",value:this.loutlier}),this.routlier!==i&&t.push({field:"ro",value:this.routlier}),this.lwhisker!==i&&t.push({field:"lw",value:this.lwhisker}),this.rwhisker!==i&&t.push({field:"rw",value:this.rwhisker}),t},render:function(){var t=this.target,s=this.values,r=s.length,n=this.options,a=this.canvasWidth,h=this.canvasHeight,o=n.get("chartRangeMin")===i?e.min.apply(e,s):n.get("chartRangeMin"),g=n.get("chartRangeMax")===i?e.max.apply(e,s):n.get("chartRangeMax"),p=0,u,c,d,f,m,v,x,y,C,w,b;if(W._super.render.call(this)){if(n.get("raw"))n.get("showOutliers")&&s.length>5?(c=s[0],u=s[1],f=s[2],m=s[3],v=s[4],x=s[5],y=s[6]):(u=s[0],f=s[1],m=s[2],v=s[3],x=s[4]);else if(s.sort(function(t,e){return t-e}),f=l(s,1),m=l(s,2),v=l(s,3),d=v-f,n.get("showOutliers")){for(u=x=i,C=0;r>C;C++)u===i&&s[C]>f-d*n.get("outlierIQR")&&(u=s[C]),s[C]c&&t.drawCircle((c-o)*b+p,h/2,n.get("spotRadius"),n.get("outlierLineColor"),n.get("outlierFillColor")).append(),y>x&&t.drawCircle((y-o)*b+p,h/2,n.get("spotRadius"),n.get("outlierLineColor"),n.get("outlierFillColor")).append()),t.drawRect(e.round((f-o)*b+p),e.round(.1*h),e.round((v-f)*b),e.round(.8*h),n.get("boxLineColor"),n.get("boxFillColor")).append(),t.drawLine(e.round((u-o)*b+p),e.round(h/2),e.round((f-o)*b+p),e.round(h/2),n.get("lineColor")).append(),t.drawLine(e.round((u-o)*b+p),e.round(h/4),e.round((u-o)*b+p),e.round(h-h/4),n.get("whiskerColor")).append(),t.drawLine(e.round((x-o)*b+p),e.round(h/2),e.round((v-o)*b+p),e.round(h/2),n.get("lineColor")).append(),t.drawLine(e.round((x-o)*b+p),e.round(h/4),e.round((x-o)*b+p),e.round(h-h/4),n.get("whiskerColor")).append(),t.drawLine(e.round((m-o)*b+p),e.round(.1*h),e.round((m-o)*b+p),e.round(.9*h),n.get("medianColor")).append(),n.get("target")&&(w=e.ceil(n.get("spotRadius")),t.drawLine(e.round((n.get("target")-o)*b+p),e.round(h/2-w),e.round((n.get("target")-o)*b+p),e.round(h/2+w),n.get("targetColor")).append(),t.drawLine(e.round((n.get("target")-o)*b+p-w),e.round(h/2),e.round((n.get("target")-o)*b+p+w),e.round(h/2),n.get("targetColor")).append()),t.render()}}}),I=a({init:function(t,e,i,s){this.target=t,this.id=e,this.type=i,this.args=s},append:function(){return this.target.appendShape(this),this}}),j=a({_pxregex:/(\d+)(px)?\s*$/i,init:function(t,e,i){t&&(this.width=t,this.height=e,this.target=i,this.lastShapeId=null,i[0]&&(i=i[0]),s.data(i,"_jqs_vcanvas",this))},drawLine:function(t,e,i,s,r,n){return this.drawShape([[t,e],[i,s]],r,n)},drawShape:function(t,e,i,s){return this._genShape("Shape",[t,e,i,s])},drawCircle:function(t,e,i,s,r,n){return this._genShape("Circle",[t,e,i,s,r,n])},drawPieSlice:function(t,e,i,s,r,n,a){return this._genShape("PieSlice",[t,e,i,s,r,n,a])},drawRect:function(t,e,i,s,r,n){return this._genShape("Rect",[t,e,i,s,r,n])},getElement:function(){return this.canvas},getLastShapeId:function(){return this.lastShapeId},reset:function(){alert("reset not implemented")},_insert:function(t,e){s(e).html(t)},_calculatePixelDims:function(t,e,i){var r;r=this._pxregex.exec(e),this.pixelHeight=r?r[1]:s(i).height(),r=this._pxregex.exec(t),this.pixelWidth=r?r[1]:s(i).width()},_genShape:function(t,e){var i=F++;return e.unshift(i),new I(this,i,t,e)},appendShape:function(t){alert("appendShape not implemented")},replaceWithShape:function(t,e){alert("replaceWithShape not implemented")},insertAfterShape:function(t,e){alert("insertAfterShape not implemented")},removeShapeId:function(t){alert("removeShapeId not implemented")},getShapeAt:function(t,e,i){alert("getShapeAt not implemented")},render:function(){alert("render not implemented")}}),P=a(j,{init:function(e,r,n,a){P._super.init.call(this,e,r,n),this.canvas=t.createElement("canvas"),n[0]&&(n=n[0]),s.data(n,"_jqs_vcanvas",this),s(this.canvas).css({display:"inline-block",width:e,height:r,verticalAlign:"top"}),this._insert(this.canvas,n),this._calculatePixelDims(e,r,this.canvas),this.canvas.width=this.pixelWidth,this.canvas.height=this.pixelHeight,this.interact=a,this.shapes={},this.shapeseq=[],this.currentTargetShapeId=i,s(this.canvas).css({width:this.pixelWidth,height:this.pixelHeight})},_getContext:function(t,e,s){var r=this.canvas.getContext("2d");return t!==i&&(r.strokeStyle=t),r.lineWidth=s===i?1:s,e!==i&&(r.fillStyle=e),r},reset:function(){var t=this._getContext();t.clearRect(0,0,this.pixelWidth,this.pixelHeight),this.shapes={},this.shapeseq=[],this.currentTargetShapeId=i},_drawShape:function(t,e,s,r,n){var a=this._getContext(s,r,n),h,o;for(a.beginPath(),a.moveTo(e[0][0]+.5,e[0][1]+.5),h=1,o=e.length;o>h;h++)a.lineTo(e[h][0]+.5,e[h][1]+.5);s!==i&&a.stroke(),r!==i&&a.fill(),this.targetX!==i&&this.targetY!==i&&a.isPointInPath(this.targetX,this.targetY)&&(this.currentTargetShapeId=t)},_drawCircle:function(t,s,r,n,a,h,o){var l=this._getContext(a,h,o);l.beginPath(),l.arc(s,r,n,0,2*e.PI,!1),this.targetX!==i&&this.targetY!==i&&l.isPointInPath(this.targetX,this.targetY)&&(this.currentTargetShapeId=t),a!==i&&l.stroke(),h!==i&&l.fill()},_drawPieSlice:function(t,e,s,r,n,a,h,o){var l=this._getContext(h,o);l.beginPath(),l.moveTo(e,s),l.arc(e,s,r,n,a,!1),l.lineTo(e,s),l.closePath(),h!==i&&l.stroke(),o&&l.fill(),this.targetX!==i&&this.targetY!==i&&l.isPointInPath(this.targetX,this.targetY)&&(this.currentTargetShapeId=t)},_drawRect:function(t,e,i,s,r,n,a){return this._drawShape(t,[[e,i],[e+s,i],[e+s,i+r],[e,i+r],[e,i]],n,a)},appendShape:function(t){return this.shapes[t.id]=t,this.shapeseq.push(t.id),this.lastShapeId=t.id,t.id},replaceWithShape:function(t,e){var i=this.shapeseq,s;for(this.shapes[e.id]=e,s=i.length;s--;)i[s]==t&&(i[s]=e.id);delete this.shapes[t]},replaceWithShapes:function(t,e){var i=this.shapeseq,s={},r,n,a;for(n=t.length;n--;)s[t[n]]=!0;for(n=i.length;n--;)r=i[n],s[r]&&(i.splice(n,1),delete this.shapes[r],a=n);for(n=e.length;n--;)i.splice(a,0,e[n].id),this.shapes[e[n].id]=e[n]},insertAfterShape:function(t,e){var i=this.shapeseq,s;for(s=i.length;s--;)if(i[s]===t)return i.splice(s+1,0,e.id),void(this.shapes[e.id]=e)},removeShapeId:function(t){var e=this.shapeseq,i;for(i=e.length;i--;)if(e[i]===t){e.splice(i,1);break}delete this.shapes[t]},getShapeAt:function(t,e,i){return this.targetX=e,this.targetY=i,this.render(),this.currentTargetShapeId},render:function(){var t=this.shapeseq,e=this.shapes,i=t.length,s=this._getContext(),r,n,a;for(s.clearRect(0,0,this.pixelWidth,this.pixelHeight),a=0;i>a;a++)r=t[a],n=e[r],this["_draw"+n.type].apply(this,n.args);this.interact||(this.shapes={},this.shapeseq=[])}}),L=a(j,{init:function(e,i,r){var n;L._super.init.call(this,e,i,r),r[0]&&(r=r[0]),s.data(r,"_jqs_vcanvas",this),this.canvas=t.createElement("span"),s(this.canvas).css({display:"inline-block",position:"relative",overflow:"hidden",width:e,height:i,margin:"0px",padding:"0px",verticalAlign:"top"}),this._insert(this.canvas,r),this._calculatePixelDims(e,i,this.canvas),this.canvas.width=this.pixelWidth,this.canvas.height=this.pixelHeight,n='',this.canvas.insertAdjacentHTML("beforeEnd",n),this.group=s(this.canvas).children()[0],this.rendered=!1,this.prerender=""},_drawShape:function(t,e,s,r,n){var a=[],h,o,l,g,p,u,c;for(c=0,u=e.length;u>c;c++)a[c]=""+e[c][0]+","+e[c][1];return h=a.splice(0,1),n=n===i?1:n,o=s===i?' stroked="false" ':' strokeWeight="'+n+'px" strokeColor="'+s+'" ',l=r===i?' filled="false"':' fillColor="'+r+'" filled="true" ',g=a[0]===a[a.length-1]?"x ":"",p=' '},_drawCircle:function(t,e,s,r,n,a,h){var o,l,g;return e-=r,s-=r,o=n===i?' stroked="false" ':' strokeWeight="'+h+'px" strokeColor="'+n+'" ',l=a===i?' filled="false"':' fillColor="'+a+'" filled="true" ',g=''},_drawPieSlice:function(t,s,r,n,a,h,o,l){var g,p,u,c,d,f,m,v;if(a===h)return"";if(h-a===2*e.PI&&(a=0,h=2*e.PI),p=s+e.round(e.cos(a)*n),u=r+e.round(e.sin(a)*n),c=s+e.round(e.cos(h)*n),d=r+e.round(e.sin(h)*n),p===c&&u===d){if(h-a ')},_drawRect:function(t,e,i,s,r,n,a){return this._drawShape(t,[[e,i],[e,i+r],[e+s,i+r],[e+s,i],[e,i]],n,a)},reset:function(){this.group.innerHTML=""},appendShape:function(t){var e=this["_draw"+t.type].apply(this,t.args);return this.rendered?this.group.insertAdjacentHTML("beforeEnd",e):this.prerender+=e,this.lastShapeId=t.id,t.id},replaceWithShape:function(t,e){var i=s("#jqsshape"+t),r=this["_draw"+e.type].apply(this,e.args);i[0].outerHTML=r},replaceWithShapes:function(t,e){var i=s("#jqsshape"+t[0]),r="",n=e.length,a;for(a=0;n>a;a++)r+=this["_draw"+e[a].type].apply(this,e[a].args);for(i[0].outerHTML=r,a=1;acurrentBlock-10;i--)Blocks.upsert("block_"+i,{_id:"block_"+i,number:i,gasUsed:web3.eth.block(i).gasUsed,size:web3.eth.block(i).size,time:web3.eth.block(i).time,hash:web3.eth.block(i).hash,miner:web3.eth.block(i).coinbase,uncles:web3.eth.block(i).uncles.Length})}catch(n){console.log("no web3 object")}},Template.views_home.destroyed=function(){},Template.views_home.helpers({blocks:function(){var e=Blocks.find({},{limit:50,sort:{number:-1}}),t=Template.instance();return Tracker.afterFlush(function(){t.view.isRendered&&t.$(".wrapper").css("width",562*e.count()+500+"px")}),e.fetch()},currentBlockPattern:function(){var e=GeoPattern.generate(this.hash);return e?e.toDataUrl():"white"},peerCount:function(){try{return web3.eth.peerCount}catch(e){return"---"}},gasPrice:function(){try{return EthTools.fromWei(web3.eth.gasPrice,"finney")}catch(e){return"---"}},miningSlider:function(){return Miner.mining||0},hashrate:function(){return Miner.hashrate},timeSpent:function(){var e=MiningData.findOne().totalTimeSpent;return e?180>e?Math.round(10*e)/10+" Seconds ":10800>e?Math.round(10*e/60)/10+" Minutes ":86400>e?Math.round(10*e/3600)/10+" Hours ":Math.round(10*e/86400)/10+" Days ":"---"},totalRewards:function(){var e=MiningData.findOne().totalRewards;return e&&e>0?1e3>e?Math.floor(100*e)/100+" Finney ":e>1e6?Math.floor(e/1e3).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")+" Ether ":Math.floor(e/10)/100+" Ether ":"---"},averageRewardPerHour:function(){var e=MiningData.findOne().totalRewards,t=MiningData.findOne().totalTimeSpent;if(e&&t>0){var n=3600*e/t;return 1e3>n?Math.floor(100*n)/100+" Finney/h ":n>1e6?Math.floor(n/1e3).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")+" Ether/h ":Math.floor(n/10)/100+" Ether/h ";return reward}return"---"}}),Template.views_home.events({"change input.slider-vertical, input input.slider-vertical":function(e){Miner.mining=Number(e.currentTarget.value)}})}(); - -!function(){Blocks=new Mongo.Collection("blocks",{connection:null}),new PersistentMinimongo(Blocks),MiningData=new Mongo.Collection("miningdata",{connection:null}),new PersistentMinimongo(MiningData),MiningData.findOne()||MiningData.insert({totalTimeSpent:0,lastCoinbaseBalance:0,totalRewards:0})}(); - -!function(){"localhost:3000"!==location.host&&"127.0.0.1:3000"!==location.host&&Meteor.disconnect(),Meteor.startup(function(){if(Cookie.get("TAPi18next"))TAPi18n.setLanguage(Cookie.get("TAPi18next"));else{var e=navigator.language||navigator.userLanguage,n=TAPi18n.getLanguages();TAPi18n.setLanguage(_.isObject(n)&&n[e]?e:_.isObject(n)&&n[e.substr(0,2)]?e.substr(0,2):"en")}Tracker.autorun(function(){_.isString(TAPi18n.getLanguage())&&(moment.locale(TAPi18n.getLanguage().substr(0,2)),numeral.language(TAPi18n.getLanguage().substr(0,2)))})})}(); - -!function(){var e=function(e,n,r){_.isUndefined(r)||(e["__tracker_"+n+"_value__"]=r),e["__tracker_"+n+"_dependency__"]=new Tracker.Dependency,Object.defineProperty(e,n,{get:function(){return this["__tracker_"+n+"_dependency__"].depend(),this["__tracker_"+n+"_value__"]},set:function(_){_!==this["__tracker_"+n+"_value__"]&&(this["__tracker_"+n+"_value__"]=_,this["__tracker_"+n+"_dependency__"].changed())}})};Miner={},e(Miner,"mining",0),e(Miner,"hashrate",0)}(); - -!function(){Router.configure({layoutTemplate:"layout_main",yieldRegions:{layout_header:{to:"header"}},autoRun:!1,autoRender:!1}),Router.route("/",{template:"views_home",name:"home"}),Router.route("/profile",{template:"views_home",name:"userProfile"})}(); - -!function(){var e=web3.eth.watch("chain");e.changed(function(e){if(e.number=web3.eth.number,Blocks.upsert("block_"+e.number,{_id:"block_"+e.number,number:e.number,gasUsed:web3.eth.block(e.number).gasUsed,size:web3.eth.block(e.number).size,time:web3.eth.block(e.number).time,hash:web3.eth.block(e.number).hash,miner:web3.eth.block(e.number).coinbase,uncles:web3.eth.block(e.number).uncles.Length}),web3.eth.coinbase==web3.eth.block(e.number).coinbase){var a=MiningData.findOne();WeiToFin=1e15,lastBalance=a.lastCoinbaseBalance||Number(web3.toDecimal(web3.eth.balanceAt(web3.eth.coinbase)))/WeiToFin,currentBalance=Number(web3.toDecimal(web3.eth.balanceAt(web3.eth.coinbase)))/WeiToFin,blockReward=currentBalance-lastBalance,console.log("New Block! last balance: "+a.lastCoinbaseBalance+" Reward: "+blockReward),MiningData.update(a._id,{$inc:{totalRewards:blockReward}}),MiningData.update(a._id,{$set:{lastCoinbaseBalance:currentBalance}})}else{WeiToFin=1e15,currentBalance=Number(web3.toDecimal(web3.eth.balanceAt(web3.eth.coinbase)))/WeiToFin;var a=MiningData.findOne();MiningData.update(a._id,{lastCoinbaseBalance:currentBalance}),console.log("New Block! last balance: "+a.lastCoinbaseBalance)}})}(); - -!function(){var n=Package.underscore._,e="project",o="project";"project"!=e&&(o=TAPi18n.packages[e].namespace),TAPi18n._enable({helper_name:"_",supported_languages:null,i18n_files_route:"/tap-i18n",cdn_path:null}),TAPi18n.languages_names.en=["English","English"],translations={},translations[o]={app:{loading:"Loading...",offline:"Can't connect are you offline?",logginIn:"Logging in..."},error:{insufficientRights:"You don't have enough rights for this action."},buttons:{ok:"OK",cancel:"Cancel",save:"Save",edit:"edit",send:"Send",create:"Create",tryToReconnect:"Try to reconnect"},commonWords:{you:"You",send:"Send",or:"or","with":"with",and:"and",on:"on",off:"off",per:"per"}},TAPi18n._loadLangFileObject("en",translations)}(); - -!function(){var e=Package.underscore._,n="project",a="project";"project"!=n&&(a=TAPi18n.packages[n].namespace),translations={},translations[a]={network:{home:{NetworkHealth:"Network Health",Mining:"Mining",MiningStatus:"Mining Status",on:"On",off:"Off",TimeSpent:"Time Spent",Rewards:"Rewards",AverageReward:"Average Reward",Connections:"Connections",PeerCount:"Peer Count",Peers:"Peers",GasPrice:"Gas Price",Finney:"Finney",Blockchain:"Blockchain",Block:"Block",GasUsed:"Gas Used",Size:"Size",Uncles:"Number of uncles",Time:"Time",EndOfBlocks:"No more loaded blocks"}}},TAPi18n._loadLangFileObject("en",translations)}(); - -!function(){TAPi18n._enable({helper_name:"i18n",supported_languages:["en","de"],i18n_files_route:"/i18n",cdn_path:null}),TAPi18n.languages_names.en=["English","English"],TAPi18n.languages_names.en=["English","English"],TAPi18n.languages_names.de=["German","Deutsch"]}(); \ No newline at end of file diff --git a/cmd/mist/assets/qml/views/network-health/529f30ee0ee386c5143b4ccb62073179ca8253c3.css b/cmd/mist/assets/qml/views/network-health/529f30ee0ee386c5143b4ccb62073179ca8253c3.css deleted file mode 100644 index 379e5808b..000000000 --- a/cmd/mist/assets/qml/views/network-health/529f30ee0ee386c5143b4ccb62073179ca8253c3.css +++ /dev/null @@ -1,4 +0,0 @@ -@font-face{font-family:'Simple-Line-Icons';src:url('packages/ethereum_elements/icons/Simple-Line-Icons.eot');src:url('packages/ethereum_elements/icons/Simple-Line-Icons.eot?') format('embedded-opentype'), - url('packages/ethereum_elements/icons/Simple-Line-Icons.woff') format('woff'), - url('packages/ethereum_elements/icons/Simple-Line-Icons.ttf') format('truetype'), - url('packages/ethereum_elements/icons/Simple-Line-Icons.svg') format('svg');font-weight:normal;font-style:normal}[data-icon]:before{font-family:'Simple-Line-Icons';content:attr(data-icon);speak:none;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-user-female,.icon-user-follow,.icon-user-following,.icon-user-unfollow,.icon-trophy,.icon-screen-smartphone,.icon-screen-desktop,.icon-plane,.icon-notebook,.icon-moustache,.icon-mouse,.icon-magnet,.icon-energy,.icon-emoticon-smile,.icon-disc,.icon-cursor-move,.icon-crop,.icon-credit-card,.icon-chemistry,.icon-user,.icon-speedometer,.icon-social-youtube,.icon-social-twitter,.icon-social-tumblr,.icon-social-facebook,.icon-social-dropbox,.icon-social-dribbble,.icon-shield,.icon-screen-tablet,.icon-magic-wand,.icon-hourglass,.icon-graduation,.icon-ghost,.icon-game-controller,.icon-fire,.icon-eyeglasses,.icon-envelope-open,.icon-envelope-letter,.icon-bell,.icon-badge,.icon-anchor,.icon-wallet,.icon-vector,.icon-speech,.icon-puzzle,.icon-printer,.icon-present,.icon-playlist,.icon-pin,.icon-picture,.icon-map,.icon-layers,.icon-handbag,.icon-globe-alt,.icon-globe,.icon-frame,.icon-folder-alt,.icon-film,.icon-feed,.icon-earphones-alt,.icon-earphones,.icon-drop,.icon-drawer,.icon-docs,.icon-directions,.icon-direction,.icon-diamond,.icon-cup,.icon-compass,.icon-call-out,.icon-call-in,.icon-call-end,.icon-calculator,.icon-bubbles,.icon-briefcase,.icon-book-open,.icon-basket-loaded,.icon-basket,.icon-bag,.icon-action-undo,.icon-action-redo,.icon-wrench,.icon-umbrella,.icon-trash,.icon-tag,.icon-support,.icon-size-fullscreen,.icon-size-actual,.icon-shuffle,.icon-share-alt,.icon-share,.icon-rocket,.icon-question,.icon-pie-chart,.icon-pencil,.icon-note,.icon-music-tone-alt,.icon-music-tone,.icon-microphone,.icon-loop,.icon-logout,.icon-login,.icon-list,.icon-like,.icon-home,.icon-grid,.icon-graph,.icon-equalizer,.icon-dislike,.icon-cursor,.icon-control-start,.icon-control-rewind,.icon-control-play,.icon-control-pause,.icon-control-forward,.icon-control-end,.icon-calendar,.icon-bulb,.icon-bar-chart,.icon-arrow-up,.icon-arrow-right,.icon-arrow-left,.icon-arrow-down,.icon-ban,.icon-bubble,.icon-camcorder,.icon-camera,.icon-check,.icon-clock,.icon-close,.icon-cloud-download,.icon-cloud-upload,.icon-doc,.icon-envelope,.icon-eye,.icon-flag,.icon-folder,.icon-heart,.icon-info,.icon-key,.icon-link,.icon-lock,.icon-lock-open,.icon-magnifier,.icon-magnifier-add,.icon-magnifier-remove,.icon-paper-clip,.icon-paper-plane,.icon-plus,.icon-pointer,.icon-power,.icon-refresh,.icon-reload,.icon-settings,.icon-star,.icon-symbol-female,.icon-symbol-male,.icon-target,.icon-volume-1,.icon-volume-2,.icon-volume-off,.icon-users{font-family:'Simple-Line-Icons';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased}.icon-user-female:before{content:"\e000"}.icon-user-follow:before{content:"\e002"}.icon-user-following:before{content:"\e003"}.icon-user-unfollow:before{content:"\e004"}.icon-trophy:before{content:"\e006"}.icon-screen-smartphone:before{content:"\e010"}.icon-screen-desktop:before{content:"\e011"}.icon-plane:before{content:"\e012"}.icon-notebook:before{content:"\e013"}.icon-moustache:before{content:"\e014"}.icon-mouse:before{content:"\e015"}.icon-magnet:before{content:"\e016"}.icon-energy:before{content:"\e020"}.icon-emoticon-smile:before{content:"\e021"}.icon-disc:before{content:"\e022"}.icon-cursor-move:before{content:"\e023"}.icon-crop:before{content:"\e024"}.icon-credit-card:before{content:"\e025"}.icon-chemistry:before{content:"\e026"}.icon-user:before{content:"\e005"}.icon-speedometer:before{content:"\e007"}.icon-social-youtube:before{content:"\e008"}.icon-social-twitter:before{content:"\e009"}.icon-social-tumblr:before{content:"\e00a"}.icon-social-facebook:before{content:"\e00b"}.icon-social-dropbox:before{content:"\e00c"}.icon-social-dribbble:before{content:"\e00d"}.icon-shield:before{content:"\e00e"}.icon-screen-tablet:before{content:"\e00f"}.icon-magic-wand:before{content:"\e017"}.icon-hourglass:before{content:"\e018"}.icon-graduation:before{content:"\e019"}.icon-ghost:before{content:"\e01a"}.icon-game-controller:before{content:"\e01b"}.icon-fire:before{content:"\e01c"}.icon-eyeglasses:before{content:"\e01d"}.icon-envelope-open:before{content:"\e01e"}.icon-envelope-letter:before{content:"\e01f"}.icon-bell:before{content:"\e027"}.icon-badge:before{content:"\e028"}.icon-anchor:before{content:"\e029"}.icon-wallet:before{content:"\e02a"}.icon-vector:before{content:"\e02b"}.icon-speech:before{content:"\e02c"}.icon-puzzle:before{content:"\e02d"}.icon-printer:before{content:"\e02e"}.icon-present:before{content:"\e02f"}.icon-playlist:before{content:"\e030"}.icon-pin:before{content:"\e031"}.icon-picture:before{content:"\e032"}.icon-map:before{content:"\e033"}.icon-layers:before{content:"\e034"}.icon-handbag:before{content:"\e035"}.icon-globe-alt:before{content:"\e036"}.icon-globe:before{content:"\e037"}.icon-frame:before{content:"\e038"}.icon-folder-alt:before{content:"\e039"}.icon-film:before{content:"\e03a"}.icon-feed:before{content:"\e03b"}.icon-earphones-alt:before{content:"\e03c"}.icon-earphones:before{content:"\e03d"}.icon-drop:before{content:"\e03e"}.icon-drawer:before{content:"\e03f"}.icon-docs:before{content:"\e040"}.icon-directions:before{content:"\e041"}.icon-direction:before{content:"\e042"}.icon-diamond:before{content:"\e043"}.icon-cup:before{content:"\e044"}.icon-compass:before{content:"\e045"}.icon-call-out:before{content:"\e046"}.icon-call-in:before{content:"\e047"}.icon-call-end:before{content:"\e048"}.icon-calculator:before{content:"\e049"}.icon-bubbles:before{content:"\e04a"}.icon-briefcase:before{content:"\e04b"}.icon-book-open:before{content:"\e04c"}.icon-basket-loaded:before{content:"\e04d"}.icon-basket:before{content:"\e04e"}.icon-bag:before{content:"\e04f"}.icon-action-undo:before{content:"\e050"}.icon-action-redo:before{content:"\e051"}.icon-wrench:before{content:"\e052"}.icon-umbrella:before{content:"\e053"}.icon-trash:before{content:"\e054"}.icon-tag:before{content:"\e055"}.icon-support:before{content:"\e056"}.icon-size-fullscreen:before{content:"\e057"}.icon-size-actual:before{content:"\e058"}.icon-shuffle:before{content:"\e059"}.icon-share-alt:before{content:"\e05a"}.icon-share:before{content:"\e05b"}.icon-rocket:before{content:"\e05c"}.icon-question:before{content:"\e05d"}.icon-pie-chart:before{content:"\e05e"}.icon-pencil:before{content:"\e05f"}.icon-note:before{content:"\e060"}.icon-music-tone-alt:before{content:"\e061"}.icon-music-tone:before{content:"\e062"}.icon-microphone:before{content:"\e063"}.icon-loop:before{content:"\e064"}.icon-logout:before{content:"\e065"}.icon-login:before{content:"\e066"}.icon-list:before{content:"\e067"}.icon-like:before{content:"\e068"}.icon-home:before{content:"\e069"}.icon-grid:before{content:"\e06a"}.icon-graph:before{content:"\e06b"}.icon-equalizer:before{content:"\e06c"}.icon-dislike:before{content:"\e06d"}.icon-cursor:before{content:"\e06e"}.icon-control-start:before{content:"\e06f"}.icon-control-rewind:before{content:"\e070"}.icon-control-play:before{content:"\e071"}.icon-control-pause:before{content:"\e072"}.icon-control-forward:before{content:"\e073"}.icon-control-end:before{content:"\e074"}.icon-calendar:before{content:"\e075"}.icon-bulb:before{content:"\e076"}.icon-bar-chart:before{content:"\e077"}.icon-arrow-up:before{content:"\e078"}.icon-arrow-right:before{content:"\e079"}.icon-arrow-left:before{content:"\e07a"}.icon-arrow-down:before{content:"\e07b"}.icon-ban:before{content:"\e07c"}.icon-bubble:before{content:"\e07d"}.icon-camcorder:before{content:"\e07e"}.icon-camera:before{content:"\e07f"}.icon-check:before{content:"\e080"}.icon-clock:before{content:"\e081"}.icon-close:before{content:"\e082"}.icon-cloud-download:before{content:"\e083"}.icon-cloud-upload:before{content:"\e084"}.icon-doc:before{content:"\e085"}.icon-envelope:before{content:"\e086"}.icon-eye:before{content:"\e087"}.icon-flag:before{content:"\e088"}.icon-folder:before{content:"\e089"}.icon-heart:before{content:"\e08a"}.icon-info:before{content:"\e08b"}.icon-key:before{content:"\e08c"}.icon-link:before{content:"\e08d"}.icon-lock:before{content:"\e08e"}.icon-lock-open:before{content:"\e08f"}.icon-magnifier:before{content:"\e090"}.icon-magnifier-add:before{content:"\e091"}.icon-magnifier-remove:before{content:"\e092"}.icon-paper-clip:before{content:"\e093"}.icon-paper-plane:before{content:"\e094"}.icon-plus:before{content:"\e095"}.icon-pointer:before{content:"\e096"}.icon-power:before{content:"\e097"}.icon-refresh:before{content:"\e098"}.icon-reload:before{content:"\e099"}.icon-settings:before{content:"\e09a"}.icon-star:before{content:"\e09b"}.icon-symbol-female:before{content:"\e09c"}.icon-symbol-male:before{content:"\e09d"}.icon-target:before{content:"\e09e"}.icon-volume-1:before{content:"\e09f"}.icon-volume-2:before{content:"\e0a0"}.icon-volume-off:before{content:"\e0a1"}.icon-users:before{content:"\e001"}body.disable-scroll{overflow:hidden}body.blur .dapp-flex-content,body.blur .dapp-footer,body.blur .dapp-header{-webkit-filter:blur(4px);-moz-filter:blur(4px);-ms-filter:blur(4px);filter:blur(4px)}.dapp-modal-overlay{z-index:99;position:fixed;top:0;left:0;right:0;bottom:0;display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-moz-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-moz-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;background:rgba(17, 17, 17, 0.5);-webkit-transition:opacity 400ms;-moz-transition:opacity 400ms;-o-transition:opacity 400ms;transition:opacity 400ms}.dapp-modal-overlay.animate{zoom:1;filter:alpha(opacity=0);-webkit-opacity:0;-moz-opacity:0;opacity:0}.dapp-modal-overlay.animate .dapp-modal-container{-webkit-transform:translateY(-20%);-moz-transform:translateY(-20%);-o-transform:translateY(-20%);-ms-transform:translateY(-20%);transform:translateY(-20%)}.dapp-modal-container{position:relative;width:448px;margin:110.4px auto;padding:18.4px 32px;background:#fafafa;box-sizing:border-box;box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);border-radius:3px;text-align:center;-webkit-transition:-webkit-transform 400ms;-moz-transition:-moz-transform 400ms;-o-transition:-o-transform 400ms;transition:-webkit-transform 400ms,-moz-transform 400ms,-o-transform 400ms,transform 400ms}.dapp-modal-container .dapp-modal-header{position:relative;padding:36.8px 0;margin:-18.4px -32px;margin-bottom:18.4px;border-radius:2px 2px 0 0;color:#111111;line-height:36.8px;text-align:center}.dapp-modal-container .dapp-modal-header.dapp-pattern{color:#fafafa}.dapp-modal-container .dapp-modal-header h1{margin:0}.dapp-modal-container .dapp-modal-header .dapp-identicon{position:absolute;top:-34.96px;left:50%;margin-left:-32px}.dapp-modal-container p{margin:36.8px 0;line-height:22.08px;font-size:1.2em}.dapp-overflow{overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch}.dapp-shadow-none{box-shadow:0 0 0 rgba(0, 0, 0, 0)}.dapp-shadow-small{box-shadow:0 0px 1px rgba(0, 0, 0, 0.3)}.dapp-shadow-medium{box-shadow:0 1px 4px rgba(0, 0, 0, 0.3)}.dapp-shadow-large{box-shadow:0 1px 16px rgba(0, 0, 0, 0.3)}.dapp-input{display:inline-block;width:300px;max-width:100%;margin-top:18.4px;padding:9.2px 16px;padding-bottom:6.13333333px;border:0;border-bottom:solid 2px #dddcdb;box-sizing:border-box;background-color:#f5f4f2;font-size:1em;font-weight:300;color:#6691c2}.dapp-input::-webkit-input-placeholder{color:#dddcdb}.dapp-input:-moz-placeholder{color:#dddcdb}.dapp-input::-moz-placeholder{color:#dddcdb}.dapp-input:-ms-input-placeholder{color:#dddcdb}.dapp-input:focus{outline:0}.dapp-input.dapp-large{font-size:1.5em}.dapp-input.dapp-error{color:#c20e25;background:rgba(194, 14, 37, 0.1);border-color:rgba(194, 14, 37, 0.15)}.dapp-input:disabled{color:#797673}.dapp-identicon{display:inline-block;width:64px;height:64px;border-radius:50%;background-size:cover;background-positon:50% 50%;box-shadow:inset rgba(255, 255, 255, 0.2) 0 2px 2px, inset rgba(0, 0, 0, 0.3) 0 -1px 8px}.dapp-identicon.dapp-small{width:32px;height:32px}.dapp-identicon.dapp-medium{width:48px;height:48px}.dapp-modal-buttons{position:relative;display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-moz-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;margin-top:16px}.dapp-modal-buttons button,.dapp-modal-buttons a,.dapp-modal-buttons a:visited{-webkit-box-flex:1;-moz-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;margin:0 8px;height:36.8px;line-height:36.8px;font-family:'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, Sans;font-size:0.9em;text-transform:uppercase;font-weight:400}.dapp-modal-buttons button.dapp-primary-button,.dapp-modal-buttons a.dapp-primary-button,.dapp-modal-buttons a:visited.dapp-primary-button{font-weight:600}.dapp-address-input{position:relative}.dapp-address-input input{display:inline-block;width:300px;max-width:100%;margin-top:18.4px;padding:9.2px 16px;padding-bottom:6.13333333px;border:0;border-bottom:solid 2px #dddcdb;box-sizing:border-box;background-color:#f5f4f2;font-size:1em;font-weight:300;color:#6691c2;z-index:1;margin-top:0;padding-left:48px}.dapp-address-input input::-webkit-input-placeholder{color:#dddcdb}.dapp-address-input input:-moz-placeholder{color:#dddcdb}.dapp-address-input input::-moz-placeholder{color:#dddcdb}.dapp-address-input input:-ms-input-placeholder{color:#dddcdb}.dapp-address-input input:focus{outline:0}.dapp-address-input input.dapp-large{font-size:1.5em}.dapp-address-input input.dapp-error{color:#c20e25;background:rgba(194, 14, 37, 0.1);border-color:rgba(194, 14, 37, 0.15)}.dapp-address-input input:disabled{color:#797673}.dapp-address-input input.dapp-large{font-size:1.5em}.dapp-address-input input.dapp-large+.dapp-identicon{top:6px;width:32px;height:32px}.dapp-address-input input.dapp-large+.icon-shield{top:12px}.dapp-address-input input.dapp-error{border-color:#c20e25}.dapp-address-input .dapp-identicon{z-index:2;position:absolute;top:3px;left:5px;width:26.66666667px;height:26.66666667px}.dapp-address-input .icon-shield{position:absolute;top:6px;left:13px;font-size:1.4em;color:#c20e25}@font-face{font-family:'Simple-Line-Icons';src:url('dapp-styles/icons/Simple-Line-Icons.eot');src:url('dapp-styles/icons/Simple-Line-Icons.eot?') format('embedded-opentype'), url('dapp-styles/icons/Simple-Line-Icons.woff') format('woff'), url('dapp-styles/icons/Simple-Line-Icons.ttf') format('truetype'), url('dapp-styles/icons/Simple-Line-Icons.svg') format('svg');font-weight:normal;font-style:normal}[data-icon]:before{font-family:'Simple-Line-Icons';content:attr(data-icon);speak:none;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-user-female,.icon-user-follow,.icon-user-following,.icon-user-unfollow,.icon-trophy,.icon-screen-smartphone,.icon-screen-desktop,.icon-plane,.icon-notebook,.icon-moustache,.icon-mouse,.icon-magnet,.icon-energy,.icon-emoticon-smile,.icon-disc,.icon-cursor-move,.icon-crop,.icon-credit-card,.icon-chemistry,.icon-user,.icon-speedometer,.icon-social-youtube,.icon-social-twitter,.icon-social-tumblr,.icon-social-facebook,.icon-social-dropbox,.icon-social-dribbble,.icon-shield,.icon-screen-tablet,.icon-magic-wand,.icon-hourglass,.icon-graduation,.icon-ghost,.icon-game-controller,.icon-fire,.icon-eyeglasses,.icon-envelope-open,.icon-envelope-letter,.icon-bell,.icon-badge,.icon-anchor,.icon-wallet,.icon-vector,.icon-speech,.icon-puzzle,.icon-printer,.icon-present,.icon-playlist,.icon-pin,.icon-picture,.icon-map,.icon-layers,.icon-handbag,.icon-globe-alt,.icon-globe,.icon-frame,.icon-folder-alt,.icon-film,.icon-feed,.icon-earphones-alt,.icon-earphones,.icon-drop,.icon-drawer,.icon-docs,.icon-directions,.icon-direction,.icon-diamond,.icon-cup,.icon-compass,.icon-call-out,.icon-call-in,.icon-call-end,.icon-calculator,.icon-bubbles,.icon-briefcase,.icon-book-open,.icon-basket-loaded,.icon-basket,.icon-bag,.icon-action-undo,.icon-action-redo,.icon-wrench,.icon-umbrella,.icon-trash,.icon-tag,.icon-support,.icon-size-fullscreen,.icon-size-actual,.icon-shuffle,.icon-share-alt,.icon-share,.icon-rocket,.icon-question,.icon-pie-chart,.icon-pencil,.icon-note,.icon-music-tone-alt,.icon-music-tone,.icon-microphone,.icon-loop,.icon-logout,.icon-login,.icon-list,.icon-like,.icon-home,.icon-grid,.icon-graph,.icon-equalizer,.icon-dislike,.icon-cursor,.icon-control-start,.icon-control-rewind,.icon-control-play,.icon-control-pause,.icon-control-forward,.icon-control-end,.icon-calendar,.icon-bulb,.icon-bar-chart,.icon-arrow-up,.icon-arrow-right,.icon-arrow-left,.icon-arrow-down,.icon-ban,.icon-bubble,.icon-camcorder,.icon-camera,.icon-check,.icon-clock,.icon-close,.icon-cloud-download,.icon-cloud-upload,.icon-doc,.icon-envelope,.icon-eye,.icon-flag,.icon-folder,.icon-heart,.icon-info,.icon-key,.icon-link,.icon-lock,.icon-lock-open,.icon-magnifier,.icon-magnifier-add,.icon-magnifier-remove,.icon-paper-clip,.icon-paper-plane,.icon-plus,.icon-pointer,.icon-power,.icon-refresh,.icon-reload,.icon-settings,.icon-star,.icon-symbol-female,.icon-symbol-male,.icon-target,.icon-volume-1,.icon-volume-2,.icon-volume-off,.icon-users{font-family:'Simple-Line-Icons';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased}.icon-user-female:before{content:"\e000"}.icon-user-follow:before{content:"\e002"}.icon-user-following:before{content:"\e003"}.icon-user-unfollow:before{content:"\e004"}.icon-trophy:before{content:"\e006"}.icon-screen-smartphone:before{content:"\e010"}.icon-screen-desktop:before{content:"\e011"}.icon-plane:before{content:"\e012"}.icon-notebook:before{content:"\e013"}.icon-moustache:before{content:"\e014"}.icon-mouse:before{content:"\e015"}.icon-magnet:before{content:"\e016"}.icon-energy:before{content:"\e020"}.icon-emoticon-smile:before{content:"\e021"}.icon-disc:before{content:"\e022"}.icon-cursor-move:before{content:"\e023"}.icon-crop:before{content:"\e024"}.icon-credit-card:before{content:"\e025"}.icon-chemistry:before{content:"\e026"}.icon-user:before{content:"\e005"}.icon-speedometer:before{content:"\e007"}.icon-social-youtube:before{content:"\e008"}.icon-social-twitter:before{content:"\e009"}.icon-social-tumblr:before{content:"\e00a"}.icon-social-facebook:before{content:"\e00b"}.icon-social-dropbox:before{content:"\e00c"}.icon-social-dribbble:before{content:"\e00d"}.icon-shield:before{content:"\e00e"}.icon-screen-tablet:before{content:"\e00f"}.icon-magic-wand:before{content:"\e017"}.icon-hourglass:before{content:"\e018"}.icon-graduation:before{content:"\e019"}.icon-ghost:before{content:"\e01a"}.icon-game-controller:before{content:"\e01b"}.icon-fire:before{content:"\e01c"}.icon-eyeglasses:before{content:"\e01d"}.icon-envelope-open:before{content:"\e01e"}.icon-envelope-letter:before{content:"\e01f"}.icon-bell:before{content:"\e027"}.icon-badge:before{content:"\e028"}.icon-anchor:before{content:"\e029"}.icon-wallet:before{content:"\e02a"}.icon-vector:before{content:"\e02b"}.icon-speech:before{content:"\e02c"}.icon-puzzle:before{content:"\e02d"}.icon-printer:before{content:"\e02e"}.icon-present:before{content:"\e02f"}.icon-playlist:before{content:"\e030"}.icon-pin:before{content:"\e031"}.icon-picture:before{content:"\e032"}.icon-map:before{content:"\e033"}.icon-layers:before{content:"\e034"}.icon-handbag:before{content:"\e035"}.icon-globe-alt:before{content:"\e036"}.icon-globe:before{content:"\e037"}.icon-frame:before{content:"\e038"}.icon-folder-alt:before{content:"\e039"}.icon-film:before{content:"\e03a"}.icon-feed:before{content:"\e03b"}.icon-earphones-alt:before{content:"\e03c"}.icon-earphones:before{content:"\e03d"}.icon-drop:before{content:"\e03e"}.icon-drawer:before{content:"\e03f"}.icon-docs:before{content:"\e040"}.icon-directions:before{content:"\e041"}.icon-direction:before{content:"\e042"}.icon-diamond:before{content:"\e043"}.icon-cup:before{content:"\e044"}.icon-compass:before{content:"\e045"}.icon-call-out:before{content:"\e046"}.icon-call-in:before{content:"\e047"}.icon-call-end:before{content:"\e048"}.icon-calculator:before{content:"\e049"}.icon-bubbles:before{content:"\e04a"}.icon-briefcase:before{content:"\e04b"}.icon-book-open:before{content:"\e04c"}.icon-basket-loaded:before{content:"\e04d"}.icon-basket:before{content:"\e04e"}.icon-bag:before{content:"\e04f"}.icon-action-undo:before{content:"\e050"}.icon-action-redo:before{content:"\e051"}.icon-wrench:before{content:"\e052"}.icon-umbrella:before{content:"\e053"}.icon-trash:before{content:"\e054"}.icon-tag:before{content:"\e055"}.icon-support:before{content:"\e056"}.icon-size-fullscreen:before{content:"\e057"}.icon-size-actual:before{content:"\e058"}.icon-shuffle:before{content:"\e059"}.icon-share-alt:before{content:"\e05a"}.icon-share:before{content:"\e05b"}.icon-rocket:before{content:"\e05c"}.icon-question:before{content:"\e05d"}.icon-pie-chart:before{content:"\e05e"}.icon-pencil:before{content:"\e05f"}.icon-note:before{content:"\e060"}.icon-music-tone-alt:before{content:"\e061"}.icon-music-tone:before{content:"\e062"}.icon-microphone:before{content:"\e063"}.icon-loop:before{content:"\e064"}.icon-logout:before{content:"\e065"}.icon-login:before{content:"\e066"}.icon-list:before{content:"\e067"}.icon-like:before{content:"\e068"}.icon-home:before{content:"\e069"}.icon-grid:before{content:"\e06a"}.icon-graph:before{content:"\e06b"}.icon-equalizer:before{content:"\e06c"}.icon-dislike:before{content:"\e06d"}.icon-cursor:before{content:"\e06e"}.icon-control-start:before{content:"\e06f"}.icon-control-rewind:before{content:"\e070"}.icon-control-play:before{content:"\e071"}.icon-control-pause:before{content:"\e072"}.icon-control-forward:before{content:"\e073"}.icon-control-end:before{content:"\e074"}.icon-calendar:before{content:"\e075"}.icon-bulb:before{content:"\e076"}.icon-bar-chart:before{content:"\e077"}.icon-arrow-up:before{content:"\e078"}.icon-arrow-right:before{content:"\e079"}.icon-arrow-left:before{content:"\e07a"}.icon-arrow-down:before{content:"\e07b"}.icon-ban:before{content:"\e07c"}.icon-bubble:before{content:"\e07d"}.icon-camcorder:before{content:"\e07e"}.icon-camera:before{content:"\e07f"}.icon-check:before{content:"\e080"}.icon-clock:before{content:"\e081"}.icon-close:before{content:"\e082"}.icon-cloud-download:before{content:"\e083"}.icon-cloud-upload:before{content:"\e084"}.icon-doc:before{content:"\e085"}.icon-envelope:before{content:"\e086"}.icon-eye:before{content:"\e087"}.icon-flag:before{content:"\e088"}.icon-folder:before{content:"\e089"}.icon-heart:before{content:"\e08a"}.icon-info:before{content:"\e08b"}.icon-key:before{content:"\e08c"}.icon-link:before{content:"\e08d"}.icon-lock:before{content:"\e08e"}.icon-lock-open:before{content:"\e08f"}.icon-magnifier:before{content:"\e090"}.icon-magnifier-add:before{content:"\e091"}.icon-magnifier-remove:before{content:"\e092"}.icon-paper-clip:before{content:"\e093"}.icon-paper-plane:before{content:"\e094"}.icon-plus:before{content:"\e095"}.icon-pointer:before{content:"\e096"}.icon-power:before{content:"\e097"}.icon-refresh:before{content:"\e098"}.icon-reload:before{content:"\e099"}.icon-settings:before{content:"\e09a"}.icon-star:before{content:"\e09b"}.icon-symbol-female:before{content:"\e09c"}.icon-symbol-male:before{content:"\e09d"}.icon-target:before{content:"\e09e"}.icon-volume-1:before{content:"\e09f"}.icon-volume-2:before{content:"\e0a0"}.icon-volume-off:before{content:"\e0a1"}.icon-users:before{content:"\e001"}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:0.67em 0}h2{font-size:1.5em;margin:0.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:0.83em;margin:1.67em 0}h6{font-size:0.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace, serif;_font-family:'courier new', monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic;}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px;}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible;}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}html,button,input,select,textarea{font-family:sans-serif}body,form,fieldset,legend,input,select,textarea,button{margin:0}html{font-size:100%}.section{position:relative}.container{max-width:960px;margin-left:auto;margin-right:auto;padding-left:10px;padding-right:10px}.container-full{max-width:960px;margin-left:auto;margin-right:auto}.col{float:left;padding-left:10px;padding-right:10px}[class*="pull-"],[class*="push-"]{position:relative}.no-gutter{padding-left:0;padding-right:0}.col-1{width:8.33333%;width:calc(100% / 12 * 1);width:-webkit-calc(100% / 12 * 1);width:-moz-calc(100% / 12 * 1)}.col-2{width:16.66667%;width:calc(100% / 12 * 2);width:-webkit-calc(100% / 12 * 2);width:-moz-calc(100% / 12 * 2)}.col-3,.col-1-4{width:25%;width:calc(100% / 12 * 3);width:-webkit-calc(100% / 12 * 3);width:-moz-calc(100% / 12 * 3)}.col-4,.col-1-3{width:33.33333%;width:calc(100% / 12 * 4);width:-webkit-calc(100% / 12 * 4);width:-moz-calc(100% / 12 * 4)}.col-5{width:41.66665%;width:calc(100% / 12 * 5);width:-webkit-calc(100% / 12 * 5);width:-moz-calc(100% / 12 * 5)}.col-6,.col-1-2{width:50%;width:calc(100% / 12 * 6);width:-webkit-calc(100% / 12 * 6);width:-moz-calc(100% / 12 * 6)}.col-7{width:58.33333%;width:calc(100% / 12 * 7);width:-webkit-calc(100% / 12 * 7);width:-moz-calc(100% / 12 * 7)}.col-8{width:66.66666%;width:calc(100% / 12 * 8);width:-webkit-calc(100% / 12 * 8);width:-moz-calc(100% / 12 * 8)}.col-9,.col-3-4{width:75%;width:calc(100% / 12 * 9);width:-webkit-calc(100% / 12 * 9);width:-moz-calc(100% / 12 * 9)}.col-10{width:83.33333%;width:calc(100% / 12 * 10);width:-webkit-calc(100% / 12 * 10);width:-moz-calc(100% / 12 * 10)}.col-11{width:91.66666%;width:calc(100% / 12 * 11);width:-webkit-calc(100% / 12 * 11);width:-moz-calc(100% / 12 * 11)}.col-12{width:100%}.push-1{left:8.33333%;left:calc(100% / 12 * 1);left:-webkit-calc(100% / 12 * 1);left:-moz-calc(100% / 12 * 1)}.pull-1{left:-8.33333%;left:calc(-100% / 12 * 1);left:-webkit-calc(-100% / 12 * 1);left:-moz-calc(-100% / 12 * 1)}.push-2{left:16.66667%;left:calc(100% / 12 * 2);left:-webkit-calc(100% / 12 * 2);left:-moz-calc(100% / 12 * 2)}.pull-2{left:-16.66667%;left:calc(-100% / 12 * 2);left:-webkit-calc(-100% / 12 * 2);left:-moz-calc(-100% / 12 * 2)}.push-3,.push-1-4{left:25%;left:calc(100% / 12 * 3);left:-webkit-calc(100% / 12 * 3);left:-moz-calc(100% / 12 * 3)}.pull-3,.pull-1-4{left:-25%;left:calc(-100% / 12 * 3);left:-webkit-calc(-100% / 12 * 3);left:-moz-calc(-100% / 12 * 3)}.push-4,.push-1-3{left:33.33333%;left:calc(100% / 12 * 4);left:-webkit-calc(100% / 12 * 4);left:-moz-calc(100% / 12 * 4)}.pull-4,.pull-1-3{left:-33.33333%;left:calc(-100% / 12 * 4);left:-webkit-calc(-100% / 12 * 4);left:-moz-calc(-100% / 12 * 4)}.push-5{left:41.66665%;left:calc(100% / 12 * 5);left:-webkit-calc(100% / 12 * 5);left:-moz-calc(100% / 12 * 5)}.pull-5{left:-41.66665%;left:calc(-100% / 12 * 5);left:-webkit-calc(-100% / 12 * 5);left:-moz-calc(-100% / 12 * 5)}.push-6,.push-1-2{left:50%;left:calc(100% / 12 * 6);left:-webkit-calc(100% / 12 * 6);left:-moz-calc(100% / 12 * 6)}.pull-6,.pull-1-2{left:-50%;left:calc(-100% / 12 * 6);left:-webkit-calc(-100% / 12 * 6);left:-moz-calc(-100% / 12 * 6)}.push-7{left:58.33333%;left:calc(100% / 12 * 7);left:-webkit-calc(100% / 12 * 7);left:-moz-calc(100% / 12 * 7)}.pull-7{left:-58.33333%;left:calc(-100% / 12 * 7);left:-webkit-calc(-100% / 12 * 7);left:-moz-calc(-100% / 12 * 7)}.push-8{left:66.66666%;left:calc(100% / 12 * 8);left:-webkit-calc(100% / 12 * 8);left:-moz-calc(100% / 12 * 8)}.pull-8{left:-66.66666%;left:calc(-100% / 12 * 8);left:-webkit-calc(-100% / 12 * 8);left:-moz-calc(-100% / 12 * 8)}.push-9,.push-3-4{left:75%;left:calc(100% / 12 * 9);left:-webkit-calc(100% / 12 * 9);left:-moz-calc(100% / 12 * 9)}.pull-9,.pull-3-4{left:-75%;left:calc(-100% / 12 * 9);left:-webkit-calc(-100% / 12 * 9);left:-moz-calc(-100% / 12 * 9)}.push-10{left:83.33333%;left:calc(100% / 12 * 10);left:-webkit-calc(100% / 12 * 10);left:-moz-calc(100% / 12 * 10)}.pull-10{left:-83.33333%;left:calc(-100% / 12 * 10);left:-webkit-calc(-100% / 12 * 10);left:-moz-calc(-100% / 12 * 10)}.push-11{left:91.66666%;left:calc(100% / 12 * 11);left:-webkit-calc(100% / 12 * 11);left:-moz-calc(100% / 12 * 11)}.pull-11{left:-91.66666%;left:calc(-100% / 12 * 11);left:-webkit-calc(-100% / 12 * 11);left:-moz-calc(-100% / 12 * 11)}.row{padding-top:1em;padding-bottom:1em}.no-desktop{display:none}.no-margin{margin:0}.no-padding{padding:0}@media only screen and (min-width: 660px) and (max-width: 959px){.container,.tablet-container{max-width:960px;padding-left:20px;padding-right:20px;margin-left:auto;margin-right:auto;float:none}.container:first-child,.tablet-container:first-child{margin-left:auto}.tablet-container-full{padding-left:0;padding-right:0;margin-left:auto;margin-right:auto;float:none}.tablet-container-full:first-child{margin-left:auto}.tablet-no-gutter{padding-left:0;padding-right:0}.tablet-col-1{width:8.33333%;width:calc(100% / 12 * 1);width:-webkit-calc(100% / 12 * 1);width:-moz-calc(100% / 12 * 1)}.tablet-col-2{width:16.66667%;width:calc(100% / 12 * 2);width:-webkit-calc(100% / 12 * 2);width:-moz-calc(100% / 12 * 2)}.tablet-col-3,.tablet-col-1-4{width:25%;width:calc(100% / 12 * 3);width:-webkit-calc(100% / 12 * 3);width:-moz-calc(100% / 12 * 3)}.tablet-col-4,.tablet-col-1-3{width:33.33333%;width:calc(100% / 12 * 4);width:-webkit-calc(100% / 12 * 4);width:-moz-calc(100% / 12 * 4)}.tablet-col-5{width:41.66665%;width:calc(100% / 12 * 5);width:-webkit-calc(100% / 12 * 5);width:-moz-calc(100% / 12 * 5)}.tablet-col-6,.tablet-col-1-2{width:50%;width:calc(100% / 12 * 6);width:-webkit-calc(100% / 12 * 6);width:-moz-calc(100% / 12 * 6)}.tablet-col-7{width:58.33333%;width:calc(100% / 12 * 7);width:-webkit-calc(100% / 12 * 7);width:-moz-calc(100% / 12 * 7)}.tablet-col-8{width:66.66666%;width:calc(100% / 12 * 8);width:-webkit-calc(100% / 12 * 8);width:-moz-calc(100% / 12 * 8)}.tablet-col-9,.tablet-col-3-4{width:75%;width:calc(100% / 12 * 9);width:-webkit-calc(100% / 12 * 9);width:-moz-calc(100% / 12 * 9)}.tablet-col-10{width:83.33333%;width:calc(100% / 12 * 10);width:-webkit-calc(100% / 12 * 10);width:-moz-calc(100% / 12 * 10)}.tablet-col-11{width:91.66666%;width:calc(100% / 12 * 11);width:-webkit-calc(100% / 12 * 11);width:-moz-calc(100% / 12 * 11)}.tablet-col-12{width:100%}.tablet-push-1{left:8.33333%;left:calc(100% / 12 * 1);left:-webkit-calc(100% / 12 * 1);left:-moz-calc(100% / 12 * 1)}.tablet-pull-1{left:-8.33333%;left:calc(-100% / 12 * 1);left:-webkit-calc(-100% / 12 * 1);left:-moz-calc(-100% / 12 * 1)}.tablet-push-2{left:16.66667%;left:calc(100% / 12 * 2);left:-webkit-calc(100% / 12 * 2);left:-moz-calc(100% / 12 * 2)}.tablet-pull-2{left:-16.66667%;left:calc(-100% / 12 * 2);left:-webkit-calc(-100% / 12 * 2);left:-moz-calc(-100% / 12 * 2)}.tablet-push-3,.tablet-push-1-4{left:25%;left:calc(100% / 12 * 3);left:-webkit-calc(100% / 12 * 3);left:-moz-calc(100% / 12 * 3)}.tablet-pull-3,.tablet-pull-1-4{left:-25%;left:calc(-100% / 12 * 3);left:-webkit-calc(-100% / 12 * 3);left:-moz-calc(-100% / 12 * 3)}.tablet-push-4,.tablet-push-1-3{left:33.33333%;left:calc(100% / 12 * 4);left:-webkit-calc(100% / 12 * 4);left:-moz-calc(100% / 12 * 4)}.tablet-pull-4,.tablet-pull-1-3{left:-33.33333%;left:calc(-100% / 12 * 4);left:-webkit-calc(-100% / 12 * 4);left:-moz-calc(-100% / 12 * 4)}.tablet-push-5{left:41.66665%;left:calc(100% / 12 * 5);left:-webkit-calc(100% / 12 * 5);left:-moz-calc(100% / 12 * 5)}.tablet-pull-5{left:-41.66665%;left:calc(-100% / 12 * 5);left:-webkit-calc(-100% / 12 * 5);left:-moz-calc(-100% / 12 * 5)}.tablet-push-6,.tablet-push-1-2{left:50%;left:calc(100% / 12 * 6);left:-webkit-calc(100% / 12 * 6);left:-moz-calc(100% / 12 * 6)}.tablet-pull-6,.tablet-pull-1-2{left:-50%;left:calc(-100% / 12 * 6);left:-webkit-calc(-100% / 12 * 6);left:-moz-calc(-100% / 12 * 6)}.tablet-push-7{left:58.33333%;left:calc(100% / 12 * 7);left:-webkit-calc(100% / 12 * 7);left:-moz-calc(100% / 12 * 7)}.tablet-pull-7{left:-58.33333%;left:calc(-100% / 12 * 7);left:-webkit-calc(-100% / 12 * 7);left:-moz-calc(-100% / 12 * 7)}.tablet-push-8{left:66.66666%;left:calc(100% / 12 * 8);left:-webkit-calc(100% / 12 * 8);left:-moz-calc(100% / 12 * 8)}.tablet-pull-8{left:-66.66666%;left:calc(-100% / 12 * 8);left:-webkit-calc(-100% / 12 * 8);left:-moz-calc(-100% / 12 * 8)}.tablet-push-9,.tablet-push-3-4{left:75%;left:calc(100% / 12 * 9);left:-webkit-calc(100% / 12 * 9);left:-moz-calc(100% / 12 * 9)}.tablet-pull-9,.tablet-pull-3-4{left:-75%;left:calc(-100% / 12 * 9);left:-webkit-calc(-100% / 12 * 9);left:-moz-calc(-100% / 12 * 9)}.tablet-push-10{left:83.33333%;left:calc(100% / 12 * 10);left:-webkit-calc(100% / 12 * 10);left:-moz-calc(100% / 12 * 10)}.tablet-pull-10{left:-83.33333%;left:calc(-100% / 12 * 10);left:-webkit-calc(-100% / 12 * 10);left:-moz-calc(-100% / 12 * 10)}.tablet-push-11{left:91.66666%;left:calc(100% / 12 * 11);left:-webkit-calc(100% / 12 * 11);left:-moz-calc(100% / 12 * 11)}.tablet-pull-11{left:-91.66666%;left:calc(-100% / 12 * 11);left:-webkit-calc(-100% / 12 * 11);left:-moz-calc(-100% / 12 * 11)}.tablet-no-push,.tablet-no-pull{left:auto}.tablet-row{padding-top:1em;padding-bottom:1em}.tablet-full{left:auto;clear:both;float:none;width:100%;margin:1em 0 0 0;display:block}.tablet-full:first-child{margin-top:0}.tablet-text-left{text-align:left}.tablet-text-right{text-align:right}.tablet-text-center{text-align:center}.tablet-left{float:left}.tablet-right{float:right}.tablet-no-float{float:none}.tablet-no-margin{margin:0}.tablet-no-padding{padding:0}.no-tablet{display:none}.show-tablet{display:block}}@media only screen and (max-width: 659px){.container,.mobile-container{padding-left:20px;padding-right:20px;margin-left:auto;margin-right:auto;float:none}.container:first-child,.mobile-container:first-child{margin-left:auto}.mobile-container-full{padding-left:0;padding-right:0;margin-left:auto;margin-right:auto;float:none}.mobile-container-full:first-child{margin-left:auto}.mobile-no-gutter{padding-left:0;padding-right:0}.mobile-col-1-2{width:50%;width:calc(100% / 12 * 6);width:-webkit-calc(100% / 12 * 6);width:-moz-calc(100% / 12 * 6)}.mobile-col-1-3{width:33.33333%;width:calc(100% / 12 * 4);width:-webkit-calc(100% / 12 * 4);width:-moz-calc(100% / 12 * 4)}.mobile-col-1-4{width:25%;width:calc(100% / 12 * 3);width:-webkit-calc(100% / 12 * 3);width:-moz-calc(100% / 12 * 3)}.mobile-col-3-4{width:75%;width:calc(100% / 12 * 9);width:-webkit-calc(100% / 12 * 9);width:-moz-calc(100% / 12 * 9)}.mobile-push-1-2{left:50%;left:calc(100% / 12 * 6);left:-webkit-calc(100% / 12 * 6);left:-moz-calc(100% / 12 * 6)}.mobile-pull-1-2{left:-50%;left:calc(-100% / 12 * 6);left:-webkit-calc(-100% / 12 * 6);left:-moz-calc(-100% / 12 * 6)}.mobile-push-1-3{left:25%;left:calc(100% / 12 * 3);left:-webkit-calc(100% / 12 * 3);left:-moz-calc(100% / 12 * 3)}.mobile-pull-1-3{left:-25%;left:calc(-100% / 12 * 3);left:-webkit-calc(-100% / 12 * 3);left:-moz-calc(-100% / 12 * 3)}.mobile-push-1-4{left:33.33333%;left:calc(100% / 12 * 4);left:-webkit-calc(100% / 12 * 4);left:-moz-calc(100% / 12 * 4)}.mobile-pull-1-4{left:-33.33333%;left:calc(-100% / 12 * 4);left:-webkit-calc(-100% / 12 * 4);left:-moz-calc(-100% / 12 * 4)}.mobile-push-3-4{left:75%;left:calc(100% / 12 * 9);left:-webkit-calc(100% / 12 * 9);left:-moz-calc(100% / 12 * 9)}.mobile-pull-3-4{left:-75%;left:calc(-100% / 12 * 9);left:-webkit-calc(-100% / 12 * 9);left:-moz-calc(-100% / 12 * 9)}.mobile-no-push,.mobile-no-pull{left:auto}.mobile-row{padding-top:1em;padding-bottom:1em}.mobile-full{left:auto;clear:both;float:none;width:100%;margin:0.2em 0 0 0;display:block}.mobile-full:first-child{margin-top:0}.mobile-text-left{text-align:left}.mobile-text-right{text-align:right}.mobile-text-center{text-align:center}.mobile-left{float:left}.mobile-right{float:right}.mobile-no-float{float:none}.mobile-no-margin{margin:0}.mobile-no-padding{padding:0}.no-mobile{display:none}.show-mobile{display:block}}@media print{*{background:transparent}a,a:visited{text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%}@page {margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}@font-face{font-family:'Source Sans Pro';src:url('dapp-styles/fonts/SourceSansPro-ExtraLight.otf');font-weight:100;font-style:normal}@font-face{font-family:'Source Sans Pro';src:url('dapp-styles/fonts/SourceSansPro-ExtraLightIt.otf');font-weight:100;font-style:italic}@font-face{font-family:'Source Sans Pro';src:url('dapp-styles/fonts/SourceSansPro-Light.otf');font-weight:300;font-style:normal}@font-face{font-family:'Source Sans Pro';src:url('dapp-styles/fonts/SourceSansPro-Regular.otf');font-weight:400;font-style:normal}@font-face{font-family:'Source Sans Pro';src:url('dapp-styles/fonts/SourceSansPro-Semibold.otf');font-weight:500;font-style:normal}@font-face{font-family:'Source Sans Pro';src:url('dapp-styles/fonts/SourceSansPro-Bold.otf');font-weight:700;font-style:normal}@font-face{font-family:'Montserrat';src:url('dapp-styles/fonts/Montserrat-Regular.otf');font-weight:400;font-style:normal}.dapp-clear-fix{clear:both}.dapp-overflow{overflow:auto;-webkit-overflow-scrolling:touch}.dapp-shorten-text{display:inline-block;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%}.dapp-button-reset{background:none;border:0;padding:0;margin:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.dapp-button-reset:hover,.dapp-button-reset:focus{outline:0}.dapp-shadow-none{-webkit-box-shadow:0 0 0 rgba(0, 0, 0, 0);-moz-box-shadow:0 0 0 rgba(0, 0, 0, 0);box-shadow:0 0 0 rgba(0, 0, 0, 0)}.dapp-shadow-small{-webkit-box-shadow:0 0px 1px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 0px 1px rgba(0, 0, 0, 0.3);box-shadow:0 0px 1px rgba(0, 0, 0, 0.3)}.dapp-shadow-medium{-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);box-shadow:0 1px 4px rgba(0, 0, 0, 0.3)}.dapp-shadow-large{-webkit-box-shadow:0 1px 16px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 1px 16px rgba(0, 0, 0, 0.3);box-shadow:0 1px 16px rgba(0, 0, 0, 0.3)}.dapp-horizontal-menu,.dapp-vertical-menu{padding:0;margin:0;list-style:none}.dapp-horizontal-menu li{display:inline-block;padding:0;margin:0}.dapp-vertical-menu li{display:block;padding:0;margin:0}.cubic-bezier{-webkit-transition-timing-function:cubic-bezier(0.15, 0.3, 0.1, 1);-moz-transition-timing-function:cubic-bezier(0.15, 0.3, 0.1, 1);-o-transition-timing-function:cubic-bezier(0.15, 0.3, 0.1, 1);transition-timing-function:cubic-bezier(0.15, 0.3, 0.1, 1)}.cubic-bezier.animate{-webkit-transition-timing-function:cubic-bezier(0.5, 0.1, 0.2, 1);-moz-transition-timing-function:cubic-bezier(0.5, 0.1, 0.2, 1);-o-transition-timing-function:cubic-bezier(0.5, 0.1, 0.2, 1);transition-timing-function:cubic-bezier(0.5, 0.1, 0.2, 1)}#dapp-form-helper-iframe{display:none}.dapp-message{position:relative;max-width:512px;margin:48px 0;font-size:1.5em;font-weight:100;line-height:27pt}.dapp-count{display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:0;bottom:0;right:0;padding:0 8px;color:#fafafa;font-weight:100;zoom:1;filter:alpha(opacity=70);-webkit-opacity:0.7;-moz-opacity:0.7;opacity:0.7;-webkit-transition:opacity 400ms;-moz-transition:opacity 400ms;-o-transition:opacity 400ms;transition:opacity 400ms}.dapp-count.animate{zoom:1;filter:alpha(opacity=0);-webkit-opacity:0;-moz-opacity:0;opacity:0}.active .dapp-count{background-color:#f5f4f2;color:#9c9090}.dapp-url-bar{display:block;text-align:center;width:100%;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px}.dapp-big-number{font-size:2em;display:inline-block;width:192px;margin-right:16px;padding-top:18.4px}.dapp-big-number dd{margin:0;font-size:50%;font-weight:600;text-transform:uppercase;color:#695e5e}.dapp-big-number dt{color:#02a8f3}a,a:visited,button{text-decoration:none;color:#02a8f3;outline:0}a:hover,a:visited:hover,button:hover,a:focus,a:visited:focus,button:focus{outline:0}a:active,a:visited:active,button:active{-webkit-transform:scale(0.95);-moz-transform:scale(0.95);-o-transform:scale(0.95);-ms-transform:scale(0.95);transform:scale(0.95)}button{background:none;border:0;padding:0;margin:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;font-weight:inherit}button:hover,button:focus{outline:0}hr{border:0;height:0;margin:32px 0;background-color:transparent;border-bottom:1px solid #ccc6c6}h1{margin:16px 0;margin-bottom:48px;font-weight:100;font-size:2.2em;color:#827a7a}h1 span{font-weight:500}h1+h2{margin-top:0}h1 strong{font-weight:400}h2{display:inline-block;padding:0 8px;padding-bottom:1px;margin:64px 0 16px;font-weight:500;font-size:1em;text-transform:uppercase;background:#827a7a;color:#fafafa;font-family:'Montserrat';font-weight:400}h2+table{margin-top:0}h3{margin:16px 0;padding:0;color:rgba(130, 122, 122, 0.7);text-transform:uppercase;font-weight:500;font-size:1em}h4{margin:16px 0;padding:0;color:rgba(130, 122, 122, 0.7);font-weight:500;font-size:1em}table{width:100%;margin:16px 0}table+h2,table+h3{margin-top:32px}table tbody tr:nth-child(odd){background-color:rgba(204, 198, 198, 0.3)}table tbody tr td{padding:2px 0}table tbody tr td span{display:inline-block;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%}.dapp-input{border:0;border-bottom:solid 2px #ccc6c6;background-color:#f5f4f2;color:#02a8f3}.dapp-input::-webkit-input-placeholder{color:#ccc6c6}.dapp-input:-moz-placeholder{color:#ccc6c6}.dapp-input::-moz-placeholder{color:#ccc6c6}.dapp-input:-ms-input-placeholder{color:#ccc6c6}.dapp-input:disabled{color:#695e5e}.dapp-address-input input{border:0;border-bottom:solid 2px #ccc6c6;background-color:#f5f4f2;color:#02a8f3}.dapp-address-input input::-webkit-input-placeholder{color:#ccc6c6}.dapp-address-input input:-moz-placeholder{color:#ccc6c6}.dapp-address-input input::-moz-placeholder{color:#ccc6c6}.dapp-address-input input:-ms-input-placeholder{color:#ccc6c6}.dapp-address-input input:disabled{color:#695e5e}.dapp-address-input .dapp-error+.dapp-identicon{display:none}.dapp-address-input .icon-shield{display:none;position:absolute;top:9px;left:13px;font-size:1.4em;color:#c20e25}.dapp-address-input .dapp-error+.dapp-identicon+.icon-shield{display:block}input,select,textarea{border:0;border-bottom:solid 2px #ccc6c6;background-color:#f5f4f2;color:#02a8f3;display:inline-block;width:300px;max-width:100%;margin-top:18.4px;padding:9.2px 16px;padding-bottom:6.13333333px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-size:1em;font-weight:300}input::-webkit-input-placeholder,select::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#ccc6c6}input:-moz-placeholder,select:-moz-placeholder,textarea:-moz-placeholder{color:#ccc6c6}input::-moz-placeholder,select::-moz-placeholder,textarea::-moz-placeholder{color:#ccc6c6}input:-ms-input-placeholder,select:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#ccc6c6}input:disabled,select:disabled,textarea:disabled{color:#695e5e}input:focus,select:focus,textarea:focus{outline:0}input.dapp-large,select.dapp-large,textarea.dapp-large{font-size:1.5em}input.dapp-error,select.dapp-error,textarea.dapp-error{color:#c20e25;background:#f2d7d7;border-color:#f5b6b6}:disabled{color:#695e5e}input[type="checkbox"],input[type="radio"]{display:inline-block;position:relative;margin:0;outline:none !important;-webkit-appearance:none;width:auto;width:24px;height:24px}input[type="checkbox"]::before,input[type="radio"]::before{content:'';position:relative;top:0;left:0;display:block;background:#f5f4f2;border:1px solid #f5f4f2;-webkit-box-shadow:inset 0 0 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:inset 0 0 2px rgba(0, 0, 0, 0.2);box-shadow:inset 0 0 2px rgba(0, 0, 0, 0.2);width:24px;height:24px}input[type="checkbox"]:focus::before,input[type="radio"]:focus::before{border-color:rgba(2, 168, 243, 0.4)}input[type="checkbox"]:disabled::before,input[type="radio"]:disabled::before{cursor:not-allowed;background-color:rgba(245, 244, 242, 0.8);border-color:#f5f4f2}input[type="checkbox"]:after,input[type="radio"]:after{content:'';display:inline-block;position:absolute;top:6px;left:6px;background:#02a8f3;-webkit-box-shadow:0 0px 1px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 0px 1px rgba(0, 0, 0, 0.3);box-shadow:0 0px 1px rgba(0, 0, 0, 0.3);width:12px;height:12px;-webkit-transition:-webkit-transform 400ms;-moz-transition:-moz-transform 400ms;-o-transition:-o-transform 400ms;transition:-webkit-transform 400ms,-moz-transform 400ms,-o-transform 400ms,transform 400ms;-webkit-transform:scale(0);-moz-transform:scale(0);-o-transform:scale(0);-ms-transform:scale(0);transform:scale(0)}input[type="checkbox"]:checked:after,input[type="radio"]:checked:after{-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}input[type="checkbox"]:disabled:after,input[type="radio"]:disabled:after{background:rgba(2, 168, 243, 0.4)}input[type="radio"]{-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%}input[type="radio"]:before{-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%}input[type="radio"]:after{-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%}input[type="range"]{-webkit-appearance:none;padding:0;border:0;background-color:transparent;overflow:hidden;height:18.4px}input[type="range"]::-webkit-slider-runnable-track{height:5px;background-color:#ccc6c6;border:none;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}input[type="range"]::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:16px;width:16px;border-radius:50%;background-color:#02a8f3;margin-top:-6px;z-index:30}input[type="range"]::-webkit-slider-thumb:after{content:" ";width:500px;height:5px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjEwMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMwMmE4ZjMiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjMDJhOGYzIiBzdG9wLW9wYWNpdHk9IjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9InJnYigwLDAsMCkiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNsZXNzaGF0LWdlbmVyYXRlZCkiIC8+PC9zdmc+);background-image:-webkit--webkit-linear-gradient(right, #02a8f3 0%, #02a8f3 50%, transparent 100%);background-image:-webkit--moz-linear-gradient(right, #02a8f3 0%, #02a8f3 50%, transparent 100%);background-image:-webkit--o-linear-gradient(right, #02a8f3 0%, #02a8f3 50%, transparent 100%);background-image:-webkit-linear-gradient(to left, #02a8f3 0%, #02a8f3 50%, transparent 100%);display:block;position:relative;left:-500px;top:6px;z-index:20}input[type="range"]:focus{outline:none}input[type="range"]::-moz-range-track{height:5px;background-color:#02a8f3;border:none;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}input[type="range"]::-moz-range-thumb{-webkit-appearance:none;border:none;height:16px;width:16px;border-radius:50%;background-color:#695e5e;margin-top:-4px}input[type="range"]:focus{outline:none}input[type="range"].slider-vertical{transform:rotate(-90deg);width:73.6px}label{font-weight:300}fieldset{border:0;padding:0;margin:16px}select{height:45px}body{display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-direction:normal;-moz-box-direction:normal;-webkit-box-orient:vertical;-moz-box-orient:vertical;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-height:100vh;padding:0;margin:0;background-color:#fafafa;font:100 16px 'Source Sans Pro', 'Helvetica Neue', arial, sans-serif;color:#111111}body.disable-scroll{overflow:hidden}body.blur .dapp-flex-content,body.blur .dapp-footer,body.blur .dapp-header{-webkit-filter:blur(4px);-moz-filter:blur(4px);-ms-filter:blur(4px);filter:blur(4px)}.ethereum-dapp-url-bar-style-transparent .dapp-header{padding-top:73.6px}.dapp-grid{z-index:999;background:#ffffff url('dapp-styles/hex-grid-tile.png');background-size:64px 111px;position:absolute;min-height:100%;left:0;right:0;opacity:0.05;pointer-events:none}.dapp-container{display:block;position:relative;margin:0 auto;max-width:960px}.dapp-header,.dapp-aside,.dapp-content,.dapp-footer{position:relative;padding:18.4px 32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.dapp-header{height:64px;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmYmZhZmEiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iOTAlIiBzdG9wLWNvbG9yPSIjZDlkMGQwIiBzdG9wLW9wYWNpdHk9IjEiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjbGVzc2hhdC1nZW5lcmF0ZWQpIiAvPjwvc3ZnPg==);background-image:-webkit-linear-gradient(top, #fbfafa 0, #d9d0d0 90%);background-image:-moz-linear-gradient(top, #fbfafa 0, #d9d0d0 90%);background-image:-o-linear-gradient(top, #fbfafa 0, #d9d0d0 90%);background-image:linear-gradient(to bottom, #fbfafa 0, #d9d0d0 90%)}.dapp-header nav{position:absolute;bottom:0}.dapp-header nav ul{padding:0;margin:0;list-style:none}.dapp-header nav ul li{display:inline-block;padding:0;margin:0}.dapp-header nav ul a{display:inline-block;padding:9.2px 32px;text-align:center;border-bottom:5px solid transparent;color:#0285c0}.dapp-header nav ul a.active{color:#ab9898;border-bottom:5px solid #fafafa}.dapp-header nav ul a.active{-webkit-transform-origin:50% 100%;-moz-transform-origin:50% 100%;-o-transform-origin:50% 100%;-ms-transform-origin:50% 100%;transform-origin:50% 100%}.dapp-header nav ul a i{font-size:1.5em}.dapp-header nav ul a span{display:block;text-transform:uppercase;font-weight:400}.dapp-footer{height:96px;background-color:#111111}.dapp-flex-content{display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-moz-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.dapp-content{-webkit-box-flex:1;-moz-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;background:#fafafa}.dapp-content.dapp-has-header{padding-top:175.2px}.dapp-content .dapp-content-header{position:fixed;top:0;width:80%;min-height:36.8px;padding:18.4px 16px;margin-left:-32px;background:rgba(245, 244, 242, 0.8);z-index:10;line-height:36.8px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.dapp-aside{-webkit-box-flex:0;-moz-box-flex:0;-webkit-flex:0 0 224px;-ms-flex:0 0 224px;flex:0 0 224px;padding-right:0;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmMGVlZWUiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2NjYzZjNiIgc3RvcC1vcGFjaXR5PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2xlc3NoYXQtZ2VuZXJhdGVkKSIgLz48L3N2Zz4=);background-image:-webkit-linear-gradient(top, #f0eeee 0, #ccc6c6 100px);background-image:-moz-linear-gradient(top, #f0eeee 0, #ccc6c6 100px);background-image:-o-linear-gradient(top, #f0eeee 0, #ccc6c6 100px);background-image:linear-gradient(to bottom, #f0eeee 0, #ccc6c6 100px);-webkit-transition:flex 400ms;-moz-transition:flex 400ms;-o-transition:flex 400ms;transition:flex 400ms}.dapp-aside nav ul{padding:0;margin:0;list-style:none;padding-top:18.4px}.dapp-aside nav ul li{display:block;padding:0;margin:0}.dapp-aside nav ul li a,.dapp-aside nav ul li a:visited,.dapp-aside nav ul li button{display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:relative;min-height:73.6px;max-height:92px;padding:18.4px 32px;padding-left:10.66666667px;overflow:hidden;border-top:#b9b0b0 solid 1px;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#111111;font-weight:300;line-height:20px}.dapp-aside nav ul li a:active,.dapp-aside nav ul li a:visited:active,.dapp-aside nav ul li button:active{-webkit-transform-origin:100% 50%;-moz-transform-origin:100% 50%;-o-transform-origin:100% 50%;-ms-transform-origin:100% 50%;transform-origin:100% 50%;-webkit-transform:scale(0.98);-moz-transform:scale(0.98);-o-transform:scale(0.98);-ms-transform:scale(0.98);transform:scale(0.98)}.dapp-aside nav ul li a>i,.dapp-aside nav ul li a:visited>i,.dapp-aside nav ul li button>i{margin-right:4px}.dapp-aside nav ul li a>span,.dapp-aside nav ul li a:visited>span,.dapp-aside nav ul li button>span{max-width:115px;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.dapp-aside nav ul li .dapp-main-button{position:relative;width:100%;margin-bottom:73.6px;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;background:#665f5f;color:#fafafa;border-top:none}.dapp-aside nav ul li .dapp-main-button i{position:absolute;right:8px;top:27.6px}.dapp-aside nav ul li.active a{background:#fafafa;border-top:none;color:#111111;font-weight:500}.dapp-aside nav ul li:first-child a,.dapp-aside nav ul li.active+li>a,.dapp-aside nav ul li.dapp-main-button+li{border-top:0}.dapp-actionbar{z-index:20;-webkit-box-flex:0;-moz-box-flex:0;-webkit-flex:0 0 64px;-ms-flex:0 0 64px;flex:0 0 64px;background:#fafafa}.dapp-actionbar nav ul{padding:0;margin:0;list-style:none}.dapp-actionbar nav ul li{display:block;padding:0;margin:0}.dapp-actionbar nav ul li{margin:16px 0;color:#02a8f3;position:relative;overflow:hidden;text-align:center;-webkit-transition:height 400ms;-moz-transition:height 400ms;-o-transition:height 400ms;transition:height 400ms}.dapp-actionbar nav ul li button,.dapp-actionbar nav ul li a,.dapp-actionbar nav ul li a:visited{background:none;border:0;padding:0;margin:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:inline-block;color:#111111;color:#0e73b8;font-size:0.8em;font-weight:400}.dapp-actionbar nav ul li button:hover,.dapp-actionbar nav ul li a:hover,.dapp-actionbar nav ul li a:visited:hover,.dapp-actionbar nav ul li button:focus,.dapp-actionbar nav ul li a:focus,.dapp-actionbar nav ul li a:visited:focus{outline:0}.dapp-actionbar nav ul li button:active,.dapp-actionbar nav ul li a:active,.dapp-actionbar nav ul li a:visited:active{-webkit-transform:scale(0.95);-moz-transform:scale(0.95);-o-transform:scale(0.95);-ms-transform:scale(0.95);transform:scale(0.95)}.dapp-actionbar nav ul li button:hover,.dapp-actionbar nav ul li a:hover,.dapp-actionbar nav ul li a:visited:hover{opacity:0.9}.dapp-actionbar nav ul li button i,.dapp-actionbar nav ul li a i,.dapp-actionbar nav ul li a:visited i{font-size:2em;display:block}.dapp-box{display:inline-block;float:left;width:192px;height:220.8px;padding-top:18.4px;padding-left:16px;padding-bottom:9.2px;padding-right:16px;margin-bottom:9.2px;margin-right:16px;background-color:#fafafa;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3);box-shadow:0 1px 4px rgba(0, 0, 0, 0.3)}.dapp-box h2{margin:0;padding:0;background-color:transparent;color:#827a7a;font-family:'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, Sans;text-transform:none;font-size:1.5em;font-weight:100}.dapp-box.card{padding-left:96px;padding-right:64px;width:512px;max-width:none;height:auto;border-radius:4px;background-repeat-x:no-repeat;background-repeat:repeat-y;background-size:64px}.dapp-box.card h1{margin-bottom:0}.dapp-box.card h3{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-transform:lowercase;margin-top:0}.dapp-box.card dd,.dapp-box.card dt{display:block;height:36.8px;font-size:1.1em;float:left}.dapp-box.card dd{margin:0;width:128px;clear:both;text-align:right}.dapp-box.card dt{font-weight:500;padding-left:16px}.dapp-modal-overlay{background:rgba(17, 17, 17, 0.5)}.dapp-modal-container{background:#fafafa}.dapp-icon-button{background:none;border:0;padding:0;margin:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:inline-block;color:#111111}.dapp-icon-button:hover,.dapp-icon-button:focus{outline:0}.dapp-icon-button:active{-webkit-transform:scale(0.95);-moz-transform:scale(0.95);-o-transform:scale(0.95);-ms-transform:scale(0.95);transform:scale(0.95)}.dapp-icon-button:hover{opacity:0.9}.dapp-block-button,.dapp-block-button:visited{background:none;border:0;padding:0;margin:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:36.8px;min-width:100px;padding:4.6px 10.66666667px;background:#02a8f3;color:#fafafa;border-bottom:solid 3px #0297da;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;display:inline-block;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%;font-family:'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, Sans;font-size:1em;font-weight:400;text-transform:uppercase}.dapp-block-button:hover,.dapp-block-button:visited:hover,.dapp-block-button:focus,.dapp-block-button:visited:focus{outline:0}.dapp-block-button:active,.dapp-block-button:visited:active{border-bottom-width:3px}.dapp-block-button i,.dapp-block-button:visited i{position:relative;top:2px}.dapp-tag-button{background:none;border:0;padding:0;margin:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;padding:4.6px 8px;background:#ccc6c6;color:#111111;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;display:inline-block;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%;font-size:0.7em}.dapp-tag-button:hover,.dapp-tag-button:focus{outline:0}.dapp-tag-button.active{background:#02a8f3;color:#fafafa}@media screen and (max-width: 576px){aside.dapp-main{-webkit-box-flex:0;-moz-box-flex:0;-webkit-flex:0 0 64px;-ms-flex:0 0 64px;flex:0 0 64px}}@media screen and (max-device-width: 480px) and (orientation: portrait){body{font-size:14px}}@media screen and (max-device-width: 640px) and (orientation: landscape){body{font-size:15px}}.page-title{position:-webkit-sticky;top:15px;left:0;right:0;background:transparent;color:#ccc6c6;display:block;text-align:center;margin:9.2px 0 73.6px}.block-chain{margin:0 -40px;height:331.2px;padding:9.2px 16px;overflow:auto;-webkit-overflow-scrolling:touch}.block-chain .wrapper{padding-right:160px}.block-chain .wrapper .card{position:relative}.block-chain .wrapper .card .dapp-identicon{position:absolute;width:40px;height:40px;left:44px;top:38.2px;border:solid 2px #fafafa}.mining-slider{position:relative;padding-left:16px}.mining-slider .slider-vertical{position:absolute;top:18.4px;left:-40px} \ No newline at end of file diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Black.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Black.otf deleted file mode 100644 index 5e04cf3f77cd605f772c19b776ee4c397cc3c374..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45336 zcmdSC2V4}#7dXCq$KF{_WnBxWcPI9O6${uA5d}p=>H*e;=1`hOMDlln` zoaxrX%}qzroyRkbssqDJZ`sSWr<>fzrX|BH@6Rwyqh9^JeDV@WEW@mE$1=ISe0*Kn zlyCSKzE5HpF4xPaMeEV4zwFI0EY@NC10(d&Z68G6Vi@H$hEa42HRyxn9b$jQcjxf8 zT_`>%^DVau%iG|6z0iobq=cZF-!jZMp$P9uggz;nO`%P*jqr~mQXgSh_4JGDct00! zdqqdZ#{Hecv_@QN;Cmgz(xMF0MA7o7U!_ieGIIG7e8ODVRKwN!`PYlTws1eoui(9$ zk=>aRV~C0iZXO;M(7Jis=50H)Y3-zQ?K!BYr&s^J zJ^KwTfNO5&J;X!f;-Z~fv`9=$Y@RYEnf4?wDx$eQrp3U}uvncNc0lJ76&#nSk1^=* zL3mi8Au`qwq>GOXGQ{ZOLJc~f-kv(IXhWpAu&22|GhIOsS~b^6z$|qs7=401EL z!lY$_u@qM))_zXpY_vxSK43JnYCl_Bz| zYtJ@eo3d5eL2M1SIa`~p$2?`8F~2j*V($)c}O z5v`8EXc#SH&(vickO-}iwL37KnO-=keUM3gP_+D!xWP!GaJCUEu#MS~Y<)Hc$vBQl zMQ>#)Gl%(#`5LX~3MQS&Kvl7c+0N`^4loCqBg{$Wd*%{znYqr~VD7LDSUywro4LJ==kGV}~=h znbFLjY-hGL+lG0-JY)k|4eP`@vc8NBQvdOvi4cMaz z>^zxT)?Ri>c1Ctv-ax)Uenc}(^IBI`XQ$KX>~#%vEp^U1SKXF6d>#8b4eB(nGs<3O zU&-FqUa+^b*Vs3;cenSqH`M>0$o~Et+oVd)nMr3WAmud3ISr9xJlX#2D5PH`wp9b$ zI*Dyvv$U0_d8OlZHFULfI;kx*h=tl3F11w!+p3x0RuHzuN^Kp$_DcEp_a=tj_8e`DXUZ&^{s$Q)(uWS+8NvJog}=q<`7n13mB*<{&l*;n}a zm24ipFX><5@>nv-T;^kP_kWL!u^o|@sDyN7U08pVlW11YJVH+QVq2iJ#G(8QW^Iw< z#-N0RASXn!RhVDcR_I~AWkgnovLHj=E+E$+|InQL@ic z*=BAs`%&JMsP5&cn#-V)S25$6O3Va?XC^aMnJG*yW)@?|%wTFWvzhA57s%89W9p!H zJdbI{EJt}-$~0w`F^!l7Og&}^s`ypN^Q)OPXpGmQ1G5gzaweMR^-Mcv14`azH04`S zCbppKvj^RU-BbghQ*j6l^kFm!-=b+aiiYJoG~LJ0-8hY=>J&4Q$z}YQADI!%1!fd; z5sk}FXi#n;FGetT(Wu->l=rx^5*h( z^6v89av!TK z@o|Iof$?#M?g24|1jFFKu$aL3h~RKTl2?R2FeWOpcb~yQVFsMcgvAaHiP0w*dIv?t znW1zyml#@5r+ZXLRHR`{Z_5jFdCRl7u<#(m0I973fqH~IOuFtxB57}8TEmM z3hB)q=qc6iC$-bhd|jwe&wNaM3)9xu3@%Wr)zf^_(+n?Ag5hhv@r?qqhqAIWQm?Z5}u~45eiXk$@5E&2~tq(NxjE{*b zG;oI4I3#$SAxIyM)srNU!C^76adAk}z)&P~tRWyiJlqf$6>Y$fNK}j^rcn@JIrc9i zEatcgwKn$5W_Bjp#;wdY)ZX(^_h+Fkuglb9SFo$lde>)`vK!bfXg7AU)KA~d?q>F| zIqW|4g&VQoVw9>e(}bOa_B|W@>bcB5b^-ehyNGGZE@PUp>5KzfgLP;RHlcNC&a_~6 zushjZ=mE5pW)O#%Z`tYWY@A~p##u%yoMW_R+OUh+CG2v>5u;v5*flKLa&|qtncar= z{3u%J@0jCgTlTUC*n@O7!_Hu5v0t(OLrd?BGlhA~Np>OAkzLB1VppQIKh3UX&fqNN zEW4H6F8LpG(e}Br+3bGwNP05s*~9F2=n-6CzekIIk-fig?Pov63;ooe**j=E`=b{? zXGS;C{{4zGs9Wf(fbl`wc$7WC3}jC+x7i=q^XN7CvRBxj*z4#|{ESxjE_08) z$KGcjun%#LHiUi5K4G7-&vDK%jJeOgVji%^nBnY6oU5Egk0cU3rvI^**lWyU_6E-S zY|)phigUke=s!`f&JO*TWz0$@180=o(PQkv0{f25WB-z|G8?qYN?BR<1^bfygMDrG zuvsH(LN8m6zT8@z^OeUrV;uU3712|W;f&D+{k0hMCTMIi6#cczIMW${eo`m&7|Wtp zIRiZ;m8=YUOG)Vegrlz)hJIdm^!6}PDyza6WVSf#3_|mE#uIOT*qvXm6ugOZ#4zyv&&@_Whz-ES!MJdyP`)p5@)2FaHcwzSuLw7D~Ene zCeCD+pf@=Q=aN;RT!m&SF8RhCf>S58xYTZSv+S!R0~Qnqc`#IonhLb-wE?v^){pI?4c zd9i}F!oUifD%`5bRdlF0rs8)M^He^nsj54wyh@ELg;mO`^jl^7$|Eb!tbDpk)hgjt zZrL`ronrfxkLJ%-ZCiDbU@vU1R-u|lwYk;)uI^qvqej^p6KdS6>0L9|F4XR|T2T9_ zv($gr>R4-9t=qK+*IrYbXnJaPYU^q}w6nE8>$>Q6*HPASsS{IYXPv+8L+#hwU#wfM zu6Nyq^_2Cd*Kbw-aD#{j&l|=y(lq+M@suWxP3AYb*R)g9%x3kQO>QPSq&kSry_@fA z;m~4D%hoM7wX$tBsddHHzOB!X-oZJdTVEpxi(T-~{k^LFRg9o;%+cBE^oT} zbiLheO!uDjsGQMVRu@ovBM()YURUfVs!{c`XA zy)*kL`wZ`M*2CQ+(j&`L?iu8Hvu}&OVSV@XtJE*C-y1J4uN1G{UZj7w{=2;^c_(}C z_kK8Fz<}igp89n38RE0i$273(z}W*|`PT4VGe|k8?x3ZEWrJ4^@gCZ7Si@nz4{tr( zbNHI!Z$@+&@zsdeBWsLYIMO((>!_ilw)wGst^H>Bz3|uiuh7f&we>Oj6Z*V>Y5^Sr zq61b2JPT|T7#3s`R6nR!&~8HwLuZ4pVVPmC;fLVH!CwS#3ce7c2B zCrnK^kk~0PBk`xCprkj+J(5Qx&raT+{33-<@k|L%`66Xo%JCF&oWr>2ajVAdA-=N? ziO&wP__y96`79f8y0O1$x&po;Cj`<3=5z2wL3HGZ0QAN*Piaz&lCGf(!Fz>x81Kk@ zLhn?6rYAfHXVE>8on$;E7c-s<+Zu5&OF?!Ry*V;jK@R45b1+%4{W%8#;4F{^iYuUh zuikLucmZmIKn9%B5v-7!XZN{)E`W^prX~)6cye6Ly z)x#F_&?gi6@FE;U&_}a&961`i!`C<1;5#VGa8%2iAgJ1VPuF~YTW0j%P=Y%ubl^<} zcyVwpZ`tSK{0thg@D&`9i~Ef$1!zQ$kVZ<_nAh=B0TGV`h_`T$EpiVD2N^FK4^=CH zclbB3Oo5zrMG+g46ck|Rb~I_v!M$t0U9TB5=xtjN&*VA}RRBj1HS#2s)P1E3a^m6-6Y$Qt(x8JU6Kt8ZkTfXbBhVx~?^ z(eTgWqIdOGcQSaBDq5(e;NND>TeM8Wzk+sogFlge;;>oZ>I=>>;Cc^SZN>jVDxdT2 zS8x?fiu-U2T*<9_kO!`LK?;){6~d_se#j|MaS);4bBIcOuH=W9p2Kc|*eMX_yU9Ln@Ol0>~Ac(~}~?6B5U0iCjUN+u+#A6?@kwhKEJP`_pHtFD8K>`~<%2QkX0k zwZHJVGu@|Ky5Nk>rC8*tBOY_d)2My+q=EiQK15s)|Nwg{B>uaSRgz> z?jhODN%GDjU13?vi~TUQ)tjAvf?4MIz4hKBo2`ZDJ23(I$pN5{}Xvc=^sxa33+k-F^Rv^XK>P zKYxD2es?V#FbzOJO8&|FR9C!5b$>L1W($byEO7Aj6Uc61m-cXkVj+G}z$>CR`C4jQ zEU|5B?)(e$2Q+}VB0S=x`~>56wJ;+oRDIJEAPHQdBDk7|@tv9HPNNv4;+wN*2hKu8 zr7C9<_`+TAB}}3%s$I0)!})9CERhpPd*%4Bu*tFNmhKmy{r1DfM<*^sj@qx~bD%ov zSpM1%-AMU8gjJJd;!K*7KoSIwq!~oN0Aa`B>sr`T1UPg?KMWfPkUX(2*b2k{Bk}8eQ*APLz zR;ox|dVgqHjqg z-kkR05MnHH-doEe`bzBuS`% zbBPjP<}bhEHO$2~6_f4`@As1Wu(X$uTOh`;GH+!efMzc>e{`mM2*usaZ_T8;`krfQ zrKQy~#Fhp~e&Mx;?>vM8=kJN+{7G&i|FD>&cujH?`6uA}mq!6sm8md401p-p!g#ru zna>AggW|(XV692jzPa+$(gqkjye!=HF{n2S*jJod4K^ys3b8$Em~9+cr630KB?n(x zINnKl;VP#xSD-xo1?c&^#wFE0Tmu@AX&j$R%8dS~0qg4uY+DL{)oUxjuo7OB*I@pana9L44VA5XgAx^ZWafC9a{g19fFad z|3m6i4q^h^igt_C7n=xPdc9Y_J^E9p_v|@+O24O{R^^D4fVYX@lE_}779N=h@rN!7 z=ycEkYEsR>!9dhVivb`ZO>D>!mcOh>)rXC2Q`Vl5aYH{PczX@-(Gm}JC3lyPJR zYOhgZRRvTaxg0dZPsrs=Rh3llnMEZ87DKQ_=LHj!l57MMM+RZN5O}A64dfkHys&t) z$Z)_8v%G$|_F2g>G`9whrFlYPlfPO}>G?1$9H@}3pihTj{)sV)`m9)9Q3B>LNWqKb z-p9wzOpXHi5AiV14Lz_4hQ9*mi|B!03iLoREpWxG1%4IVnzcY_{dj9J@^qpC`|0GW z9-Umpl6Isq3Bt)$J2c#}_|pzO`5*`+?Vt&X)qX{Mg_~#Hnl|-t?bxyBk58ZG=HAk( z-UoK0$N-JPnbp68d<2zHKBkXL(?g>M{rh%2s4L(t`KAV#jI{p^c9!U#zA0py^34_h z$^l*Af7#iBp3W?4m`?m_Iu?NTc!&O6yCaS?hUTb%@1a(qThjGkw{#IFOGwEHaAclD z#wR#)$q)XZQ|{RFACsv=!msG5%xZ*jUE%ARlO!Xp<}NE@g4X|9i!vU@HxhW9YSQFUs9AhE^+ayR4vpv zb{AC8)Xu84@;PAyG$xH8XriWm*1g_;s`;eL_c!f7sx_SyeFdt?3TrlvYICtJ_rorW zL#x431<^nfcPV@4)j#ZTg2Vno2587*$xZKbU*U*^hK_HQ`Q0xWP*)mOEfmM@hc@hA zfwl%dD4MX2LN69{!r&8}L+kdhTA?mV66j|^G|KR{YS8Dt@($_4l@3#Zvypd23Bo^# zGpRr7o<&ZDo+1N1*`pXuvc>2UyfqFNNFP$J4bf@IO!)g$OS_o(v@lmv`QWJ@nzqD+ zbA1A}0zjpP)=)baT54e)`Fr34yY%JrGfxBSAM~T<4!ClMIuYd-B3G;4YeGCw#BORPJn4x2WxD9&RV)KWg(lCr;y@70Tj!+7TK1^<2yx|41 zpg$)CcB%1+fyB%M9JW|>#fys=5H*iZ{xDFa^q>z$q@Mh9q)OodKKC@n;`5#EQfA|W z)1^5yi}4qnhgTMt3gD4f9_P)&O-mtFT&h%AN>FK&3jJBy@QJLc@%y#u5Ogrl(`j{# zf>q*Q8Y`mI15Lht165v>Ax>Oi2#UG22%ccVY zpIe*~{N3V_iBsqzic1sOT`0i@N{*4#(M>fqQuOrm8{j=OCs!jjqW4PD59bIKu~|Qi zj#Pwx8ddSS;txdx3%2@wCL|hVup%PfD9r(ctzMrE*TWX!wvrsamS`zoL1rO$Ps{&i zjyb%NVh-r?@ox&k6tD9AJ{(E3+y9U@Abx zi78z^xwkYdGDzYiO6XrfHW#V<=Htwy;l+&ETte8mkl@l5@m8j9Tenk-`lMXWk1wIN zot5nl-@Sg9HkO2+iP##$zZEOK3lrQ14s>%nHZV8$*sJz8>;KY$N3K&OzCo_r2L52d#KyN5V zdULQzp~^I~2h5~Fl^BQ=;D2HwN5&~gEwYBxfi?6R7MM~w5(cTtqUGBZ^AKZA8J||4 z>Po3eIDx}ia_YfV)2>eihGXXheHuWjJ%(x-{v|9xsMdiiP=*h20N;Q5WXY#CWI_2H z?R7!A!FPG}K8EL{S>Oi0qdi__tS&d!6EPj7ex40+g9}P>)1=}^ePeZSBlnf6A|=Id ziwe*b;{DNz)auh#pn7RmA513XkdL&F>r*Vuh9o)sRbrrezo|{BFgnh{6=hWdOniL` zI^i@Z1bySNC_Puiqk?nOq_F1NLm1ItbLRU+yVb`w#2aR7Nfiar&Ttt(7`wXXdqJ6t zhu3Cr*6;`W!&rE$#HxbB71A0Xj52i+#w4%UxMBIyP1@^2717C&sgY_`X)XROJ}5GS zDHrzt2Ld~!MWc}Vpnd{lF%d+~k7MAp_*mdm(n?F>!6N27p2ddJQRK%nC6Va>W1$l^ zV+|>IF*FZw-$URSkd|R)3Bj|tq{UVT9`CNo=Hgq zf5hs2nZ=%#B+992Ek6_0{b^PnOS2+-Fzr*Y%_m$cET&vmpbv(T_MbQv!s82cF`X7v5oP;bF?!_RVC5Q=uSnQ-_F#%;09%XJd&BSMT7Oc za^G7t=2xbbkQ9Yw_rqHS2+gh#N6l7pSKu!&LzU4<5vdXC(MhNuRxI7DEvgn)Q;!Sz zOOKx&Da9Cmd>V@7Rl(|OS$!`pv@gNwis`nP^!+@N?&xNrX-qdOQFnGLg{nnV*s=Uz zT?ny(T7MvAaS57FPJ>LN&YXkACwD6rSC3CCmWP#`CdJ?nG%Fozl(3Qnc%M}&utkeT z*Gg*vabaHp?-U3``Hs(QWliln6RLfAhq9^)q63D zW>mnaMM$7(WT3hyNfP!g$k@D7y=(pGQPZ{jHj^hAB#bdL!zS%bG#1DnXe_2rK~viW zBY~mN9lR24PhnzEdr0I{#ZHK=&+zzwP%Y+<#^_-fhteGd$vnU`rP3HCdMU?QTs*hI&*scuI$YjNu!r&q1RRJ#i(W{NO^TJXyOE8 zP@#0NVIlts=a2~n{rFJ`?U`-#@gSrXY zz%CySHxvXLG7tW;JooVC>op6AO9#9=aY7F<6bA+e9Q%p`9?z#5%NbJy5>Ni8*c~!- zO@B3M+?22chxj1r{v7$L*>?w4@7|{2QwJg^kdxpf3^fn;p@Zh(9;Q`wodllf-!y{b ziR=Q*^{Wlju~o`bc|lB zg61XnX%~i6QpLu!TmMsjxKk6bQ^ph})OGn-$jRhunq5NAXBI+XB{DWAIeTW(_A$DP zKMMQ+;QA{0KF0_O(tv?3cuBa+N`701qPP{NwwCXQh>1TUy-f~Mt6Dx1B}^i@hVO?$ zHcX@HG==J$>(GQ1%R;;yPEjdyC1r@5bVn(Zqm+65SyXEntXf0N*BU;Bw8l=mMUneY+o8f|?t`8-RYE{~B9*@Xw9Ugf`!csVyHuagfB}a8xKW&?F=pSc3QFHQ z7+#`lS7K^7|E}SGjn7uhzyohc@|EM|Y3=Xjfqb)oFS$AyjO%Z{_)M~3tW~`k% ze~l(OI6<#BN6hx*r@c?Kq`mLId4FqGfw4EJ{n6Nuqan1yf;)#a5zHb>YAN?}6|H)Jy z;>7ZQf_De&&1!wY=Oin_*+AiJHm#i zqsb6jG$5@=+o$zFIKDqUYm0WUQXdlCdr#BspX%Y+PHJyzKua%8va)Qh@g@0H@r)lNCrDe*@u|cj9p@Q+_!!c=aQvOB+au( z{#hEV!=)&SYTAE+Yg!>>(@Mscl4&aFM@p1`2$#ic!l}J`PHmdFA$o=OFz{Smg(I=$ z#>J(L4Y%ukAoQpP6Bo9kZbKw*{0BJxR)FFSGltV}d6dAgS&5)GyLq*dHxG(~ady&U zz!;xkEo55Vyjzf=JhFaU_Rh@6ks6YPF5w^O`+=?VZKBku##sSnVpex~=q34#6d1#= zD+G@J>epvV{u?OYM9F`3iWiSyC(OtgVoD$iLZ%G)3?jHENxV zCrU^Pw#hpoh}k6Gl#Ll+<{IYWTdI}#*i^)2JZ^eWyf%%+(e}i$sEzfROwl@eGyhc+)yX__%RVvo*=da~C9O zhmz)8{NAGzPpP5C%)6IBX=f!lU3QQL>Bj=K3QO~B@_S^mH78qI26QhS(3T$=(6jGN ze@mGAS~0LDVvU7b=r9d3=VJb1++oSZN&@OB*R8)px^b{d zp$fOGl4d7jMT!f0@0ED5wAxDk&EAhMnu-PU7+f+v1@#mK4H_gY&4TJ*7{w|yXGll& z0V=Hq%C(tR6v;~r?WdS~1v{!4Q)o9(XB2uYvhNxenol0jTPNff3zBNnuC1Z#w5M=R zL1)A`Wx)8l?MEjK)^;S?1W^dELz-<-APPR$ezd^feQ$*~xA+P#nTe`56!dW2GCbA9 zw!)yGF~cTn#U_?<$x#kpuyf22^{G93PMy~8@xnRy<@_zak+XgAhv+mp4{YB!4Co9#%)+l14o(u%Y}4M>hSAm1AC*RB`9EN+W(tX85V z7;TEpQhdTJ2JSOK9tAh4_mZ82rKL%-@6O<`|<~% z?6&lq-_XKz|6?=N0s{YJiJ;+F5(VbFDe*Iw>PUv)nFiObQM6(zaVt|OgvM`Xs0!U_ zj-v5<7^v9H+V3mO2T;b67QbN>PLXNUfreKw9}UAn*XTsGKkluSk*=gGru507KmJt2 z9b;XgD_UO}>8~YjHr9BOHQ=CCy$4HNT*R^u#F^>80!(LxRy@Vb()8*;oQM6(W@wl{ z(HiFGF!Dw-SfkN{u&&fuFJXff|EeyT_%E?2=&5^AZ{xtfC1U~PvPRrOS!(`j z?|<76o!}uMaRHzg((s8GS>TBv-J0M8@1KrSbKLIGW_scp8Y&CL%!p9_oH)biB(zcR zTLMTGjz2dib=>R}b$$a?FE{`fi0)ET?tvm3YH~A|E}gkdZDnjNzZ`h?Uy0354M`-+ z1peGlSqF~K(exx?9KSp@ee$O5cF^U4urz)_M2H=Ku3PZ%0W&oD9Dh7N8lFg_;dDPT zep0r%0<-cR9xAIJPddLwzW9f9fs+_>BF@nL#Op&CKyD(%xf8|3sLUdbZYb7W`i~tM zpxx*1k?B-G8HZT?xwf$c&~(6~AEmS_v|Lf~oG{I5>$L$`p|eh@I#lwB|| z??$;=3eY|@mb3VWw|qVjF(h-$;aOs#&a;AW;VpBxke~_rn>F;>_BV4VXTaZoyU?ps zIRmJ%<8xt)+4rXo)Dp#|AGW_t)$m#1r*!omJ-~q8#D{AiDQ0|ie$*TOTws`RDPeOB z8kS;qSK@x);(&8L4NEcx9k7q}lRr&tOw&JVVo9Az&;(ZF{AUN~FGGkNHlqha8Z_%p zlv>gkHl+`@n>1lsLcd;Xa$GdM&^sM`_0iauYH0fGGH_b(Bw2~y+I_QV-pV~^5(95( zu7H-?=hSYEBL;AagBIh9n7BR|i~CR8p;@k$UYsax@#8z1@ibHXfkwh1fj#N7$4! z!hG&dOx7sw;TQMs<7QzZv@NuPde9N`;o@=SBa*m4BnD)!8>b2w&9`YtT53&GaZO;M z^3bZ)*}GT757qE*hQ`GY(vVhbl;<}l=|@E*x@+S|>-`Go35vT=qnvc^aI(d@h4za(k+C!fBYW~P{>ue7J6 zI(9W0_DmAY#Ne|EaQr~G_-HE)`OrymAES~gVHWf!Jrl&Ei4srnsHKy{Jc}*JAsNa+ zV?zT%VmIv5Ko(BsaEg^gY;QP$&BbGzj&0ZQIbG?Lu0$w8QEe^OqS~77IR0#)GzdXC zmSUF*>(OB@F^^45Ge;s0mefLO5ws5$Lz^ZgVhaTKFyLW2q$W1R@bQp8B*bA~36 z{rt(9DhJbG7tIeYanw`OiVXX~G-=$O&C#Vv#tL$=Lp9tEo6RAyT9c=a@Kj0w9bwAm zRFE|bGf_rJ^qBN6nU6NEuLdJ%Sv-X&t1Y?V2sbzqq-bxsN>acutOwDGTd?~&*m@Dpn;sv#97J`-fztk7D}A5mYgL#2!q}E{W|!W z%}Sk$#>Jn*BuQj8N2-e}G0AH(hLMXFjV?NZ!$^;h*QBY+w4EcRx!!Pz{P}S( zQmS$nnyQ>t;`++hruwA6CG#V3b<}?Sw6)Lh%9CdI1`SrlqegkzcLSyVjC>V^}gdv`3N&U22 zn{bPE?V7h%&0pKJd{XjP+AfOLGe?B>w)5PpzmmOq>DpDA(a;#elzixo*?qI?VYw*s zm5@An!P2D*<}cIcL@Oqwjhi|Sr)ulOpUCPxpR@3!#m(lE7Ki^s?w^94X*g0L^f-LO<7Ct&a}D6Ie)n;x4k_ ztl%$u9vFH5qTRzE&OUtfg9ql1U+X#2(Q~+lIOBVFC4ZUJQye|K^WjB1=!c1mwTMBZ znn?pGgV6nSNf5s^uNqSa@1U`YH55_YkE7ufx>oF^JUV~x#*H~;_*;@q-G$?v(x+rDwab{fV)X>8nbdftS~V3qiIq?^x8a8Aj&yIbksgN-gsFu*Ng*kqz*$QW1YoGUDx^RP z?kML;fR=Q!Ig>tuAd4pq@9UXx0PMj&egF43i}?oe!^3!3sEk`bK%~cFyv1#VDidxY z>_9gxJO?jZxCdV%6WxWYbZ4uqet=s;?LE?wJ9Z&=+Y$A~WfNj!<3gh%wB$?jHEv@N zQKrdU<)43Y*RP+re#;J#Vy}{VIP)qu3A$neM<*6;)0k0Nv6BEzp+1JXOp{T+j8~GH zc=!+oz%eytkYiq-{Z5IiCw43&tdhE+Bgfwcqr)&?a50ikv0(GPO-%;-I<`MGe23-%p1!%GU$cz1>M^DkLeA=h0ROmzQ6uBh_w30?N8{NQ zM{O0humSw#;u~?V04+>c3Euq<6_jM0X%z=E6sq7!;EZhGgv$y|ZP!8+>5V*X4}xhLG6g5hG$(Y~PWw5|7w=MK;)cw;|qNADQ6e6P3Pa@A}o> z;j+afa65-a#TGo-RX7T*V5}V0OcIb))leUgHyA@IfQAesPDIuePvolo$N_3!*uQ4O zMs4SjL9GUkSh~reX@f_R8czQfdr!StY$1$_Pv5iFz`wZ(TLfq+I^nS~<*zEf zGTjggRm83N>jc-{G5S8*6NKTm?9EQ!tX?|*i?j*jlTtAsNkpyFm}?GyfRZ%E_1zOk zxkLN2_8qdz?YXaoMg=owVVuPi788%Rc=m7Rah-1~GZ#-vNSH8rtRZC8?$O%5M8Spb{W0!>8rX{` zZ+{=Sd+=hdxQe_ejGIFNZgV8u94KycC~ketxGkItOveOpetY~`KJ`!I>8h2X`gN#| z=OZ@c4>CpRfl2wr2cjbmM1A*BZsF;no8q0H zbFH+@RV%h^v_lY=-1pbj%x)rJuM)NVp|oV|+1LpSR%r0us>KU4H3)@tu-UXMEk1tS zr10?6g{xOD{bmy;)?TopJPYK$&v4N$pPcYTQOt2#<~H|()Ll6DbI8lj@fS1d7Vhb^ zxux`UTDqmDbNq|;G}FJJr*r(xJFH8HrKPmZS&fmn&M={9R~Mzh0LTg4$C_&Xa}8RWth$jte_@Iqt05*ih^ypycts(@o>(7EyzO zG!73y@4N;fT86q&OJe&* z8eMCDXv5uy7ba7OVS^IkY*-K0YS7J|BLv7KeXgBvVFrBJ|#&CsuVNxpj z{S4_2wUvCrkrSttqz*aB9VGa^K)XOO-ptk&N7{n$-for=OE^+=#P%Ms_CSNpm`5yI zSK^3~316VG@`ZBjTBw8CT_=YWv9mxbJGUp*NcCIo(2`fac^7jRs&%|W@POWOHapiE zy!*!(f`VdpoIJ61$4*q0O)&@I7?fvG6UuK^D^Pzba@e9MZP!~AB!g=PA!64LX~FcO zT5xW@7UXlydXQY2T2w1Z-ozYOP)G~qevX)^$dUq$XNxOE_4&E@*R!x@Lhi6?&AF0h zYDqQIT&kJ+OPYxsLaa_mEYF%*UJj!mL--J17jVBe9FNv4O)@wS0cX%jFWo0Bzr-SWfgZ5t*h ztuv&T{=+Bi}82_=h|;3CB~;sj)|Q(Z_VmO3o@{g92~%t=yxLn%VByoE4NZk zwQ{M7tVV`Ehicb$MNt-~wx14ZzM!GqE`?#rNKD(L(*`!s5Io}OM_JwAoD$8@P|3#mVY4(V0;Uc5?Lw;a!3?|3dw<0 z3Qz>D9eX>_!ub@3;;b(o_}8qDVBhC`B-ek-`{LRH_09ViQ`hNcZS7x33=pf*WE`cJMF!(d*E-~M$LJETjmsV z+H~7Lu*vm+&i=<7uI`)Ongba|J1%!fU>(FI@?Yt>YW)>(`!5V!_Qx03L4ecjMmQ}8 z53#q<%G0w|i|;)jJ^udt$B#U}Z-G{@+Z51020fO+6DVtllixpak{q&m{}f77x7G>l zCR)c1hJJJz>o7J#Ti7Q3$98C);wM|e)M}sfOl7Kz;KbQ2 z7I5k^8a$POu!zGW^;PH_WaC-(4j7Vgz|SML|1-w(8*rl=jjbtGfCERWDfq=Jpdm*b z75s)|(vY(+{s4<469*0i#dv}TZ(@beBzlh*8&Zgdp7O_sE(Z{c^WaCIcb%68{TeGQ(2+OlOc(pJlFz?09v zDX}rq0hg&C;b5$SKo@Mu8#+#eZc2w4-$stLsE5I?*i5ydkHLF>!RHnw( zLPbg-z3|ljy7?4?J%aTZRx6`w=d}1J^Gnh>6r~e1*!b;t_8f{Rp(3hsz{P|L>@4xA zTzpFW1*l+pN-AJT`5d9=c=W|EPhW6iAHfJY>=l;_*-Mt5*ML(SC80n8HM%L3+#UCet67xA;KxCuLVFux2mq&<5(fU zEzu#S+bz$V%f;sA=gp<(Kfn|$e+ah7;b)kF<;j*0K5vZX&zDURPswrjQzk~reL3Q; zz%SPD#e|H(9JnhGp}{3RSCPio#Tx7ktojK=onk<~ty??Qq_4V)r8@Us%pH<#eI zgfu+1tnltAelFb~MR!kW`2NxcDh;dw9?S4U3ieR(iwjB(F_%KjDSU)&!QCJ15Ox7p ze0uRS-g$rNly^+(D2zRy^%$=u5E{-Sw9~b>cGZ6}sy$u+LI2HK{(^!DT#AOl(x6 zt0D!LIDb+Y$eAxAlat5Jt~oAY-l9~kFK+jV-E=JV0Nw8M>*Xb&*aJ^%{Ha(D_FNss z{B!@?uo^cA)>PfXuYCFL_P$%kk-cBS6uFp$hf$9RO5ZkC3nOlmRK?8sv&=v9=2fT< zskg`|#rDiy=?B#Bf8PsnC%Oit@hELm=i7>zQ)W$`VmCX1b8`9(zinm@)V2pVbqU`e zgXaRQN)Y!+d)X&~Gj{rJDLd-<+|if&AL_Qc40OY9JaAT`d9M-Gp&n^qhnA||?fOu2 ztOo6oGjvwoNI!XS!;iRez6O8Sd@g}%Rxb2_HsBJIX#3cFg*z6W!Bt`Vlx-6>X`VkP zRiH|fCiuk)%SHz;2vqYqLBW&9jn+1KMyil1&l_>$!>5FX*aa;xEE}z(|_b zP1~kyS8v}of5|588++XDUZvhEZrPRvSv&2>yiS5&=(cPve=U34_U!EKA$~YD^a}~~ z)2JesB^XC0(jyp$gY$gz_nVY-2qT}{dr!-a&F7cFuiufn{DhQ?bnSv$`%65Llg~Xn z>~842ab+;~)EOL={57bx1jC-7wZn8c%K?ytp9S52fo6Z;kUzp>>ftJM7k)v~G$U>H zDtE0|xozvt#Gt*JJJ5wY;_bAdotii|!`-9W;XO&Si!FPS?&1#Uu2g+J3sRhrb>JDU zSm2pkNY4FW6rdM8qf6*T4&8Dm&$v3y&{&Z%k|W&}d=j2hlR(N-t zG*xEo!&8HAq50_k2aF`cVB~i52XO>P+x_TQEiBNZ>bFg6Ye=4NS=q_Nlq5pBfx z$7Wpw-aj9bx!LI@LFz9x`w8wl>3$qMR)TH?J+;kII`bchvahZVMF=7FR$Kl}@+n51k@5R@NQjv{-S^q7S zqCfQIz)fkQpLh?sq#TFE##tb3gzp6Wjxj9e%AxFGF;@)u(_%Ip)HC(ShYa?)m~Yzx zk2+WiO~g6SL@vG((}kwKgS`T@r}Tpkw@{Nxt(uY=r23<#Q0eK>!>4v@z4ja#{8$Z@ zA3eoMNA*@uF&b!6;aB2?L~qW?S+`~T;ca95Hfl#jgoO=Ki>hja!!~D!YjZYk-Fifw zwQkI)QPHD=F~+h8N3faE8(P?+j5^^WT6;cM9A>;KtO$shXHcUmY16M8!8O-hmyP6R zN4u^uk)8>OUoQ>U#E`mN{MPMLzEgwanX51qXB9W2;9;&^?wZU~E0<57ycWHd?gzyj zD^>gALJSgtAg$bxDENu@xHGE=&5-(d+G!(N4vE#7mg~XcJ(feF<(i!HiPjL#Af3g^ z;3yZf@aSaIJfeeFxcY@(>x3h^D1SI%QGOkKj;oUF0TCT$0=ETR+~yiRCwQ<0CggLC z8i900xaW99fAH!#9nr%40e@2ds13U23j7)t`Zan11V4sj>n#*99dXV>boUhgq!u2Q zq1X%f5rA$Ko<3c8@i2dxYzr>ZwQ3yY=b?Ro3t&5TA6juz{qx?S&e{!8err6{q^^Sl zsf`C^$(o|uJPg;|?Qz*L0#h{WkWt#zxO})T16Ro65=M@SOW(VDb$X6gC6>n+a`OZl zJafd=lXg(<%S4P-O5tP}VgBTo9f6emSelmKe57!2Swmk-0cH(9_=sPgZ{c`2mNj`1 zh45b787ql@;{Juti_aN<`Z%_StVq8sf^=P`7}77TNcUulBi)oK1?jmjKa8~KSFO|z znfyq(_vwH&-lL6`BXNyIhZ;s=NvgW>dn+CBM~7FAfPc|7r|JX8xF%~UE8>;_N3=mY z3_LpGnjifxBOT7`9Tg}eV+Eo^{emw2ZcJ)0&X&$akH@9mc)76~o{jXbQ=W?M*1$KO zd9#(O&A7tl3fB_ZX~yYt*eK#?ZO0?p1qD<#HKbp;2g}~6IWk&7I^}iZR6TGl+gF^1 z262seUoO574+`LGI!oFqA(mv3G_si^t;PH3v!78SYt0}dU@po_$f5*xsW^mgwEYPF_h1d@&+a3XrI^gmEdf+Cfp985}vP~bZ z*}5`o$)1{|&dVtw6Gx{;){NW`lbNul%&pzm4?nm2y+tk&FyDjJ?9hwIhb{KoF#x}m z$1Sk`;8u2|(pyJpbm99|S>MqTK4OZndD-gqnJbc`L!!qT;xs86re&-_+rQXULl_aZ zK6}lg6|0tOH;vwI$o4BUDKX)T1huLi)D)^hj$rBfD)xve64p8#h zM`rmS=|ReM*P;KVdDZImzJn_dXKCh4<*=c_OZUd(PImdNr#J)s5fgWdf?fLJr?+t61w9%azfQr2G$JiYU)(0rkTgdg_QB4y z#Myp7v@{N6fVQCx*u5qwx}ngRje#e%7M;UJJ$f~FxY+C2!6O+v zw`sl3a`6dK zb_hm7T%nU`0VZTEK)2RascN?zS>LXpDBKk23(})-1zf_BDw0u{_C3n{9_`6K@y5?r ze`fFDA6$Poo)g@Cecj!U`kp_3^yvBXzDM1)9cC2a6`U;d;u>v+M zgY_%W)l`XHKqWUO!8u``5*HPl;1)Ne5`OW4nsmh20DeN>x4-YdcuF%&;WealP+PTg z_pQf;Y(X@ zsc&2wJ@~M8?ic@?It4=_W2S;m3sc?)X!~8|Mn?w+j8uoltvwbx7|tgv)$Ne)zb~0A57mN=~ypr^HMblcQZ8n~4(hbd(JvbXf zF6D(NDEol>)k{BJqwE9hi=Te`{ZkoehUpr91!!TWDauex@r2+Jy6%5jzx#8 z+2bEy?i;rvVy%|Hd}7mY|+ZaOXqJv#z_({LRFlFv_;>p9z;PsIl3Je1*mFbNY$5QAHLY9H1cGh zfT=Am%8q1UCm6^P7tCm?2LlyHNiz<=#PldM^e9^8KCgtaw_pL&Zs9_ zzk~QL#9^9diC;ZzK8l6{a$|>zgXBX?%jZ<#7MAnB+Txz*O45vV)e3=BQVePIsfW9% z#Mih-IYPw1ROQl=dTALC+eC9h?vWo$%*VZ3Qa-LqyoU#`oThoCJxa zvI6q)uZ$|W!;=<@*$cB5K3ceGp@R4?yt7cLNpJuEm2xG(RaRH{ocq6*yqCNzgcl%a zLJTR5hy(!xI*FoUL>dYrB3cItghdD;6Nz<6Eh4pyAmY*tGSs59fYd4zt))n#qtOA{ zQbfzBwR9!{7mR=mBoLO{@0|aC@W@X4?tI_f&pqedCHMZ!U_-%Wq4?(fxaLamb8DuA zLd}&`p@in6;gh$f@-ZT(pKa<6e2>^B^9c<#nUdoL{&x7unB%1}Q`Q9pYp!z2978PY4`8+5=`xJD6(gokggJ+&0LhB&Q4bW<$5v zAa^VJrz8DOq@%Hl0;V+{Bfp8p_mpG0!fAWTSKJnk-<~r6fWKSg_Y^kKm}@1vkI9`T#NtggYEpu-BZi{N$0{hd9+<0%gq;llol$J+zIVdyL6 zDLjG(BL5}dV>j?b7p5A0tErcH8vX8~e8mATeg|=-{n!_v5oS|6SPC7wfb$jFh}|xd zcn8LDk%)M>$)Qjiyhu6xHwy4xKw`kG#awm-wAZ>4?4ys`!mPktmfOZQ7)fa+8Ye02 zI27iU6wm7@ql1}LVN`AX~YfGi~mY#oIyT*l7jqzwY-^n@^a+Yq5K)tZ^T@!qoi)P zi^PC9;F>a;ZW$q;6pHU(Z#}8ru zKZX7kl*<+NIBX|g4OF2VFqv3inf5HF+rz+FZh(vkM4kuwh)BTO?5~^{tY6s!e*|O? z=OO<#_F8~)1)@9R4Alj(qy^4R@JWrWkL1m5=jw)N8GP>>L}~tJ%tNH#J~=mRi2U-sSqGPLq6o|fd<--+yOd>nRt*NBuCrD(N=Ss zoY93vlPEm9V&*&=R9d{Sj7Fm$e%4Yfq8P|ap-bp8`e9T#qb`AZ(xsF|In;}sn{Jqt zNdw1?FUq7*6UUFsq{*HHLjg*}YE7s9bh(xVFn*AdD3$t924&Mguhd6zlnhyE)Q^5Z zS9qm^l+-mCnDa=r4` z%7>JXEvP6d;}&5<$}!3z=@>`*pJL5*ssiU>_^}!D8X)5 zxpQu3j^p|fPg6gKRzkNq4&$04B(>q>UBI|tX{yctUq(9duz`Z(N!1L*0noaz>FPmY6g z497E83WwN$6W9SKvJafZesD6RGwp#^aX4)le!Uu{8JgOlDMQ;}yJ#tBPdn*#8{I+g z({}V@S|_YBn683krbap>bAr^jggdp?XA8qJlyWR5d-Z3akJL-sa*Yeb=^K3oOhwB=X^IX=B z%w6Ps$2!n+JaT?#>G?fa&+lvX{DqhG{C0c0=eC=6Pir^rp3x~Y%I`0yGUbKJ4=XQH zenNTqyqOhc^sMqKb1}o26uU=#$pNghU9Zm zD39dpcr=gY2|Sta;psew%XlF_%uD!5Udh$GhS&3}T*F(qmg{&Y@8-Sy1=n*UALSE# z*7!`ENjAOAr6$Ydn89Yaxz>y_g{H_%G*iq}Q)1?ta`S+xGKfBzm?m@DF;2iqbiz(wC({|=41#@E+7qx2j9ZrMRmrDNf;~iuKoXD) z^aC=1%YXvlI^cR>6mSD@BXAQi8n_uK1a1YGX4})AR9E)J@hR=wF^lG>@b36~hwWV3 zQtiqALyH#mPzy(-w5Y7^@QI5YwL3C9Z}XLo_&+mN!6!H|EN<YI!Zr<#hWO%-FYNV(@+;id`S5#ceYcr%#hT zX6x+t_K!%q*a5oJO8uW&!^j_x|(sf zhi!n|ljnPP>?N$w&C(7&QZ4Kb&AsjRwfi)8Cc<_XTDG`#owInrwscQhwA2wgktj0( z9o-h4OT`NL)NKLVWUYMOiCnGf%p!MXc0OWj`4K%^mtU9{J)=v+x9$IMl3-PyUpMw( zt9Hh0l+(vQ+&>5J9;EEoZi`4ud&J8h_2OoG7=I!0lYI}C+o1mJH)5-2FPmAW6epg% zq2=~agWF{dZSg`aT^Q54RXo3AjEJC zZj>S1ru&==8JvAC^x=VC7{ZZ|#~L8$=g^s*9ASJf5x!S>xpJj)w(_;gzZ7<4tufD5 zzDxOPEA%HCOn=4=t$;qJPw9I4 zoc7VpbQEDM{;D0PAK^ZpKt-IzSu|0+MYnSf=g=ha7Tv)kc%-~pbYA719KvXEIO#HQ zw-=ql&?yi46+mh~x`oE!9K0Pm<*H6&pwTkCmYzbG0WUmDCGDMUzzm6M@s6=wJf^-QjMW(2LJjdTs(r?1hC@Xl6fz71<~41I_f-E9~HuSD1x z($HH+GWb3d#tm6)PgC3b!uG*<$n?7IYhFM| zq}8+r>0i@tkY0-rq?h2$UU*Y&K;KtjXAfBT4lH;Vb~1f{&|9sI(R~;T|L=hWStY6T z8A4FkN-F&a^U_D>MP5mA_leinRS0^^339ELU{@Gk-}c=?QkzvbJ3_{OMLa2wb4B%Uzp1EW?t{{^?S B0!;t_ diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Bold.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Bold.otf deleted file mode 100644 index eaf99a57166cebbbdaa5b9c0b7104aedfa196760..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45968 zcmdSC2V4}#7dXCq$KHwMRMsQP=`CV!hz$iBil8V+6D%M~IRUBC!A4><32MH^#1eZi zSU?2@#a?6Yv5URLn8fxL=QRH}dq-1HWAgidem@az%gmcMZ(f@>Z|2+w4RU9yGwF<+ zad32YwiFxM{LC<_Dh%_@mA-wPoaNpoHViZWIKwc_`+B&056|A=VNnSw0aIIaW0+ZY5#Gb7z?4`v%>!St&GC;SIxtF?Wp@{0vor8k z9UBv$@OK{5o?&V{#P^mAON%nhjQS7R5jDHLWaM)CoH>2Fo0tMOXKm@rPpYdK@VxEQZZn3_zm@tR}$F>%Ig1wP+yyspC3W_~eVo0hq*#?)i3 z7@t=!b6ta(!8|uUS0Qeb5J%R;6fsI-7aFfwrjCp^Udxa&&5YM_rlYK_@!EvZ%7Ts8 z95X}qrSV$9Xyvty*HsuRd2xBuGS}6Z_Hs{Snd)V(Yp|B`VtiCgN0a4_F|ny};h|v( zmTN8B+qCOw8I)?-KQS^~mk?;_6B!sClN2A3YHisoGSX5i7H=7+i`T^^=|ZgCVxkl9 zGA=NocT8kRJ8K&oo33=ox|Y6ZL*JC%TGCrzU0i&4Otht;f`_-IjZJ&0Zdgo0a7=U( zePP|%rfXDSgf1pwlyziyPG5NqGI zZE|w5by`F!?L}}*lyzWS+d*OB@s`eryrp-{sD$LeIGrUvhzt+bMaSzxEEA(cba9pm zVLD517gtO7SY5QCu&bd!Ys=COw6nI9fEnvjFo8*d;gNwskvhxd@PshSKuhOdo|b_L z_LfF;;)CPDV-w=7mpf9&iqSz7YtMmKlY$C|!c2`knBu6Vrw1 zfOmFSuMesOU;K4t+)-D#;nhH9&`0|6aZ1xsO2ARGXWHUVvh-ukq)DStJQfu9D8wcZ zsooab3_~30SU5|4qND7MSECS4vQ$QgPYfk!Z-TLR(bDLI;PXVh4v}bRiRHuaiq>|) zURh$lVx_WWA-k4?&>BlsGy-&-Ez4k5zTIMM0+IfK2#<1G5dNiYC*wWE!xEp-c6%|N z(scq-#8TqnQtHHGUnn=mVvTrgk#a#Ke#YR_P^64I)_47^I+6vTwgG=-b&T4$KGlfQ zy@D0-ohbvXy;PDZ{xsZG_LsG1E!c)^eb#{;#QL*VY)iHkTZi>!>$28t1GX{q8}o$u zoq5Xq!Tibm#XLhh@Phqzd0%OHAV%lIw+adFIVY)MY zap3wR8+xN)jYI;DLNY|M%~>_uf*sB_VdIcgW0`SGI`cI%o%x>m0j=ReW(l(#)j}qd z#pE+Pm;z=GbBH<0oMX;2m(fDqWSg=h*k)`W>=lQ7uEm%$-53XE7&8W$CmuJKLV^z}#W(vcasDwPQQ7 zK4{PDqBl~H(J)Pzrc5)Y1=EA+iLLZvhA=}JKjtSkhD~M@*hqE^o5V)5@oXX+#h941 z#xkR^_Z-s_>2AkNV3jP7SP3{vt#FjwSU*;WJ(|GIL?5HG?6B+?*>!nS`A_ma+R57I zmUS#GEVY(amQ5{fEbT4(Sgvo#H?(Tlw4rsw04teQO)E1iwUvdH)~c0NKdX^ex+X`7 z?C-y^O{&K1nI&v>q?{Hxrx|jLE9=1qApN4Tt-9FOA#CfCv8{CNGfUpGu4R2oOQ|ii zeP!D6liI3{ZPhDjD+JqOrM7lpdzJkAJCkAFhT?BF{(8Ofe$&!W@RmS73!mR=Qdm^D zsqlwF@4|jJ_Z4=&x#*_nO&5l_i9X}aHa8pIAUB>d%+(*b+sMhIvC0%y#a?3{voF|J ztSDn-9c8vMSJ^O`Kgt<;f3gXNUkY9Jm28^qd;I)fHk000^sj7rESX{`^D(*mzemQ{ zuE{ePZHv;9fbuh#HA9YzKnV#&PKah}Gxync3^1=4k+now zpuTEVNm8q!tZGnN>mr}GF!H$>%5E=-*PR##))S4GpTzOQP)+t@4x&VlL77fPsZK$O zn}{+!S(56xDA!b~zeKs-f|9)nrFt{#%xp!;K1OAmxr!d|bw-IQU5@Iv3Mz6HGamim z2@KDC#nfRYG4+|L=sSPMG+?GNUocaUr~k(^L~nN{)0$a;@-&ZW#mr}#Ge0qnnV(UO zFGikU$}B^3y8@k+RcLruq5)pb*fMKS^46iT-heW(9^IT=bO&;%20)i$Cz{~hsP=cE z`rnJjV?P?_eduf)L34DN8P1$$Mlfd?f94buz??w?auJQjHRQ!8rVtIsZ8V3s7%%1k znzdh02Sgb)Kq6`b>d;(5Lv;ZS=C5dwZA>2%8sKDcwHfmh z0zhM6frM;@CZG!v!x0UD2P*$Sw1e?Dfayr)X-MF?NWx4c(+(WsV~G4sG&O%A)4XBj ztSMVlQee&44k#$S*uJR52BW#4%r~B$#AdKRuyff(>~eN3o5kj`JJ|i~FYGDy3VWY@ zf`a>6rjXT=nai}Y#xfh3z03gx*h4m0<}VA9jh4m8#-iYUjgz(+ve~j_vW>DGvfZev zPRP#6F3Il69>|``isUl6sl1llTwY(^L~bp&mG_eOmwUB%%@>Ka(@@eu}@`dtM z^3C$?^8NA?@(c3o@(1!i<*!ZTCN)gVO)O2Cn{+U-H|b^4-^9~oh>5>Rs7bQPS0*z| zel}TRa?RwozUaM21qKGAm!9ArmKYrx7?&6o8JL(bI50RdK{q%!JT5pfYE+~yrB_g# zE=lJe6&M^B6YbJ}a7efg=PcpzgG1v2lXSfd&wIs$#zgBPTtZ?J3^0e50&p=_H53^t zRr8Ws@d^&4FcZQfLv+K8PfF2pl%Di21>`L~7*^7Tqf~uBnVxtD>q5dKBLlt5JPVZY zca`e8N;Ucz|Hj1xCJd6UUCWerMfih^a0Zom9%$%BprIR1QoVr^RHqV*1{$80spVv- zDqiiU&-rN=BA>7m4q5 zhR*cSMJ5C$NF@@Cu-v0`q4=nDSapV;#)gMV9gLRRik9kxmMIop<~p$~^}>QEt4iFM zXaJQ+$(1a@i78t$d~}SVTyiOSl8f0l-0&*g03ul;ZMejV(c#fL>yYS}s5D(%jCFKk z6!NG}`b;f_BfX=A5|RyN62g$KQmK&eq;NVVkBpu>Jd>SzE$ zdLwm(_P|h>7NWc(0W_479))8g-r=Fq@i>7GON|ZFMMvY1(pF;w;}XIHBSXSRjf#zn z2}ul2hzmr<35<+SMD>w?y^Icuj|~jgMaHD*qC<5~iE%My25wY%Tzo{PUj8<>sk z4E6`~?6c95H)0yI3)m%SyPGic*wySB^n5q7)JxA{H#51Y+Vjy9ZqDvxzd?VYB|9Ch z`!@8dXEOQhPwXuAXQmZKpjxv_nKtZ7b`_h+u0!Ku&9r4Vv0K<2wEs5J{9z}vi~W|J zhBJ)aILBy*GmQ332X+n`k@-wVb`i6OUB)hFI-xmP&u&0#z8CHDe&ztXmCa+fvjuc6 z!+wWm=X>^lXy@&5p70}ch@H)JW#=)6*~Mt6dH~OIW>(m6^ym^yF6HjISEb z7!%M#tbzWX4Cjk9ni+@A#8~uQ!q8i*h4UPL^pd)vzi5g+<#*^Gsbp2rS4u(eClWoq zaP;zep|6+7u(Dc=PG*LVM=1K9K}?8D&5V$lGmF_*bf(I_W&f7RnFcZ?`jD%bHL_~5 z>gcPc;cRw+tcFY_t0}9EzGF}H2Z!T)G!y5kW0<9~FJz|Z#;nA7?9b>+eu=Zo$>>i` zLVt1`IyUL(nSRYol<~4UY#Q~21|pMR#OdB_?7W+79(om_^2;WjO%|FwFW%N2UiWalF7@VFm|A?JX`$JqIalATepLPK^ zP3x=85?CQxxM``hbhlj7ux7)IhIg$RT6tRiV0ELBQ=_jNZEW>0UPV0QXi(QwWx}3FZWfyFB!=ATq zY42%2-Tp*Zldhe*F6;VRH^*+PyQ{k|>;AMy-yR!#+Vsrm`P^ZU!|h&Sy-j)t_bzbM zI(jdfLV?A$q_4JzHwZ^-yx6V6fkjbEi zgJK39@nL+teRlfX@s0Am==*H&(7{`WI1Tx0=+R-z{D%0=^V{qv`aAi5>3?i^)8YMw z?+wrd1Oy}n>>N>TME?=9M*KCBA31&Gqd+#WU*PP(lYtL|ss=d*#RlyPdKKJ0I4}5e zFbN3^`6cA3&Q#~B3)79${W_}CsG*}KjLIGLBvc-%3GEO%AaqLT-q5>Y%CKQ!x#4_x z@9>!L1>uXsmyNDBdfw>2BfgKU9qAvrHOe|FF6yVK>rq9~meGBq)1qI-c*l&5$%;7^ zb0@Z5Y+&rMG0}1TpUPwJm^EV)Z^c=Fqn zSt++tUZ-|S9g?~zbzkc1G>f#3Y5r+(Y3tK&jn$4FFgB2MnYvSavXjNXjd#kYnuy;P zdFa1Y!1v^!n)HAlIe4fbmSm3_=#74+Qm+V*uAv9Pdxf|g@5qmY-l<+LNdh%!#D2-_ zl%geaaUH1DJBgYDF9q3A zhNK$@>2Iok2CVDQo`o^MfC(^iQC;-C`qA-Uew!f>MiKsPVtk|~GI9BaZ|QBT8OPlo zX`tns8lTb3eP|{17_Ju0Q6DTkXv;w@1>v9-N3{4!T5(YL#{4q?KZdp}gn~^r*vKKb zXudjc{kpvT(dz;NMn?<}SRaumfRFim&-T2r_>8s;J$OXvURTi&x)GZ}99()c{xd)U z2US?efK0i#q-cX0s*p@lMG3iYT7Nn)GUB#N5+oQn$|c!MymyBmS2W)oImy$=NuHFG zc2iC|sMv*kwoefgm>d#f;kF}b%eKwSx319g1tWHGDHFy|9IKfy>Bsqt=B- zf%+ND`ID64yM5nzTA9dPX9<>eGHJ9<%~mh5=btAvj` z6uGD~m&Zp%#m7fR#V=pGcKPzP!ejlu3YhzMXiHjwjTr>LgeEWer|?_R2{r#}%}W0x znll@Az7VVwF<*{P((+GZVzzr|oWh1!2`?3EX8pWa3xnRcelq#Q{!_v7N2v1y2>8>G zG=K(X;uLV=b6)3yrCM(WR&WOdg1@2?8tU^htQ2}HDw}Q!{`_TV&cW9TK8G|H_bd71 z`u(s*O&k=^8gjVB3e~Qu&;Z&(9cT>o&CY-mq(Xnv5nTBfXNo-3Z#>{PCD=W`2-WU; zpYE_g;Kd6|@(*3Gc-8C_X{RODq`n#&D|W9RgKQi#SRjoRq>c$b;a{A{iS{2F6zxKv zsa8({8?g^UfEZfr>llM40?Wns)&1FM6vk)-H7wk%Rs#=)0kdgfR?wZLNkHqzeZv z6;K1Za73dR*mmFp?kb7=*Nu^h*Q1gkHc31LEzFQW(EkZPPP_nV>QA6V2^~Gbf;5AH zNdjM>>&8u=^Yipsnzi%CCMSPB z+waW1n}76pJ=L?RU?p}0EA|XH!%1+F8(Cnx5)#208bL6Gkk(*DVg*u@SgE0!0=Vn8 zq!y{!y)$72!YfpuK_FoJ2q>Jtke^N=oWGEj$i60R{vrpUB4D*pz`zzdJR%*iUUg+T zs3m9}#L+0m4BA&VA|#%~QNFFHoyw3d?)XEff->M74VlNmg=hFD;^b1D$G;#gtp6$G zStz^E5Pt=*q{z#~x8eacSnBiMc!>M)vo^lH4VL6K2ujuar5BasY)B%*KdG{jRB~uq z8JXZ7dHYGA&Z0q-5MO}?vAiLyr7#%C(IoVfKwX5kl)OD9BZ%aE1>e86RTta8V%taU z;QP-U^$Ki5$v>=!a*A@4I|>76Gc%z-w($aU6$7n{<2jY}&MUk8YE%04wz7 zp9;^=eP^_$22%>=gyZ1!Ck};?r-C4pVk4%OGL+bsjF)f_EAG?J2D>=|>O%|sZ6qmZ zXK=mEPbiX$N7PVXzZ1ErjWT*tM}aLWfXP z6BlJt;P45d8d9bGJ*WnzckY4m_}OUxT>_u?2h`yBOUE3EY)c~z8AI$y8#027gigd7 z!heUVoAz83U}ah8&=1Eyd-Rg;ctlbKkDl7m!Xlq&#Gmh|0LR2xMj&5JyUGsz)aA%{3iL$m_6k`+o7dAcO2$U`bBhiOu=Hy%nAcus;g zq*ju+7aCJ>5IN|}=M`lad8+lDNn`k$Tv2$%MEeJMuiQOUYe%YaeSWzb^i%^a9^Qf$ z0-vJKBgtyoD1}z8k=x~z(zZ9#-z`R+XsR>dQDr(K^Ua)hE1`pIHV$n1fU^_W@DGoo zYT*AYRs;h7up<2+@OSBBd`mrP?WDK1??Sx+0}QBis7MXmee3*g1w-kn??`*S_d6+h z#!@eLmC7`vyxC9&VzK92qAy>sw6yVvjTBWg0k-eSx4Z-Fn?aUDmVYZ@=$zYXErcWm6SV@KEqKS9-*62T%F zT$0(l)L}Uy;SLiO&}(P(3(`1{gAu5SW-6ORt!Z?A2}f>;F{o}ba0oqVTOIyp52Q1H zGYiuhdC^sKS=mEPSSb?HP#hQfW1-U z+3Wi#$**D`jz(u{|`=!Mb%O(7a`O>j z*!8Yg!S0lVJ9T)myrKf!p`C)9{@CzQ8-Ua(mUsl6NN1TzV2@IN0nWcG_K)8e`wIrK ze-l3nOvxZJ{-Z5~h{en9jwz*$d3xn{W*H3D>(5bQ7GJ_)~o$p{wrz*yD zOoUeo)qHexhoYk!ZWaw5Lb8yBNyb}68dyF>Brtuxp7sCt0QVmrVm-9yT?iCQy zT_9Bzsuc*r1ZPJHQ2&8s=^!0LOfXG+p?+ZW7)(H=1UHaBf%edn$nO(3fv5;hh7v%j zyu3BosrSgB?x?bw5<9RE3k^{!Nf8!JUaB5FG9WoZ6A`^|Z9LB5cRvIk+FBGV!4e)B zE)AOQYi-N?>+Vl9XRfT-u~*Q)68j^d!QeD z7~Ek1xXa-|(GWH1M&x!xEs$xV;sU8<5geA}-J3AEM;*1!qyg9W22>vbrW&w;S{J}l zfFJYPdang>PB~LJ9F6V&f#!Cib5qhMp)%*@ zI2rxlwr+@K`avV2N)k`t+!Jwl@+2MH`QhRl2vL8CRK;ZAqbi|0zv#li=Rq&N(sip_ zVT5xyjc_h{H^RB1fa8aQ*@B1XaEMBVgCh1L*v&%B9>P>{mb#+BE5@i2d@ADuUc9g0 z^%2JNT_VlRS#+(?%l=E;i;;BwW1N}m^m}o-zE`O-mN}h>e=_J8-^m$ z5CWhOIy~W1;Enluj0uF6Hnu~-=LL7JIAokc37YdRL5ndnqdA z12bZZmSG6gL_6Z9RlQqR++9wzVD-R%2#JO+iV+bHRpw2?ygvUBE{$#=+$hOwjKI|! zj4ng=r+bYMPtyKjlcoI#E$_4SSDJc67d4bT|{U72;gD8|P|AWjK5>XzC^GY2) zjF*nI{#1yM4Z)Vd$V>;45vCK=y>kkEl?g?j$ePGMtrV@iygJ*uQGRNL{MD+2pR{YH zabt98x>04<8+VmkZ(O=)VieluV zpE;~HuEF=!&mn!qIUMm)zzSURQ;D6XVz8qNojjUlyuQH47X5AxV`=IB3O<`?uzUkr zzPEx{6klWARJva1s(`v;3YhCtDuUx&Ub1#lXX4)hMp=_^Oeu1$RM0kIps=KwywAd) ziXJ>PEIN!6Z9i4!AOoX`B~2H6R?~(d5TCvye_wni?ammOU`Ej>xfm9NtIgF@LXPd@XFjd1zE;>Sz8fJ>o9C21)X#ODS z4hQKq%+belWDGbd%a>Qb<4QW~*L_-js!ydRVIz)l#R(NF^|_x0Od3ghu;~j8(;+_3h^zj(AQF`%9RvXlozcj#POpQsT)pPf!3A#1mx~V!QfgM3-joV>19Rn zao9rVNtN_rz$7pwm}Us7hY!KrY!$|b+@S|w0LR2_>UKR7LplouM8T~&aA=FG+j zUttolQWA@d-tJ8-nxAn3<@p24^EYbwacl?!(Z z!1^ghqz{ks(WokI@pth_*_qDozW;x;zxR)3xL}3d_AxA2b;Qo+JHT%7cQv1zUXq=} z=cgMIl=xhSk{l&0Xh>6<<5M}R{C0;5sFmtqBp0@2q!$+aG?E=fjaxiUyI`{TsuGFx zb*&t$3Q(G0#AsJBLZ61sNmR^;%>YR?w?OJ`PlplW>-RIG_#I3|$x(bkx^2IIglJlN zF{`EjGgM2cRscUzUMp1#1Bv}VLg6!+y%7B*q!p$nxFMk!e!JMesCsca7QYi(+5RIe zQjK)j`7tth6nj;s9g<*diJ*Jjwna1o(%}Tkx=oJ~SwCoy^+@08!dIj*74}{z?0j@O zmG>$a4Due3?xy5NF!_q;pp;-kj+bGfi(kx0PS?1J<1`cK%C)pKhRx)_3xxsG7Mc^} zv>E{pRR*UIi}2O>MN4{OkMNFmSVdhkq*yw-W+N!c7=C9u3g=mMu~Sy;qzT|qfp@mm zVGi;8M>I_=7R;?Bg86B3aK;$%Lu~ufh+k7gH`f7X6}48Q@_0YWm+SCeM%i9sS~;%# z){68<3A)%+u^!o4sUCrSlfZ(mU1+SnNADUj&O3YRF^-LZ$ zQsC#OZweZ?q^qV|$HY;#!WL46TXW=>`30KO*=PpFQO>BB;o#lWqS=LhpnCRe&V^hp zLg=&g*TCnRKdx>#vR|;d%Y}vxPw~^Z_-#2oUJ&al!1E_GH?>G#%nifI(8<|3+Yf7w z=K8q^{G4?CR7^tgk6M+xW$n^kXfxateq(}@{54>`S3Tu_Gcq{UlF873d;wp;1`KBo zO*Xp#z2Ix;%@>HRDc*x(hUo-YMS3auac|N9KMKw%hi*C$b4CNLen%_U1-do`IcY5f z>f5WGh8?(hz2M-Pa|NDuU50r&3aTcPK?^G}khvUs%i#cmBwaCIR8H(k7m0HAptzlX zWt%|EE^t8!y5wOROisRWEq~w1?b%6TD+H)@k-OyIX`7{{JS;J+Xn2|Iwr~vX|7*az z(0ibGJ}jD6abDZ6B;wyRV~9M&C5f%U5`)IQU(k#;JMd9|xZ@=qYx%GdG)lu%wh;S@ z;}R98vaKk%J?F&M>=X4=OTWf+I38oQ8*o&HB%7_k!Jdp7&h7B((#4OCw)-TE zj1LASbV`P5$;Xn}rCynLOpb{iWi-Q083*cO38vWrV;6T z=(krwfU*QGxZ56@m5_L2k)8NJ&2PQiU&(JgNabm(r!8K#FC_ej(27R1#0OZAKJ~nxxC5D1S8Hy+5v6>mjfr&#pqZ?zOe^e~QWhObCQg(0>u) zA;Mnqsk%51usAPJ;PwCW`cK<5l6zKpXVIB-`%hcJwNf*jc4bD>o{6qyJi-^y2p3EL z{dgMOzoAg)Pf6@h%6mYYJ8{?^!;gnURQw#jYe-Cptp%}1`D3A%mY=X8bLRX^A>2Q4 z_(%&^OySSVmQwg>NG)~Z_z6-9|APEqu5RCJkW>HU;hO#6sE7*c zU=KS%5;!2#C*n0RizdtS*IbmL+kI9#XH+2?>n51V*zPw>$2_@bW&TFNOWAMeh%TP) zi#H6@x)W0_=tyA{Za?V_Ri8i`fn>i>_Z`0X(&hZUr%vYicIy$~(@%J>(f!g?5?eNI zaOp|gXZXtwaEZ<)FP522UMZeUUMMr0ylk9J@{b*0uA7AN6^H-BI8#CufZZI4R5##^ zcu9>(L6+mhp&L*I@<=c0(ZM3+h1|WT4rPV7YDpg6KU9KQ_iLn@R&~VyVa=m9 zU@tj_2m=}5T3Ims0x*NBN`Cz#f`1pBqn2&GV>i5Pb47n%0?%KotO0@>s>G~h%tkaj zjvFkTC8GTaHbpDn&rRkZ7QR`j7PE+hJ_|E14K>-*;2?*|<`q7^S z0NlqZe}zfhtMsqltwf`3sbGV+y3mBo!$q?yNyx<1!U|Hh`G*tV%z7850gG=@E0)cr zR+qsz9ObbAsgeZfJ(eRFPCbSYS2`}Jd6HaThLoMd4Hslg>=@0hq#1G0=;$LTtuk?>NQr$oE$rRo(D zaSvPZQ0S``r+FF?-V3gDgh@}D?Kuvb(m@VEtTyZR?A?S|={ETYeA=y2ocPoo#Yvyr zlX8r6;q4Vng^Q6Y&I?O;IUXD)NSUD5ixz%*CTNE@3ro<)oD~Dbi&7;1JXB0(Tq|sc zsJ~CpoZBSh(?}>HXbn*$A!xI+ICQb_tweoXiqK~&{gUHHP17dg03->)q}rCmf{A-G z>Vav-g;Suw0Vq?OE)`G!DR8SY4&I1Ma=maV^W%WSC0T@cNnM~1Nmr#!NeBml3QSNh zgkccOks%69a`fcH`bOo^OsNVd6K+J(jchp1Seq(}rZ}7M4WL%;yUa0lvUXi*Jv&kU#tLdnQJMk4@A#HMPHuZwQ;DWnL4d}%>fYK6g&h1)j}JrTTu`(Y4M_V8m!Pn&Rep`_pWi{#EyFEh z)PO4dwYx?NFUAnT`J6o`rfUyu3_%Ztnv})L^IP^D$0u2aCk~R4>3NM*)vA8NwzSZM zG=VnQ7PV6je4c1887j93oof~T(j8PxS@>#`lFvIfb4%V)&B5#tR|?ty$Y8B12Gpqh zoCVtYq5=F|xR^Xrf@1-!5+7AKO<9V`BgJi8D}#H%C*!^h>=qyya>|k6d>K$Vm4f06 zdg%*4l4DVZQpG_wq3Gc%azbfYg1mKMIUje2w#$r6h?{Lysq1WJvbH;zw zj3Jq}x34r$9E8z0nidg{o<{M;kBWAElsw~~wWP_k{|bZBUbZUlm2CUBBrJgpZ;Etf za%JC5oo$NwU;nBLbQXwXl>(Wm5(OWM!%JNiTqCu_nc(L(P`y=>*d1zqo4kys%XY?D zQfGb@?qchp?xWym2jW(3e$@1|)M=@jk|t`OYy+%L7)si5XBByv2giT^-GYS~3pFLI zUAx~y!fX=A|Hy1Lzv{uBU#@6>&S*Xi>KY)$g`q(7_UKZBA1G{TW zc)m12wznshWG|`H7vQ^hJ)jRH#b2NavY$m0K+#nbHCQ~q@sK*I2HF>ypgM^z8i4}c z$z`->kZ^E>^ZItBG%*VI-P7w2Y!ke4PmI2&`2)jL`vra@4Rnv9f$o08HlGOpg)ec(K64EOPJa9wz2H-LJS+69< zeXUH4n}2c^{eUrOWfql>Zwvf2V~AT@afrJNcp5>MCR-RmmzM!f1L$wNy$}1tvGb)A zZ+Fy=8{i8J(Q8X$iF6Jw8a>8qeLfI9Bn#1;W4!i4C4ocorQ{i`PNr53mCR|FVweU{ zYr9tQ)2}DC|M6879)nfN9vK6}M!8l|m9LTw%gWnV{`7OqqB5B4j{rDhFs8Wit4YO% zl)nVgxNG@6XnB>PL%N|y^eMgI*VyXEf5b?VR$t@h&C^hg-3lG>3U><4L#Kq)ZsShm zLI&}KbvfNE;^HQTyE`r4I#4@^;2!uiYQ}jn~$oP!u+BGBhJTNo~-L$ajI)T<*BYu7M?ipz=97b z9+%QFpm-&KT>>KZ@MDNoj8=sM&!0Z5@ADBZ`)(@cZ1%_Cn-AuS97KQC3%Zip&=sBe z>qTE-sIpO0(oWE)gM&Ctc_AzJ*n#!o1MvVJXDv}JRPrxw?1=R68X4A82qHBL6qqo= z-hw)}ypGr}#X~6$uG@6{j0Mzae1){d?UJdJaL>XrP?$ZUP9AQc<8cpL`j~{TQ#BD8 zsS9&0F#WY5Mgbc_3*tapIuPz6`ASJlE_yuQz31m;n-N4hf*@6s@X!jyu|f)G4@%rP z+!=M@Ba0>lo!)q*lPShehjtv;(d8 zdR-l-<#TjhD_%6KB$-ztm$9$3r=2C;lKqc~#)pyCP9NcdjIVL;SQFHP+GMjmsCoyZ zHqI08OS+gWQuGe-ammmQ3fp{4fNeNmd#EI4zjg)F%ZJw;%hvKK?dhbgVi;A*t7mvc zwex3yq>+YV%nD#>WhpYE4-Geb9R9d>QKnHfgx_28ceU8dr-4@gP5;5?h!NGbGUzS?B~IkvV%(oLmXA= z)ru`KFZh$m|BWF)Hw1YPH^gTpo9(4j{o9>TI}8^eOEFap4e(Ll^bPTI&8XrTYT!Qy ziT^Hjg{oJMNc=avy^;^eFAmk=x`r`Sx2SxmZr-{zIYL=BmC}TEN9X(07=ig=Ze6|0$JYE>3T7c;VnslGO;BG#4?K1b-Y za69eFsW{(kVkrOG1+#`Hn!`|9zB?_?>P?AUH06k$f-uF`eQ-e)>w<&gB|Lsf9#;gV zZaGU2<1xjK2hVFe(GctTrk{S(s03N zG%R&3R@_^D9*P^DKZk0blEcgXPkcnPQR=AML0gUtQ(#znK5->$=t*uEX6XJq>CS8HhUf+MNQjoML=dRX(vsU5#>!ENN_fQ%~72>(On{P`g1YKDYbRHaPt6>8_tZvZ)f z#Z(Nsb}fg&pUeP$bc@F4w`%B<>YdSl^jV}L@~ODCcPXuABnuArRsK4W>$q!q6A*q-8dSKgWohanT>wUg+UJJ|&C(dN(_DZw0?9 zovsbH#I@m;xKorrnoie;Hz;#fF3eiGYSM&dS}gGcG~njO1phcnLzFfHNDTpCjGD&T zMO>oWi8!z*^Lzkr*@;cMEriCT26?8Og=0r&aJ5iH3G~$c{tNP&L6L#)v>XJMCz8(i_ir zA$^Dd&!7&TW!H1ppg(U}fU@ug3a9C9TxbyT!%Kk5ka5n6ZS%W-DA*mQ==D{Bq zB;=S$lL{#WKglqGn48?$jHmRGjv+1`+UZWhCp~P+8t+-z=@4xb^1<0G7BZ5|iyVW(&_irYG9`!LRoq_r+yrePh^I}Ie zI6{B!Pkj)nPxXxrvE^EWiSo?mXb&%4IDYNcn*D>(U}(4@$NmieO#_`@JVJUhjwhSU z7gUkB@?(wr8PQOX_zrkz;bA{_-+;1sHeN!alrs7K`(w9i5Fm_pBTVd?hZp*TQI@Tj>6)D`tG z=k7b9s_YV#o z;5a&e_kqnhrv;T0j@y33dp#N)@uK)EMlAHX1P@L89ekAJdp(|iOfGF5 z?dd);qDPOw^@k4TuD>LxBEClQ%8@cd@RYx`I20++Qx40%M*jynwF&Mzil7>qc#!su z+K}d?{+)K9y}W<*_Vof$PWM3sH9o%c*8~fFNi8n)(A~t#nw6qTJz&(v!^gK|9Xq#v z_+YP)AZJ0P--e5jc&rRrUDQ%eR-1#Z0?)O@oiw(1)ZkZB@4=Uk!R;X)RHG7?11~>W zwtzlPkHU#N;>d98D~ckHxTy!Y#Rq!{`JK6STedCPpjkD4VsdI)TvCES+7fHd0dC$S zeU#U)a|PQsZ9r1;}pSp_z$$;k_m@4=b zVnP1Lb%S7B((4GEl25sP5HD|f-X$C!o3lm&{_6H`M;;WKt%M!Tp_wB-gW`5osJo0pD_j7-Gi-$pIWiV%ji=OVWpPx?jk?8Jeq$3|>% zpCyR%$?LM{j4wrJr-aUUiq6hrbjD68^hkm}Hw!NzS!sV^J1E=!1&Y7gf>O%7NdHjZ zA0drfxsB`>wk&*OvcT_h7?u(dxj0#p7ZGOwo@`9ye-K^1M}Ae7Ab>Je>9Kavxs-g!eC05X>Guhw+Ve6Q*kujAmD zJ6t2xg|;Sp)&=x(hzRiYjmW!rVO<{XOVL}PNxLK|DfwOV5{0B9t0n!#LLzD|7%tj> zmU<$)r`&%0%l%^IfpOg^n2w2B&;Q^~7?p($hx=_FQU)JaURgwJIi5_F#eP&4IjAgD zcvbtkrsqR=J>5h?9cPugL4zhO2?cb1FSp&Dq(F9+ukRMZ#9~T+; zF(Us|Qh9#-ZW3ZKbIPMX3-{kgnwz2?<>c@s5{J~b??~zr_4#g4^^X(#?_3|W*LK+G z)G?{T@$c4eJg(WW?yJ=0!uA{7l2Kki57ngN3SZXZ)X1=;w9w$xC2KO5EZ&5m*Wg%O zy~nP4C5H%eh+%DTTkG{zGM4Mvb7A3`QKv=(cB-NXQGLfIO*O zKAu%59%ROp`}=PF`3RSdIqWt1_l{H4Q2XjF+^$l`@hYj-tiN}A`+b87cWhX+a-rZd zJv@AXCM@!&1#!Y~J1!}E|M*>+1u#w>nzAr+e7zhir$vM(r6MaYU0uw|;wvK~(;<0ZO(H8p zX5o{YH!I*}MB;s3?tRuzGSfTIOmCrPx`da{xNR#j(y__o(Ln#a%3#Buk#1<4Q;oKH z!Me4}7ou$@GawV0`LBm%m>DuDH{XW3CEVP>PU7apD;5gnCzBAZO@IN_p7MrMh z4<6jR*KXhQ7k2NtaDMRaUTAN+O@glIn|H-RUFA?i^p{fQhGME*!Nv_c3&J+w6mq8t zO`j|GOr`JI3TCqOKuz@f+JAVROErHI27Wd{=L6DzIYtd^N)MCVfQL!aj68@nFF9cH zL(f!tYsA@X2QCSA#g3Z_&tN{rM0D@8^d>$bOY;&HK7|i zNL{cZodhj``eIEf5q)RaM!%uqVM8%RaHqiUu|+?a^u=9#eU(wLmc!ZiSu_PUh<79W z?VQZcEAo+xC+U2?0d7F3Mvr)344pYrOOZ_Q!?N6+Mlk_T%!PW2G}4G8^%djkoko#D zZ0PqzECT!x%H7ph{A_^P5E`jdX(d6i5E^kRy&d-4I8xBz{gJ}q#BV4W;4!()NzF+F&o5Ie@NIQy zvk+QafQj8NxCO1DZD-QxJ1wS0#FH}>;6VoA2CD|xOjk_L=#Yrbv;_5Ps3+wiWQetl zMBm^yEG&HJu#Mpb7`(ZMdv)Eui;W(t86LZMo4_Cc18V(<=cf_cKB-QuQ%P$JVsgU` zZCt}bjHpbAw0s#9Gl-$wvbA1 z54oij%~cmOOEJF-)5sSe;capZr7x69A4}wF`1Q3lhayO*2&(MK$Vco{@v294lIAnFlfhST!NsM{t3&;9|{ay%(whkE;>g{QT^_frz{fY8PQ8K{g%PamTVA$2z^ zR?eOnArLoZm=7Q8=e8+%7;3<+;QSZu7Li{JeC-IZT3HSq?Owz}ZGF))A|z zb&A;Z+3N%tsC*WXMa;D>c>4aS#i{;yww=;(N%+xmTG#PO;f@xhhSEPdwXc@cIiUpe zyzFNJxGC4op0i5336;q{3=Px~UqKx_Yz>iqg6oh_hpc+@3Zrs$NOkcQc5ZA*8QkHB zh5nXy7?L_rUH=Nlunw$3Kxb*9@e#0t2U8sDL$n%3R&3?Fu-bWIy4_gKpS0<1sCFGp^NiI3pp6}^HWqzcmYrHu zUtUxnqHs&{oBD)BOlKLMi>>6yru4bKmGpco%)s*dU;(CF!VG*)7JTrz?RC+Foh~NH zQ9mqFzXVq*{@7Jlz+Vn56}U^&RsHJy=PF`Dt8S!K8)DUl#^Tj+M*#j(FmR2yR`gt@ z=cQI*Zl$fN^ePEDEnI{cFI`%?LlQhqq@BPfeBpZ!j$SVI=MzN`4?r2%VxB%MhmD!{_=2cc@+<)NPQd^N;$nyu3W!b~7+-QH+g^}!ldyB#R@^U9HRH;epMlL6Yu3dDhMz&s5tU-r%^A6CR&B|sr-G^& zN4$UW{Kdz3vL!NZKY3AG`rRT!`$f2GoZUC>4;LW*BAKE1Zf?fhpDkuj!yhgDaFHY_ z4z53veNJ=qWSIAM;V=5_E6#+?Z>+&}Xl--S#9wIQa9fd)o-uLi#HkaeO_*4{Nk@mj z6r^cB)NcyiHP7i+x?B)cR*RFCC5ao7m(mQ<-g#ib`+smRI3F2$$a8b=`Bk73vB2$B zqywH75Z|dWX<|Vd-)aK&611cZ;2VEvtGqP-P|k)URaDt?lFng7dKy@S(T48f^$gJP zCq)r+0`n(sOU%|jeai6{TRv&g99LSFh6K#@)9@Gl112Qu1pZ|6r!8Cl(VR;hHF3mn z3%|Jm%XHc%O`f!T{+vtB-a0W)lfQKiP9L8&dh(>nU)=IdbMtmska-w0arWMKO5pFG z-oO9!nFHR=TK;5TuR%^)Rr12574*2J70GC$+-E`E96V;wS2_R@Q^G1dEt2;3T_dVu&OLuR475oAntT7u}DS2P`V&0Q;P|HGP zITeHI%`ll9zq)~aj%U0>7Fek92~Ijl*R#q)tJdzy*_JRO7mbfOw{K97OnVJ!)zOx; z5FC1vs=tzEJ&A=l3kj{7HWhR(CypP7w>Y7~^P~6_aUwiW~U3pNESOP8j-xM&NjYI4)GK*p6SNa~$o4HPpgy9kYiX`wbsv z`*E$RE5;iAp}V+3-E-6+q7?9)@XXosmT39N^;tttX@1S#2TBYiDWW7pCogi4EF8kCFysu|b=68_ZsxHH0>}9~88~sPwVeU~GhLS3g`b`=}>Q ztj~f?9s`$NAI;91>|MgnfwyZoTLs7ssF{W`rer;5KsOHTL+D_yfC6^pvjyKQ%fDq9?ea zm#Wm$PxKPt7OBT!vFRW)7F(+(rnFdJbaZL4zBqHH#p-ZiqHnGS8DcEM7`7K4PJ=4} z^w?%o@idsqi#R+^v$2nt%ShqGNS_1EP@{FU!LJOedD{j|pY1zvB3E$Py4ULu4OG2- z9~q!#$9trzpl^s|7&#sha9RH-4G`; zg#A+yfHM>@$LxLl2*<+C(rOqz^1>XmMzri|gqcj&d{*OxZ_L`d%(JjTPRHR~y(5x}jt44=idFi3Ks`yc_OQ>V{_u zusHYYhKF!;LzkPX3rK%aTvWsb{BD@=$KsaUd=%zr4NLLe?=mDrPF5{Yf zQ4TH{pTQvAPqgQnnoLF07?-kU4a2pF!?N3~)K6iTMj)Sy7oEWXnS+O>E z(~7uIzn}=;Xl>l4^mS`2*6Mqz`G+0>n+|MVwR+PEAvc8Od9%tCOn0@gBX>tG7Rc9QP43NLLXSV$J`}igV zwP*Dw{LOSxN6+5PAcKh~`34uD-7tsdn@dkuZ#yImzsd!AJEVAOh&x(yEy}VNPRm;3 z-w@3EY)-se1@#L|95**h!0#4Q`6_2m8M3FVhSctAN$Lpv?sOu&Yzrm__ATGPS&J=A zpTPOd-4=gX1149WU`Q*241j**J0X!AQXkvwgNHipPIuOM4RF^TIz`JL-@NxAy4`I1 zB(@OLau`iy>eo$(`fU@X^i(_rkBx7{Ks7ujYVuf#nGdJb@EczLrc@pI>FR^?;C<%N zRd)H+dpF_96*`x7QWI~)-iEm0>B7yB_r1Uy(Xqi3;|G%F_!UZCLRS-L3TXR?75*qt z!!{#LF%`oUCt+5Y8B-0K2|u(^H*@IIy43~8-wSpv%ibvX?cx#=BF4pPe1miM?b(vE zXHDkVF-wIV2e=KRhb-~asM_JFS(YqrIPD=9Ir0B%?MlFFy0-Az``nv3S0uR+2{)no zimI8I2@#^^YKj*_NDV=x5vtnPK~ux4qLimvUW%I4P;E^uZB_9+pQ>tkK3+{lNeOap zTyfsN*SR+XnfiV2>~F2T&mPxWd+l}h-uIk+r`z>p{PSwED*>mwC*0qvcfeaSeej28 zwkGRwK>pK3S#@khBf-_DcmdbbW_}YKF%C%i+LM-y;t6iT|a#980^(&VEdF7k!@l(eKRm>=KPuO zE{xDydCz@k&RmDHb+&!h?Afy%_nUjon*Gk)DEzV5!g&kk&v$&i_s30VB2WLA`rO{A z`7`Eay@@@KXWr7ioC`0B{}}Xgzv~9Q`$_0EP5&8h2Q}*$?`kwLD#ex6s^7}EUF)n* zE%>b8)ySWJ+Isc-sDTHqDdR?t#Aefr8&5BZx_$9-hL0m{e`_%%KkK@{ug0N&K(Cy?MBDQ(L0w#N-D|t3?RIQ_w1`@L zKTZ$L&-$Yv%S)+|KIBl|!HY_b^sv*q&(FGVWmRc5-sOB)c^+0Se2=W3upj^Hr!5^W zhwH@YO9#B>dF^guz3kQPj&;lO?9F>3Tm$;s^A31#&Yn7U?35QrVVGl`lRgXz%IP8P8Zzn{BY)_b!GNc!_LwB!k6EXRP zX~X(;Td^a-5t1<&|9`Q4&<_{V&qwNx^GC1jow9P+$5A1v2UdRi6<}`;9kUH`P&UClG(aJHLwSgx%TNRnxnU>*YH5=L1*G`>m0Cw%4z&;ns6r zzp8U>XX9J#>v}u!g}zk1x>Wo?G@J7VpPsVVJcSecf$2E4_icN~7Wc86=|!h*ZZQwt z3`sXn=d?NT?-F8)vxYVWe==9>G@84K3L-agx!CmXmjmx-qRb4IeMe5SSp;(Uu+*TE_LXT z4dZt1*sx(I76L=nUn3UAZA4ru;%v?w9O8OTy*<{Yw3jDM!EIN9`?ln}r7ESPnBc^o zUhn+TWq+Y+%MZZhelz|9SU+0y3cd|5)i>8)2tK7wxfrfHmf6P+c_C?N@guae3*U=> z?Tv*WM1>4rk-c^E9*50&9EUTCukkj#qWPOj9hYsx;@SMe-C63RPu0!09{%8S%cI|L zr}HP=wt@z(-G#qxJahs|k zzdTrt^d!JdNLyFS00|;-T9Ud(u}(BMRx3bS4?ws~N4Z$) z!LXS91Th=_bH-UqAa#`=l>&c5xe7pYA&=r)0r(Re(2fb=@H zH|1WcCqBgeKnjx$jR*22^yxEXlT)dl>`%4ibksMM95ngC4Q&SbX)gdal2v;R{x0~3 zC{Wu(k>Wdw62asr-lAYJfvjRVRTFPgpje9dETm^s1lkF&biU$sO+#JZqpoiB7rF_! z1sd1Fe?W}^&Ez?%LbuH{@e65y>f#G(NB01^Xgk?BBfG&arJ((p)J3FX%x|SZVlcHA zqfmYp(*6OMLNN?^B*lGtOjL*OfWIDf{2lNiMXI(7;R+D}#8P9PW`mp?K`*`ps4@H$ z?%#+0KA=_%pdEfKMGN~6C>nmWmI#_=7}wo#wPa`HQTZNFTjfLcH8g{wtotEHGrpF* z47;(Pq#Og9?qkesq8Ql`buB_&Ptvmr zF_anr{KZh?clfdJ^F=xdga-iX;r=}QI)L7Qmbfnf*O4lY1VRA-bxE?|{yg9UUBulb zx`tY&im9Y=K0n$e?~@i6-*W(kj?Q>~95oo9oS8;(D2K~1$Qzy)>I;U1Yta+M;sw$I zDTHcJZK_LQq;-iM5KZ-a_30T+o%;9b6-|lm8YKCUjY6p=Jx297&Ij%LLO<*j4lS-j z_1&=+@}nTsRh^>faeC4nYbAfGO4TTWqM=U>=&9u7@tGosaX8~>#&sDtX51{p;sEp*1B871pbX-o|(b zXMC9Pv9!q(GQ>&7XBeMne1&li<2w^GQqsgdg(WfeVjRFYm~r@|$?21%gK-_k^%*y2 z+>&uS?q?|cpYT=RsS@R34ZY@z{=l^1Plp6+U`1Hzm_Y3cOU7Q6!2X=4d~D@BW#cN) zq`I(Et*8_Ap#C(NMo=nc&?_{9=F(!8r4UU`+C-vxPiby{JVt~XTdDM_J7$*KpW*hi z-2Qa8|GK-xt2EyoT0-l2ED73X`l6?qSB$_2eFb3w3t>t}idXO?He(56PDxCPOaXdC zCYK6CXcR__fEBF)oPzNx#2DiT;DLz2Xy^hlfoNiG*MOfprj^(g)ctp&_syvgL+HhFQ6$RKuF*~p#j^31-Oc^0tcaX zLB~OrAFPdlTw5U4!J#!AlC%fBD=HO~Mx83vkDjG(=^)ApTB$JCA*cyz7Id9*l>8C; zoiL~7bY*n~I76)P7D4Xx0??z20IA!WATW@*!In_<&hn_<&N2aimjlul`kGZ{}~{5sBA@|T;rtM4%CV#A7dnd(at$-2Jdofe`iex6Bu0oaA`K&Wns{Bz5Oc%= zu|zBvtHgS-MSL#yh;PI}aa>#!Il?KW43MK_x|}Anfe@MOu6;HcO}_!V+!iZ0T<4Z5d!0Y#DADWf^bDuuQeQYEf2gG<2vm z{FIRonE;ELh7&o|eJ}+Y*U1K`0tf;`0ipr50PO)C0389H0I`71fG&VIKvzIKAOTQX zi)B$#GF~q%t0*$*sytR46@bzQ=uLMB{1u2KH@9Y5QLfTLVUR*Dq>u|KDRY_mGn9RkzGF6-JwRXjAo}nNl%kJ^DXVSNWF9%bCL*l#La)573tnpdqfZ z^CI;>uq6*LItC;MCBi~@Z&X{dihgHuv@{D~(j!|IzVO%p@ z#@EJq=t2b-%H(^p7?+`omA*XXj5~&UVpez=dWBis89X^n-_uS-rNRGYm?erEjFlTr1%al^RgxmUirGi6nhX5)f!q%_zK#3x&Z)0vNTo;65`Gj5EeQlyw>hfpd&QZoT`- zQw(uANOi&H6SVtB;Cr65%J|AIpl5Cwd6miS$y2emBWIY(t+@7Rcyal8YAW*GoLy7> zi1AwhmjmmS&z7rFdQg#dD6}PiqVJ06163GxY~AiX4>dtcEnrdb@!=| zNpb|9Gipaj&4ssNt+b7HxZPJ&((T7eZ$BM|J67mU(wRbc9y@iW%fYJ3ba$|-QtqDV z)Wp4n^TI4T04`XB7dl5#yNIjfcJ+nFH5TkpQ6^}{QdD8_BI88Hvlx$K{21ewjAtvX z1#*~I&*EtgKh9WLB!QJLu#^hZTO8AZ!yhsJoH2GXk!mQ6b*q|psa4@bgnokrCgLs} zdt9NouLFk}8#RK>YfoJ3z&_E43cgMd6+%Y4fO?~w(b}O32;83qZfLu zH+Db#=o!!y0x1kb+2N3*l}5pZao<^4PN7V(onD92xCeb`I=zXol3XApHy_lf-VDVK z%RG(oA(@?w8>@dh^ z4q8(Z5!jWRkFb(R7)vAwe6K-Raa$GpCp(b36E2i{JB;}cVE(Hz|2F1dfd2#Nn}gsy zggLh`=YGt&g*mtKUbzraCq~4OH}tv{_ODW*-PossY?Mw*mKjz#ke1p5ibsr+kYw&*9sURWD>Y*P diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Hairline.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Hairline.otf deleted file mode 100644 index 1ee11cedec1e1181e2f6675d0b2aa341aa0022fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44156 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
TSM2?ee z@`~VSmr^RDa_T@8R7w6p2#1iaI5%7Rpc%@Wj>Hf1$*2nR$Z2uvh&kod38nCBylQAc zY^IDBqDU#UFqL6kgvv2iqYjYKqEvx#F@#RZ1*}y;lr|LcS`VM`(>G3)zmtPg+B z)5c5Jrep(NDVdBxgQ2NZRy;n%@-U|(Er2a8ge@$BEh~yG;*e!nGOveP%7LlvrNnn! zo{vQxU@OlnNbjx z(%N!wk%LyDJ4@oFjF7!#ZjMYc-u zZYe$>#mA)hj1*szaEp=D^7q9YGaT#hi!Ji!-7%Me|EHC+53RZikUZ;0X@b~bX`~1%NopYY&dtRSsuq;_yu9Z8%ME1q}z=J6> z9hN#}lhUcjIjfQw1)bXFavx!)f3J?JW1Rl&>Xho#WqP`<)c5K6dZDh@4SK15mX*9x zzpP)^>-0vwSrZ}FpXf&2qz~(3x=nZJF0am8>@|4HycOOWZ=<)(+u=2OOo~CNVa;hYz09aZB%Nn_biI{Z zQ?zVgDF+n7pb!RyFerpUAq)y(Pzck;k7^QJjyxTn0ndbI!4>dqxDu{{tKnK3MuSc? zI6r6&ME5K7(5$lQ}#izTK2g`eXdyvHbW`28ESE6A_LNvIu`WD~Ssk&Eo#wCVIDRiAv(~8FPAw+YjQ=iu*1iMpjgtkFl&) z*}q&Hz0sL*eXaN$_TK@Yo0Sh(nZiEJA~wa_*1xVjcYW!={o9Vn+=)l*a{qRD_q>l} zuTN@7+6FF2+Kb4DUJa%bIx zPqRnui_n+qT59H=DmPWRt42xgtWlD?t52PHKR$JFh6(lhBp2*!C|M`t$E4xI<@Qm& z9@j^?dP0OI>nKgtj%ersXTugr^?H|9xOA0E=ee}Nr4wCBq!62}lb>=aktW)?GfbLeWKvUFfYON|!Z>x>OOLwWg)ZDL{)cxu> zRHrUL^SDKHtND0@>1u%8}!)PO(q1ck<_TPMV>Jd(} z5SmRT$|jnPR&&s%$Z0bdUDl%GdT6P7OYH;?(PK4w97V4dy!u_zrVi2fIQpERC+QOD zj|c<9Oa#%xA4-KJ`jAClHr`PZy^P_#m|nApu1q7oR}JOi-!DX~Rq7?8dSZRCv%XYq zS0Af;h=uG{6(G=rjt7{DHR=%2g9Y?4#aT8C%hHG#NKc+aK1gf%^eFh}VdW&!Vj?;@ zU_2E({IQrrds(zr!z!qSg6J_9zpaiaMGA9lAvi5kk5czB#w$rZ3FWv^OL916JB|5k z6%=q|7X+hMkp;PQklR2MQ^qlyNXR?rxJhm1#<&H_R9n?HV5SA_qq?k zI{?1Bsr3bvip^g!qrS#+t-gUqIs22{dK|)Nw9w8^sueVUfrc_menb8ppYjf(Fn`kT zUl5THqNAGj#KTXcb-^nIyz-G{WKx)o6Oje4B=DMsT+aBUfKv^!V3gu8%61rybQpOK zqmaWW=+Fs*&PsZaIh_ke>*!Mu$su~S0a*~qb%`!<0=V1RK^!^UZhdIkloaM$@9&j=39G$KCOwUHzq+3B_T+Dg{3SuV z)#JI$HPy(1kmsx?lJY+{ CfH~X% diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Light.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/Montserrat-Light.otf deleted file mode 100644 index a01805ff0dac184b5c283efdffe5bb5d58a7e911..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44792 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%0D(uKH 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 diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SIL Open Font License.txt b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SIL Open Font License.txt deleted file mode 100644 index 295975a5d..000000000 --- a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SIL Open Font License.txt +++ /dev/null @@ -1,43 +0,0 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. - -The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the copyright statement(s). - -"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. - -"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. - -5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Black.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Black.otf deleted file mode 100644 index 492661cba400bd23f6f48b0e9d9ba6966700e00f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122372 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.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 diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-BlackIt.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-BlackIt.otf deleted file mode 100644 index 2fbb1d1a1e7687f4f24543385a90d7254542e171..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95056 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 diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Bold.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Bold.otf deleted file mode 100644 index 597072f5823bc755b9b3a38eb48d33006ef849b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129212 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�-GOtS;pwi6dSKLOX|{+oR#62V#o)g~ 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 diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-BoldIt.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-BoldIt.otf deleted file mode 100644 index 56bdfaccd2c1687b1945a0db6e4a05a0544efa1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100072 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
    !lNx6a@Z3wS^%I?!;DXtB@+c{N|zXg?!ey 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 UzLdqXZSu+&kK4JP51;dY0DM^D>i_@% diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-It.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-It.otf deleted file mode 100644 index 7ab613d4dc4c79514a768f346937729851845eba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98820 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 z 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

    - - -

    - - -

    - - -

    - - -

    - - - - - diff --git a/cmd/mist/assets/wallet.png b/cmd/mist/assets/wallet.png deleted file mode 100644 index 92c401e52c7a6cd0715d15a3db781754c2502b21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1114 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}oCO|{#S9GG z!XV7ZFl&wkP(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@WME*L<>}%W62Wu3QbEqBqxd}F1es25UtI9 zI^n5*+PnVO)|SXD=ypj*S=6s(Vd%eHaVnTTO#F;9qqCZXbI5%U#zZ1_54{qgVy3wQXJk5i)8|WRa@AaYVr%K{XzP*3^(Zhjw3>;{US?Vfa3$vJ79ch@TUZfbXKB|~Jhy;}JG zYu*8uA9JkeyQwAjza`G=Rch)VPaBQKP0KiPJ5;tZExgzLWkcqy>xUnH=@&XO7Q|$`f=@_*dwg}r>H7hw^|)NAbi=q qEZ$;S!;C6!@qLqjUWtEx>xcMkfi0_;l5d>>Wq40lKbLh*2~7ZcbjkYw diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go deleted file mode 100644 index 7512421a1..000000000 --- a/cmd/mist/bindings.go +++ /dev/null @@ -1,92 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import ( - "encoding/json" - "io/ioutil" - "os" - "strconv" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" -) - -type plugin struct { - Name string `json:"name"` - Path string `json:"path"` -} - -func (gui *Gui) Transact(from, recipient, value, gas, gasPrice, d string) (string, error) { - d = common.Bytes2Hex(utils.FormatTransactionData(d)) - - return gui.xeth.Transact(from, recipient, "", value, gas, gasPrice, d) -} - -func (self *Gui) AddPlugin(pluginPath string) { - self.plugins[pluginPath] = plugin{Name: pluginPath, Path: pluginPath} - - json, _ := json.MarshalIndent(self.plugins, "", " ") - ioutil.WriteFile(self.eth.DataDir+"/plugins.json", json, os.ModePerm) -} - -func (self *Gui) RemovePlugin(pluginPath string) { - delete(self.plugins, pluginPath) - - json, _ := json.MarshalIndent(self.plugins, "", " ") - ioutil.WriteFile(self.eth.DataDir+"/plugins.json", json, os.ModePerm) -} - -func (self *Gui) DumpState(hash, path string) { - var stateDump []byte - - if len(hash) == 0 { - stateDump = self.eth.ChainManager().State().Dump() - } else { - var block *types.Block - if hash[0] == '#' { - i, _ := strconv.Atoi(hash[1:]) - block = self.eth.ChainManager().GetBlockByNumber(uint64(i)) - } else { - block = self.eth.ChainManager().GetBlock(common.HexToHash(hash)) - } - - if block == nil { - guilogger.Infof("block err: not found %s\n", hash) - return - } - - stateDump = state.New(block.Root(), self.eth.StateDb()).Dump() - } - - file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm) - if err != nil { - guilogger.Infoln("dump err: ", err) - return - } - defer file.Close() - - guilogger.Infof("dumped state (%s) to %s\n", hash, path) - - file.Write(stateDump) -} diff --git a/cmd/mist/errors.go b/cmd/mist/errors.go deleted file mode 100644 index 255ed07c1..000000000 --- a/cmd/mist/errors.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import ( - "fmt" - "os" - - "github.com/obscuren/qml" -) - -func ErrorWindow(err error) { - engine := qml.NewEngine() - component, e := engine.LoadString("local", qmlErr) - if e != nil { - fmt.Println("err:", err) - os.Exit(1) - } - - win := component.CreateWindow(nil) - win.Root().ObjectByName("label").Set("text", err.Error()) - win.Show() - win.Wait() -} - -const qmlErr = ` -import QtQuick 2.0; import QtQuick.Controls 1.0; -ApplicationWindow { - width: 600; height: 150; - flags: Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint - title: "Error" - Text { - x: parent.width / 2 - this.width / 2; - y: parent.height / 2 - this.height / 2; - objectName: "label"; - } -} -` diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go deleted file mode 100644 index f443bacbc..000000000 --- a/cmd/mist/gui.go +++ /dev/null @@ -1,462 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import "C" - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "math/big" - "path/filepath" - "runtime" - "sort" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/ui/qt/qwhisper" - "github.com/ethereum/go-ethereum/xeth" - "github.com/obscuren/qml" -) - -var guilogger = logger.NewLogger("GUI") - -type ServEv byte - -const ( - setup ServEv = iota - update -) - -type Gui struct { - // The main application window - win *qml.Window - // QML Engine - engine *qml.Engine - component *qml.Common - // The ethereum interface - eth *eth.Ethereum - serviceEvents chan ServEv - - // The public Ethereum library - uiLib *UiLib - whisper *qwhisper.Whisper - - txDb *ethdb.LDBDatabase - - open bool - - xeth *xeth.XEth - - Session string - - plugins map[string]plugin -} - -// Create GUI, but doesn't start it -func NewWindow(ethereum *eth.Ethereum) *Gui { - db, err := ethdb.NewLDBDatabase(filepath.Join(ethereum.DataDir, "tx_database")) - if err != nil { - panic(err) - } - - xeth := xeth.New(ethereum, nil) - gui := &Gui{eth: ethereum, - txDb: db, - xeth: xeth, - open: false, - plugins: make(map[string]plugin), - serviceEvents: make(chan ServEv, 1), - } - data, _ := ioutil.ReadFile(filepath.Join(ethereum.DataDir, "plugins.json")) - json.Unmarshal(data, &gui.plugins) - - return gui -} - -func (gui *Gui) Start(assetPath, libPath string) { - defer gui.txDb.Close() - - guilogger.Infoln("Starting GUI") - - go gui.service() - - // Register ethereum functions - qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ - Init: func(p *xeth.Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, - }, { - Init: func(p *xeth.Transaction, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, - }, { - Init: func(p *xeth.KeyVal, obj qml.Object) { p.Key = ""; p.Value = "" }, - }}) - // Create a new QML engine - gui.engine = qml.NewEngine() - context := gui.engine.Context() - gui.uiLib = NewUiLib(gui.engine, gui.eth, assetPath, libPath) - gui.whisper = qwhisper.New(gui.eth.Whisper()) - - // Expose the eth library and the ui library to QML - context.SetVar("gui", gui) - context.SetVar("eth", gui.uiLib) - context.SetVar("shh", gui.whisper) - //clipboard.SetQMLClipboard(context) - - win, err := gui.showWallet(context) - if err != nil { - guilogger.Errorln("asset not found: you can set an alternative asset path on the command line using option 'asset_path'", err) - - panic(err) - } - - gui.open = true - win.Show() - - win.Wait() - gui.open = false -} - -func (gui *Gui) Stop() { - if gui.open { - gui.open = false - gui.win.Hide() - } - - guilogger.Infoln("Stopped") -} - -func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) { - component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/main.qml")) - if err != nil { - return nil, err - } - - gui.createWindow(component) - - return gui.win, nil -} - -func (gui *Gui) GenerateKey() { - _, err := gui.eth.AccountManager().NewAccount("hurr") - if err != nil { - // TODO: UI feedback? - } -} - -func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) { - context.SetVar("lib", gui) - component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml")) - if err != nil { - return nil, err - } - return gui.createWindow(component), nil -} - -func (gui *Gui) createWindow(comp qml.Object) *qml.Window { - gui.win = comp.CreateWindow(nil) - gui.uiLib.win = gui.win - - return gui.win -} - -func (gui *Gui) setInitialChain(ancientBlocks bool) { - sBlk := gui.eth.ChainManager().LastBlockHash() - blk := gui.eth.ChainManager().GetBlock(sBlk) - for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) { - sBlk = blk.ParentHash() - gui.processBlock(blk, true) - } -} - -func (gui *Gui) loadAddressBook() { - /* - view := gui.getObjectByName("infoView") - nameReg := gui.xeth.World().Config().Get("NameReg") - if nameReg != nil { - it := nameReg.Trie().Iterator() - for it.Next() { - if it.Key[0] != 0 { - view.Call("addAddress", struct{ Name, Address string }{string(it.Key), common.Bytes2Hex(it.Value)}) - } - - } - } - */ -} - -func (self *Gui) loadMergedMiningOptions() { - /* - view := self.getObjectByName("mergedMiningModel") - - mergeMining := self.xeth.World().Config().Get("MergeMining") - if mergeMining != nil { - i := 0 - it := mergeMining.Trie().Iterator() - for it.Next() { - view.Call("addMergedMiningOption", struct { - Checked bool - Name, Address string - Id, ItemId int - }{false, string(it.Key), common.Bytes2Hex(it.Value), 0, i}) - - i++ - - } - } - */ -} - -func (gui *Gui) insertTransaction(window string, tx *types.Transaction) { - var inout string - from, _ := tx.From() - if gui.eth.AccountManager().HasAccount(from) { - inout = "send" - } else { - inout = "recv" - } - - ptx := xeth.NewTx(tx) - ptx.Sender = from.Hex() - if to := tx.To(); to != nil { - ptx.Address = to.Hex() - } - - if window == "post" { - //gui.getObjectByName("transactionView").Call("addTx", ptx, inout) - } else { - gui.getObjectByName("pendingTxView").Call("addTx", ptx, inout) - } -} - -func (gui *Gui) readPreviousTransactions() { - it := gui.txDb.NewIterator() - for it.Next() { - tx := types.NewTransactionFromBytes(it.Value()) - - gui.insertTransaction("post", tx) - - } - it.Release() -} - -func (gui *Gui) processBlock(block *types.Block, initial bool) { - name := block.Coinbase().Hex() - b := xeth.NewBlock(block) - b.Name = name - - gui.getObjectByName("chainView").Call("addBlock", b, initial) -} - -func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) { - var str string - if unconfirmedFunds != nil { - pos := "+" - if unconfirmedFunds.Cmp(big.NewInt(0)) < 0 { - pos = "-" - } - val := common.CurrencyToString(new(big.Int).Abs(common.BigCopy(unconfirmedFunds))) - str = fmt.Sprintf("%v (%s %v)", common.CurrencyToString(amount), pos, val) - } else { - str = fmt.Sprintf("%v", common.CurrencyToString(amount)) - } - - gui.win.Root().Call("setWalletValue", str) -} - -func (self *Gui) getObjectByName(objectName string) qml.Object { - return self.win.Root().ObjectByName(objectName) -} - -func (gui *Gui) SendCommand(cmd ServEv) { - gui.serviceEvents <- cmd -} - -func (gui *Gui) service() { - for ev := range gui.serviceEvents { - switch ev { - case setup: - go gui.setup() - case update: - go gui.update() - } - } -} - -func (gui *Gui) setup() { - for gui.win == nil { - time.Sleep(time.Millisecond * 200) - } - - for _, plugin := range gui.plugins { - guilogger.Infoln("Loading plugin ", plugin.Name) - gui.win.Root().Call("addPlugin", plugin.Path, "") - } - - go func() { - go gui.setInitialChain(false) - gui.loadAddressBook() - gui.loadMergedMiningOptions() - gui.setPeerInfo() - }() - - gui.whisper.SetView(gui.getObjectByName("whisperView")) - - gui.SendCommand(update) -} - -// Simple go routine function that updates the list of peers in the GUI -func (gui *Gui) update() { - peerUpdateTicker := time.NewTicker(5 * time.Second) - generalUpdateTicker := time.NewTicker(500 * time.Millisecond) - statsUpdateTicker := time.NewTicker(5 * time.Second) - - lastBlockLabel := gui.getObjectByName("lastBlockLabel") - //miningLabel := gui.getObjectByName("miningLabel") - - events := gui.eth.EventMux().Subscribe( - core.ChainEvent{}, - core.TxPreEvent{}, - core.TxPostEvent{}, - ) - - defer events.Unsubscribe() - for { - select { - case ev, isopen := <-events.Chan(): - if !isopen { - return - } - switch ev := ev.(type) { - case core.ChainEvent: - gui.processBlock(ev.Block, false) - case core.TxPreEvent: - gui.insertTransaction("pre", ev.Tx) - - case core.TxPostEvent: - gui.getObjectByName("pendingTxView").Call("removeTx", xeth.NewTx(ev.Tx)) - } - - case <-peerUpdateTicker.C: - gui.setPeerInfo() - - case <-generalUpdateTicker.C: - statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number().String() - lastBlockLabel.Set("text", statusText) - //miningLabel.Set("text", strconv.FormatInt(gui.uiLib.Miner().HashRate(), 10)) - case <-statsUpdateTicker.C: - gui.setStatsPane() - } - } -} - -func (gui *Gui) setStatsPane() { - var memStats runtime.MemStats - runtime.ReadMemStats(&memStats) - - statsPane := gui.getObjectByName("statsPane") - statsPane.Set("text", fmt.Sprintf(`###### Mist %s (%s) ####### - -eth %d (p2p = %d) - -CPU: # %d -Goroutines: # %d -CGoCalls: # %d - -Alloc: %d -Heap Alloc: %d - -CGNext: %x -NumGC: %d -`, Version, runtime.Version(), - eth.ProtocolVersion, 2, - runtime.NumCPU, runtime.NumGoroutine(), runtime.NumCgoCall(), - memStats.Alloc, memStats.HeapAlloc, - memStats.NextGC, memStats.NumGC, - )) -} - -type qmlpeer struct{ Addr, NodeID, Name, Caps string } - -type peersByID []*qmlpeer - -func (s peersByID) Len() int { return len(s) } -func (s peersByID) Less(i, j int) bool { return s[i].NodeID < s[j].NodeID } -func (s peersByID) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func (gui *Gui) setPeerInfo() { - peers := gui.eth.Peers() - qpeers := make(peersByID, len(peers)) - for i, p := range peers { - qpeers[i] = &qmlpeer{ - NodeID: p.ID().String(), - Addr: p.RemoteAddr().String(), - Name: p.Name(), - Caps: fmt.Sprint(p.Caps()), - } - } - // we need to sort the peers because they jump around randomly - // otherwise. order returned by eth.Peers is random because they - // are taken from a map. - sort.Sort(qpeers) - - gui.win.Root().Call("setPeerCounters", fmt.Sprintf("%d / %d", len(peers), gui.eth.MaxPeers())) - gui.win.Root().Call("clearPeers") - for _, p := range qpeers { - gui.win.Root().Call("addPeer", p) - } -} - -/* -func LoadExtension(path string) (uintptr, error) { - lib, err := ffi.NewLibrary(path) - if err != nil { - return 0, err - } - - so, err := lib.Fct("sharedObject", ffi.Pointer, nil) - if err != nil { - return 0, err - } - - ptr := so() - - err = lib.Close() - if err != nil { - return 0, err - } - - return ptr.Interface().(uintptr), nil -} -*/ -/* - vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib") - fmt.Printf("Fetched vec with addr: %#x\n", vec) - if errr != nil { - fmt.Println(errr) - } else { - context.SetVar("vec", (unsafe.Pointer)(vec)) - } -*/ diff --git a/cmd/mist/html_container.go b/cmd/mist/html_container.go deleted file mode 100644 index c9b1f1cd6..000000000 --- a/cmd/mist/html_container.go +++ /dev/null @@ -1,152 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import ( - "errors" - "fmt" - "io/ioutil" - "net/url" - "os" - "path/filepath" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/xeth" - "github.com/howeyc/fsnotify" - "github.com/obscuren/qml" -) - -type HtmlApplication struct { - win *qml.Window - webView qml.Object - engine *qml.Engine - lib *UiLib - path string - watcher *fsnotify.Watcher -} - -func NewHtmlApplication(path string, lib *UiLib) *HtmlApplication { - engine := qml.NewEngine() - - return &HtmlApplication{engine: engine, lib: lib, path: path} - -} - -func (app *HtmlApplication) Create() error { - component, err := app.engine.LoadFile(app.lib.AssetPath("qml/webapp.qml")) - if err != nil { - return err - } - - if filepath.Ext(app.path) == "eth" { - return errors.New("Ethereum package not yet supported") - - // TODO - //common.OpenPackage(app.path) - } - - win := component.CreateWindow(nil) - win.Set("url", app.path) - webView := win.ObjectByName("webView") - - app.win = win - app.webView = webView - - return nil -} - -func (app *HtmlApplication) RootFolder() string { - folder, err := url.Parse(app.path) - if err != nil { - return "" - } - return filepath.Dir(common.WindonizePath(folder.RequestURI())) -} -func (app *HtmlApplication) RecursiveFolders() []os.FileInfo { - files, _ := ioutil.ReadDir(app.RootFolder()) - var folders []os.FileInfo - for _, file := range files { - if file.IsDir() { - folders = append(folders, file) - } - } - return folders -} - -func (app *HtmlApplication) NewWatcher(quitChan chan bool) { - var err error - - app.watcher, err = fsnotify.NewWatcher() - if err != nil { - guilogger.Infoln("Could not create new auto-reload watcher:", err) - return - } - err = app.watcher.Watch(app.RootFolder()) - if err != nil { - guilogger.Infoln("Could not start auto-reload watcher:", err) - return - } - for _, folder := range app.RecursiveFolders() { - fullPath := app.RootFolder() + "/" + folder.Name() - app.watcher.Watch(fullPath) - } - - go func() { - out: - for { - select { - case <-quitChan: - app.watcher.Close() - break out - case <-app.watcher.Event: - //guilogger.Debugln("Got event:", ev) - app.webView.Call("reload") - case err := <-app.watcher.Error: - // TODO: Do something here - guilogger.Infoln("Watcher error:", err) - } - } - }() - -} - -func (app *HtmlApplication) Engine() *qml.Engine { - return app.engine -} - -func (app *HtmlApplication) Window() *qml.Window { - return app.win -} - -func (app *HtmlApplication) NewBlock(block *types.Block) { - b := &xeth.Block{Number: int(block.NumberU64()), Hash: block.Hash().Hex()} - app.webView.Call("onNewBlockCb", b) -} - -func (app *HtmlApplication) Destroy() { - app.engine.Destroy() -} - -func (app *HtmlApplication) Post(data string, seed int) { - fmt.Println("about to call 'post'") - app.webView.Call("post", seed, data) -} diff --git a/cmd/mist/main.go b/cmd/mist/main.go deleted file mode 100644 index e8ae9b5e1..000000000 --- a/cmd/mist/main.go +++ /dev/null @@ -1,142 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import ( - "fmt" - "os" - "runtime" - "time" - - "github.com/codegangsta/cli" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/ui/qt/webengine" - "github.com/obscuren/qml" -) - -const ( - ClientIdentifier = "Mist" - Version = "0.9.21" -) - -var ( - gitCommit string // set via linker flag - nodeNameVersion string - - app = utils.NewApp(Version, "the ether browser") - assetPathFlag = cli.StringFlag{ - Name: "asset_path", - Usage: "absolute path to GUI assets directory", - Value: common.DefaultAssetPath(), - } - rpcCorsFlag = utils.RPCCORSDomainFlag -) - -func init() { - // Mist-specific default - if len(rpcCorsFlag.Value) == 0 { - rpcCorsFlag.Value = "http://localhost" - } - if gitCommit == "" { - nodeNameVersion = Version - } else { - nodeNameVersion = Version + "-" + gitCommit[:8] - } - - app.Action = run - app.Flags = []cli.Flag{ - assetPathFlag, - rpcCorsFlag, - - utils.BootnodesFlag, - utils.DataDirFlag, - utils.ListenPortFlag, - utils.LogFileFlag, - utils.VerbosityFlag, - utils.MaxPeersFlag, - utils.MaxPendingPeersFlag, - utils.MinerThreadsFlag, - utils.NATFlag, - utils.NodeKeyFileFlag, - utils.RPCListenAddrFlag, - utils.RPCPortFlag, - utils.JSpathFlag, - utils.ProtocolVersionFlag, - utils.BlockchainVersionFlag, - utils.NetworkIdFlag, - } - app.Before = func(ctx *cli.Context) error { - utils.SetupLogger(ctx) - return nil - } -} - -func main() { - runtime.GOMAXPROCS(runtime.NumCPU()) - - // This is a bit of a cheat, but ey! - os.Setenv("QTWEBKIT_INSPECTOR_SERVER", "127.0.0.1:99999") - - var interrupted = false - utils.RegisterInterrupt(func(os.Signal) { - interrupted = true - }) - utils.HandleInterrupt() - - if err := app.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, "Error: ", err) - } - - // we need to run the interrupt callbacks in case gui is closed - // this skips if we got here by actual interrupt stopping the GUI - if !interrupted { - utils.RunInterruptCallbacks(os.Interrupt) - } - logger.Flush() -} - -func run(ctx *cli.Context) { - tstart := time.Now() - - // TODO: show qml popup instead of exiting if initialization fails. - cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx) - cfg.Shh = true - ethereum, err := eth.New(cfg) - if err != nil { - utils.Fatalf("%v", err) - } - utils.StartRPC(ethereum, ctx) - go utils.StartEthereum(ethereum) - fmt.Println("initializing eth stack took", time.Since(tstart)) - - // Open the window - qml.Run(func() error { - webengine.Initialize() - gui := NewWindow(ethereum) - utils.RegisterInterrupt(func(os.Signal) { gui.Stop() }) - // gui blocks the main thread - gui.Start(ctx.GlobalString(assetPathFlag.Name), ctx.GlobalString(utils.JSpathFlag.Name)) - return nil - }) -} diff --git a/cmd/mist/qml_container.go b/cmd/mist/qml_container.go deleted file mode 100644 index f2cabb474..000000000 --- a/cmd/mist/qml_container.go +++ /dev/null @@ -1,82 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ - -package main - -import ( - "runtime" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/xeth" - "github.com/obscuren/qml" -) - -type QmlApplication struct { - win *qml.Window - engine *qml.Engine - lib *UiLib - path string -} - -func NewQmlApplication(path string, lib *UiLib) *QmlApplication { - engine := qml.NewEngine() - return &QmlApplication{engine: engine, path: path, lib: lib} -} - -func (app *QmlApplication) Create() error { - path := string(app.path) - - // For some reason for windows we get /c:/path/to/something, windows doesn't like the first slash but is fine with the others so we are removing it - if app.path[0] == '/' && runtime.GOOS == "windows" { - path = app.path[1:] - } - - component, err := app.engine.LoadFile(path) - if err != nil { - guilogger.Warnln(err) - } - app.win = component.CreateWindow(nil) - - return nil -} - -func (app *QmlApplication) Destroy() { - app.engine.Destroy() -} - -func (app *QmlApplication) NewWatcher(quitChan chan bool) { -} - -// Events -func (app *QmlApplication) NewBlock(block *types.Block) { - pblock := &xeth.Block{Number: int(block.NumberU64()), Hash: block.Hash().Hex()} - app.win.Call("onNewBlockCb", pblock) -} - -// Getters -func (app *QmlApplication) Engine() *qml.Engine { - return app.engine -} -func (app *QmlApplication) Window() *qml.Window { - return app.win -} - -func (app *QmlApplication) Post(data string, s int) {} diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go deleted file mode 100644 index 0618c5e92..000000000 --- a/cmd/mist/ui_lib.go +++ /dev/null @@ -1,281 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import ( - "io/ioutil" - "path/filepath" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/event/filter" - "github.com/ethereum/go-ethereum/xeth" - "github.com/obscuren/qml" -) - -type memAddr struct { - Num string - Value string -} - -// UI Library that has some basic functionality exposed -type UiLib struct { - *xeth.XEth - engine *qml.Engine - eth *eth.Ethereum - connected bool - assetPath string - // The main application window - win *qml.Window - - filterCallbacks map[int][]int - filterManager *filter.FilterManager -} - -func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath, libPath string) *UiLib { - x := xeth.New(eth, nil) - lib := &UiLib{ - XEth: x, - engine: engine, - eth: eth, - assetPath: assetPath, - filterCallbacks: make(map[int][]int), - } - lib.filterManager = filter.NewFilterManager(eth.EventMux()) - go lib.filterManager.Start() - - return lib -} - -func (self *UiLib) Notef(args []interface{}) { - guilogger.Infoln(args...) -} - -func (self *UiLib) ImportTx(rlpTx string) { - tx := types.NewTransactionFromBytes(common.Hex2Bytes(rlpTx)) - err := self.eth.TxPool().Add(tx) - if err != nil { - guilogger.Infoln("import tx failed ", err) - } -} - -func (ui *UiLib) Muted(content string) { - component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml")) - if err != nil { - guilogger.Debugln(err) - - return - } - win := component.CreateWindow(nil) - go func() { - path := "file://" + ui.AssetPath("muted/index.html") - win.Set("url", path) - - win.Show() - win.Wait() - }() -} - -func (ui *UiLib) Connect(button qml.Object) { - if !ui.connected { - ui.eth.Start() - ui.connected = true - button.Set("enabled", false) - } -} - -func (ui *UiLib) ConnectToPeer(nodeURL string) { - if err := ui.eth.AddPeer(nodeURL); err != nil { - guilogger.Infoln("AddPeer error: " + err.Error()) - } -} - -func (ui *UiLib) AssetPath(p string) string { - return filepath.Join(ui.assetPath, p) -} - -func (self *UiLib) Transact(params map[string]interface{}) (string, error) { - object := mapToTxParams(params) - - return self.XEth.Transact( - object["from"], - object["to"], - "", - object["value"], - object["gas"], - object["gasPrice"], - object["data"], - ) -} - -func (self *UiLib) Call(params map[string]interface{}) (string, string, error) { - object := mapToTxParams(params) - - return self.XEth.Call( - object["from"], - object["to"], - object["value"], - object["gas"], - object["gasPrice"], - object["data"], - ) -} - -func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int { - return 0 - /* - return self.miner.AddLocalTx(&miner.LocalTx{ - To: common.Hex2Bytes(to), - Data: common.Hex2Bytes(data), - Gas: gas, - GasPrice: gasPrice, - Value: value, - }) - 1 - */ -} - -func (self *UiLib) RemoveLocalTransaction(id int) { - //self.miner.RemoveLocalTx(id) -} - -func (self *UiLib) ToggleMining() bool { - if !self.eth.IsMining() { - err := self.eth.StartMining(4) - return err == nil - } else { - self.eth.StopMining() - return false - } -} - -func (self *UiLib) ToHex(data string) string { - return "0x" + common.Bytes2Hex([]byte(data)) -} - -func (self *UiLib) ToAscii(data string) string { - start := 0 - if len(data) > 1 && data[0:2] == "0x" { - start = 2 - } - return string(common.Hex2Bytes(data[start:])) -} - -/// Ethereum filter methods -func (self *UiLib) NewFilter(object map[string]interface{}, view *qml.Common) (id int) { - /* TODO remove me - filter := qt.NewFilterFromMap(object, self.eth) - filter.MessageCallback = func(messages state.Messages) { - view.Call("messages", xeth.ToMessages(messages), id) - } - id = self.filterManager.InstallFilter(filter) - return id - */ - return 0 -} - -func (self *UiLib) NewFilterString(typ string, view *qml.Common) (id int) { - /* TODO remove me - filter := core.NewFilter(self.eth) - filter.BlockCallback = func(block *types.Block) { - view.Call("messages", "{}", id) - } - id = self.filterManager.InstallFilter(filter) - return id - */ - return 0 -} - -func (self *UiLib) Messages(id int) *common.List { - /* TODO remove me - filter := self.filterManager.GetFilter(id) - if filter != nil { - messages := xeth.ToMessages(filter.Find()) - - return messages - } - */ - - return common.EmptyList() -} - -func (self *UiLib) ReadFile(p string) string { - content, err := ioutil.ReadFile(self.AssetPath(filepath.Join("ext", p))) - if err != nil { - guilogger.Infoln("error reading file", p, ":", err) - } - return string(content) -} - -func (self *UiLib) UninstallFilter(id int) { - self.filterManager.UninstallFilter(id) -} - -func mapToTxParams(object map[string]interface{}) map[string]string { - // Default values - if object["from"] == nil { - object["from"] = "" - } - if object["to"] == nil { - object["to"] = "" - } - if object["value"] == nil { - object["value"] = "" - } - if object["gas"] == nil { - object["gas"] = "" - } - if object["gasPrice"] == nil { - object["gasPrice"] = "" - } - - var dataStr string - var data []string - if list, ok := object["data"].(*qml.List); ok { - list.Convert(&data) - } else if str, ok := object["data"].(string); ok { - data = []string{str} - } - - for _, str := range data { - if common.IsHex(str) { - str = str[2:] - - if len(str) != 64 { - str = common.LeftPadString(str, 64) - } - } else { - str = common.Bytes2Hex(common.LeftPadBytes(common.Big(str).Bytes(), 32)) - } - - dataStr += str - } - object["data"] = dataStr - - conv := make(map[string]string) - for key, value := range object { - if v, ok := value.(string); ok { - conv[key] = v - } - } - - return conv -} diff --git a/ui/filter.go b/ui/filter.go deleted file mode 100644 index 5b1faa293..000000000 --- a/ui/filter.go +++ /dev/null @@ -1 +0,0 @@ -package ui diff --git a/ui/qt/filter.go b/ui/qt/filter.go deleted file mode 100644 index 090260e4e..000000000 --- a/ui/qt/filter.go +++ /dev/null @@ -1 +0,0 @@ -package qt diff --git a/ui/qt/qwhisper/message.go b/ui/qt/qwhisper/message.go deleted file mode 100644 index f8bed8a2d..000000000 --- a/ui/qt/qwhisper/message.go +++ /dev/null @@ -1,23 +0,0 @@ -package qwhisper - -import ( - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/whisper" -) - -type Message struct { - ref *whisper.Message - Flags int32 `json:"flags"` - Payload string `json:"payload"` - From string `json:"from"` -} - -func ToQMessage(msg *whisper.Message) *Message { - return &Message{ - ref: msg, - Flags: int32(msg.Flags), - Payload: "0x" + common.Bytes2Hex(msg.Payload), - From: "0x" + common.Bytes2Hex(crypto.FromECDSAPub(msg.Recover())), - } -} diff --git a/ui/qt/qwhisper/watch.go b/ui/qt/qwhisper/watch.go deleted file mode 100644 index 0ccedc719..000000000 --- a/ui/qt/qwhisper/watch.go +++ /dev/null @@ -1,13 +0,0 @@ -package qwhisper - -import ( - "fmt" - "unsafe" -) - -type Watch struct { -} - -func (self *Watch) Arrived(v unsafe.Pointer) { - fmt.Println(v) -} diff --git a/ui/qt/qwhisper/whisper.go b/ui/qt/qwhisper/whisper.go deleted file mode 100644 index 4ab6d2e5a..000000000 --- a/ui/qt/qwhisper/whisper.go +++ /dev/null @@ -1,113 +0,0 @@ -// QWhisper package. This package is temporarily on hold until QML DApp dev will reemerge. -package qwhisper - -import ( - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/whisper" - "github.com/obscuren/qml" -) - -var qlogger = logger.NewLogger("QSHH") - -type Whisper struct { - *whisper.Whisper - view qml.Object - - watches map[int]*Watch -} - -func New(w *whisper.Whisper) *Whisper { - return &Whisper{w, nil, make(map[int]*Watch)} -} - -func (self *Whisper) SetView(view qml.Object) { - self.view = view -} - -func (self *Whisper) Post(payload []string, to, from string, topics []string, priority, ttl uint32) { - var data []byte - for _, d := range payload { - data = append(data, common.FromHex(d)...) - } - - pk := crypto.ToECDSAPub(common.FromHex(from)) - if key := self.Whisper.GetIdentity(pk); key != nil { - msg := whisper.NewMessage(data) - envelope, err := msg.Wrap(time.Duration(priority*100000), whisper.Options{ - TTL: time.Duration(ttl) * time.Second, - To: crypto.ToECDSAPub(common.FromHex(to)), - From: key, - Topics: whisper.NewTopicsFromStrings(topics...), - }) - - if err != nil { - qlogger.Infoln(err) - // handle error - return - } - - if err := self.Whisper.Send(envelope); err != nil { - qlogger.Infoln(err) - // handle error - return - } - } else { - qlogger.Infoln("unmatched pub / priv for seal") - } - -} - -func (self *Whisper) NewIdentity() string { - key := self.Whisper.NewIdentity() - - return common.ToHex(crypto.FromECDSAPub(&key.PublicKey)) -} - -func (self *Whisper) HasIdentity(key string) bool { - return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) -} - -func (self *Whisper) Watch(opts map[string]interface{}, view *qml.Common) int { - filter := filterFromMap(opts) - var i int - filter.Fn = func(msg *whisper.Message) { - if view != nil { - view.Call("onShhMessage", ToQMessage(msg), i) - } - } - - i = self.Whisper.Watch(filter) - self.watches[i] = &Watch{} - - return i -} - -func (self *Whisper) Messages(id int) (messages *common.List) { - msgs := self.Whisper.Messages(id) - messages = common.EmptyList() - for _, message := range msgs { - messages.Append(ToQMessage(message)) - } - - return -} - -func filterFromMap(opts map[string]interface{}) (f whisper.Filter) { - if to, ok := opts["to"].(string); ok { - f.To = crypto.ToECDSAPub(common.FromHex(to)) - } - if from, ok := opts["from"].(string); ok { - f.From = crypto.ToECDSAPub(common.FromHex(from)) - } - if topicList, ok := opts["topics"].(*qml.List); ok { - var topics []string - topicList.Convert(&topics) - f.Topics = whisper.NewFilterTopicsFromStringsFlat(topics...) - } - - return -} diff --git a/ui/qt/qwhisper/whisper_test.go b/ui/qt/qwhisper/whisper_test.go deleted file mode 100644 index efa4e6238..000000000 --- a/ui/qt/qwhisper/whisper_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package qwhisper - -import ( - "testing" - - "github.com/ethereum/go-ethereum/whisper" -) - -func TestHasIdentity(t *testing.T) { - qw := New(whisper.New()) - id := qw.NewIdentity() - if !qw.HasIdentity(id) { - t.Error("expected to have identity") - } -} diff --git a/ui/qt/webengine/all.cpp b/ui/qt/webengine/all.cpp deleted file mode 100644 index 3b7c2f7b8..000000000 --- a/ui/qt/webengine/all.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cpp/webengine.cpp" diff --git a/ui/qt/webengine/cpp/webengine.cpp b/ui/qt/webengine/cpp/webengine.cpp deleted file mode 100644 index 118b451ef..000000000 --- a/ui/qt/webengine/cpp/webengine.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include "webengine.h" - -void webengineInitialize() { - QtWebEngine::initialize(); -} diff --git a/ui/qt/webengine/cpp/webengine.h b/ui/qt/webengine/cpp/webengine.h deleted file mode 100644 index 9c3b13bfa..000000000 --- a/ui/qt/webengine/cpp/webengine.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef WEBENGINE_H -#define WEBENGINE_H - -#ifdef __cplusplus -extern "C" { -#endif - -void webengineInitialize(); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // WEBENGINE_H diff --git a/ui/qt/webengine/webengine.go b/ui/qt/webengine/webengine.go deleted file mode 100644 index 600dbb6cb..000000000 --- a/ui/qt/webengine/webengine.go +++ /dev/null @@ -1,18 +0,0 @@ -package webengine - -// #cgo CPPFLAGS: -I./ -// #cgo CXXFLAGS: -std=c++0x -pedantic-errors -Wall -fno-strict-aliasing -// #cgo LDFLAGS: -lstdc++ -// #cgo pkg-config: Qt5WebEngine -// -// #include "cpp/webengine.h" -import "C" - -import "github.com/obscuren/qml" - -// Initializes the WebEngine extension. -func Initialize() { - qml.RunMain(func() { - C.webengineInitialize() - }) -} From 46bd6c43db04680be3b040a5338ff3e5615d3e0f Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Jun 2015 20:33:25 +0200 Subject: [PATCH 077/110] travis: removed qt deps --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b0f295fb6..11daadd41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ go: before_install: - sudo add-apt-repository ppa:beineri/opt-qt541 -y - sudo apt-get update -qq - - sudo apt-get install -yqq libgmp3-dev qt54quickcontrols qt54webengine + - sudo apt-get install -yqq libgmp3-dev install: # - go get code.google.com/p/go.tools/cmd/goimports # - go get github.com/golang/lint/golint From c590b505ed92957baf2ab4baa1788c6b0ec862cc Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Jun 2015 20:31:11 +0200 Subject: [PATCH 078/110] core, ethdb, trie: validate database errors --- common/db.go | 2 +- core/chain_manager.go | 16 +++++++++++++--- ethdb/database.go | 4 ++-- ethdb/memory_database.go | 4 +++- trie/cache.go | 8 ++++++-- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/common/db.go b/common/db.go index c12a2cfb0..7f3becd5a 100644 --- a/common/db.go +++ b/common/db.go @@ -2,7 +2,7 @@ package common // Database interface type Database interface { - Put(key []byte, value []byte) + Put(key []byte, value []byte) error Get(key []byte) ([]byte, error) Delete(key []byte) error Close() diff --git a/core/chain_manager.go b/core/chain_manager.go index c3b7273c2..e3795f561 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -377,8 +377,14 @@ func (self *ChainManager) ExportN(w io.Writer, first uint64, last uint64) error // assumes that the `mu` mutex is held! func (bc *ChainManager) insert(block *types.Block) { key := append(blockNumPre, block.Number().Bytes()...) - bc.blockDb.Put(key, block.Hash().Bytes()) - bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes()) + err := bc.blockDb.Put(key, block.Hash().Bytes()) + if err != nil { + glog.Fatal("db write fail:", err) + } + err = bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes()) + if err != nil { + glog.Fatal("db write fail:", err) + } bc.currentBlock = block bc.lastBlockHash = block.Hash() @@ -387,7 +393,11 @@ func (bc *ChainManager) insert(block *types.Block) { func (bc *ChainManager) write(block *types.Block) { enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block)) key := append(blockHashPre, block.Hash().Bytes()...) - bc.blockDb.Put(key, enc) + err := bc.blockDb.Put(key, enc) + if err != nil { + glog.Fatal("db write fail:", err) + } + // Push block to cache bc.cache.Push(block) } diff --git a/ethdb/database.go b/ethdb/database.go index 019645ced..5faf8c4e0 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -42,8 +42,8 @@ func NewLDBDatabase(file string) (*LDBDatabase, error) { } // Put puts the given key / value to the queue -func (self *LDBDatabase) Put(key []byte, value []byte) { - self.db.Put(key, rle.Compress(value), nil) +func (self *LDBDatabase) Put(key []byte, value []byte) error { + return self.db.Put(key, rle.Compress(value), nil) } // Get returns the given key if it's present. diff --git a/ethdb/memory_database.go b/ethdb/memory_database.go index f5d5faee7..c15c56bfb 100644 --- a/ethdb/memory_database.go +++ b/ethdb/memory_database.go @@ -19,8 +19,10 @@ func NewMemDatabase() (*MemDatabase, error) { return db, nil } -func (db *MemDatabase) Put(key []byte, value []byte) { +func (db *MemDatabase) Put(key []byte, value []byte) error { db.db[string(key)] = value + + return nil } func (db *MemDatabase) Set(key []byte, value []byte) { diff --git a/trie/cache.go b/trie/cache.go index 2143785fa..4c76c6cba 100644 --- a/trie/cache.go +++ b/trie/cache.go @@ -1,8 +1,10 @@ package trie +import "github.com/ethereum/go-ethereum/logger/glog" + type Backend interface { Get([]byte) ([]byte, error) - Put([]byte, []byte) + Put([]byte, []byte) error } type Cache struct { @@ -29,7 +31,9 @@ func (self *Cache) Put(key []byte, data []byte) { func (self *Cache) Flush() { for k, v := range self.store { - self.backend.Put([]byte(k), v) + if err := self.backend.Put([]byte(k), v); err != nil { + glog.Fatal("db write err:", err) + } } // This will eventually grow too large. We'd could From a40a91d60f978477fd2582487dfb5e83d4255bf4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 21 Jun 2015 17:08:47 +0200 Subject: [PATCH 079/110] trie: fixed tests --- trie/trie_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trie/trie_test.go b/trie/trie_test.go index 16311aadf..9a58958d8 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -12,7 +12,7 @@ import ( type Db map[string][]byte func (self Db) Get(k []byte) ([]byte, error) { return self[string(k)], nil } -func (self Db) Put(k, v []byte) { self[string(k)] = v } +func (self Db) Put(k, v []byte) error { self[string(k)] = v; return nil } // Used for testing func NewEmpty() *Trie { From 07c3de3f75a579cf573fae7bf7c0ec11427dda9f Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Jun 2015 16:28:11 +0200 Subject: [PATCH 080/110] core, miner, xeth: renamed gas methods * BuyGas => SubGas * RefundGas => AddGas * SetGasPool => SetGasLimit --- core/block_processor.go | 2 +- core/chain_makers.go | 2 +- core/state/state_object.go | 19 +++---------------- core/state_transition.go | 15 ++------------- miner/worker.go | 2 +- xeth/xeth.go | 4 ++-- 6 files changed, 10 insertions(+), 34 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index c78d419ce..e30ced312 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -58,7 +58,7 @@ func NewBlockProcessor(db, extra common.Database, pow pow.PoW, chainManager *Cha func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) { coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase) - coinbase.SetGasPool(block.Header().GasLimit) + coinbase.SetGasLimit(block.Header().GasLimit) // Process the transactions on to parent state receipts, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) diff --git a/core/chain_makers.go b/core/chain_makers.go index 4e685f599..76acfd6ca 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -79,7 +79,7 @@ func makeBlock(bman *BlockProcessor, parent *types.Block, i int, db common.Datab block := newBlockFromParent(addr, parent) state := state.New(block.Root(), db) cbase := state.GetOrNewStateObject(addr) - cbase.SetGasPool(CalcGasLimit(parent)) + cbase.SetGasLimit(CalcGasLimit(parent)) cbase.AddBalance(BlockReward) state.Update() block.SetRoot(state.Root()) diff --git a/core/state/state_object.go b/core/state/state_object.go index 2e4fe3269..a31c182d2 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -104,7 +104,6 @@ func NewStateObjectFromBytes(address common.Address, data []byte, db common.Data } object := &StateObject{address: address, db: db} - //object.RlpDecode(data) object.nonce = extobject.Nonce object.balance = extobject.Balance object.codeHash = extobject.CodeHash @@ -215,20 +214,8 @@ func (c *StateObject) St() Storage { // Return the gas back to the origin. Used by the Virtual machine or Closures func (c *StateObject) ReturnGas(gas, price *big.Int) {} -func (c *StateObject) ConvertGas(gas, price *big.Int) error { - total := new(big.Int).Mul(gas, price) - if total.Cmp(c.balance) > 0 { - return fmt.Errorf("insufficient amount: %v, %v", c.balance, total) - } - c.SubBalance(total) - - c.dirty = true - - return nil -} - -func (self *StateObject) SetGasPool(gasLimit *big.Int) { +func (self *StateObject) SetGasLimit(gasLimit *big.Int) { self.gasPool = new(big.Int).Set(gasLimit) if glog.V(logger.Core) { @@ -236,7 +223,7 @@ func (self *StateObject) SetGasPool(gasLimit *big.Int) { } } -func (self *StateObject) BuyGas(gas, price *big.Int) error { +func (self *StateObject) SubGas(gas, price *big.Int) error { if self.gasPool.Cmp(gas) < 0 { return GasLimitError(self.gasPool, gas) } @@ -251,7 +238,7 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { return nil } -func (self *StateObject) RefundGas(gas, price *big.Int) { +func (self *StateObject) AddGas(gas, price *big.Int) { self.gasPool.Add(self.gasPool, gas) } diff --git a/core/state_transition.go b/core/state_transition.go index 4a8d92375..915dd466b 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -151,7 +151,7 @@ func (self *StateTransition) BuyGas() error { } coinbase := self.Coinbase() - err = coinbase.BuyGas(self.msg.Gas(), self.msg.GasPrice()) + err = coinbase.SubGas(self.msg.Gas(), self.msg.GasPrice()) if err != nil { return err } @@ -245,20 +245,9 @@ func (self *StateTransition) refundGas() { self.gas.Add(self.gas, refund) self.state.AddBalance(sender.Address(), refund.Mul(refund, self.msg.GasPrice())) - coinbase.RefundGas(self.gas, self.msg.GasPrice()) + coinbase.AddGas(self.gas, self.msg.GasPrice()) } func (self *StateTransition) gasUsed() *big.Int { return new(big.Int).Sub(self.initialGas, self.gas) } - -// Converts an message in to a state object -func makeContract(msg Message, state *state.StateDB) *state.StateObject { - faddr, _ := msg.From() - addr := crypto.CreateAddress(faddr, msg.Nonce()) - - contract := state.GetOrNewStateObject(addr) - contract.SetInitCode(msg.Data()) - - return contract -} diff --git a/miner/worker.go b/miner/worker.go index d339507ca..55c23376c 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -319,7 +319,7 @@ func (self *worker) makeCurrent() { current.localMinedBlocks = self.current.localMinedBlocks } - current.coinbase.SetGasPool(core.CalcGasLimit(parent)) + current.coinbase.SetGasLimit(core.CalcGasLimit(parent)) self.current = current } diff --git a/xeth/xeth.go b/xeth/xeth.go index 7342be4a9..99e17423a 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -212,7 +212,7 @@ func (self *XEth) ApplyTestTxs(statedb *state.StateDB, address common.Address, t block := self.backend.ChainManager().NewBlock(address) coinbase := statedb.GetStateObject(address) - coinbase.SetGasPool(big.NewInt(10000000)) + coinbase.SetGasLimit(big.NewInt(10000000)) txs := self.backend.TxPool().GetQueuedTransactions() for i := 0; i < len(txs); i++ { @@ -827,7 +827,7 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st } from.SetBalance(common.MaxBig) - from.SetGasPool(self.backend.ChainManager().GasLimit()) + from.SetGasLimit(self.backend.ChainManager().GasLimit()) msg := callmsg{ from: from, to: common.HexToAddress(toStr), From 398d08a8dd9617954c55219872a5e0eecc1ea41d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Jun 2015 22:20:14 +0200 Subject: [PATCH 081/110] tests: SetGasLimit --- tests/state_test_util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index e9abad788..2f3d497be 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -166,7 +166,7 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state. snapshot := statedb.Copy() coinbase := statedb.GetOrNewStateObject(caddr) - coinbase.SetGasPool(common.Big(env["currentGasLimit"])) + coinbase.SetGasLimit(common.Big(env["currentGasLimit"])) message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce) vmenv := NewEnvFromMap(statedb, env, tx) From 6fb810adaa539a2fa97cf4481588b339ab5279ae Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 22 Jun 2015 00:01:56 +0200 Subject: [PATCH 082/110] p2p: throttle all discovery lookups Lookup calls would spin out of control when network connectivity was lost. The throttling that was in place only took effect when the table returned zero results, which doesn't happen very often. The new throttling should not have a negative impact when the host is online. Lookups against the network take some time and dials for all results must complete or hit the cache before a new one is started. This usually takes longer than four seconds, leaving online lookups unaffected. Fixes #1296 --- p2p/dial.go | 30 +++++++++++++++--------------- p2p/server.go | 1 + 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/p2p/dial.go b/p2p/dial.go index 71065c5ee..b82d6d1f5 100644 --- a/p2p/dial.go +++ b/p2p/dial.go @@ -17,10 +17,9 @@ const ( // redialing a certain node. dialHistoryExpiration = 30 * time.Second - // Discovery lookup tasks will wait for this long when - // no results are returned. This can happen if the table - // becomes empty (i.e. not often). - emptyLookupDelay = 10 * time.Second + // Discovery lookups are throttled and can only run + // once every few seconds. + lookupInterval = 4 * time.Second ) // dialstate schedules dials and discovery lookups. @@ -206,18 +205,19 @@ func (t *dialTask) String() string { func (t *discoverTask) Do(srv *Server) { if t.bootstrap { srv.ntab.Bootstrap(srv.BootstrapNodes) - } else { - var target discover.NodeID - rand.Read(target[:]) - t.results = srv.ntab.Lookup(target) - // newTasks generates a lookup task whenever dynamic dials are - // necessary. Lookups need to take some time, otherwise the - // event loop spins too fast. An empty result can only be - // returned if the table is empty. - if len(t.results) == 0 { - time.Sleep(emptyLookupDelay) - } + return } + // newTasks generates a lookup task whenever dynamic dials are + // necessary. Lookups need to take some time, otherwise the + // event loop spins too fast. + next := srv.lastLookup.Add(lookupInterval) + if now := time.Now(); now.Before(next) { + time.Sleep(next.Sub(now)) + } + srv.lastLookup = time.Now() + var target discover.NodeID + rand.Read(target[:]) + t.results = srv.ntab.Lookup(target) } func (t *discoverTask) String() (s string) { diff --git a/p2p/server.go b/p2p/server.go index 59b97a0aa..5eff70345 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -115,6 +115,7 @@ type Server struct { ntab discoverTable listener net.Listener ourHandshake *protoHandshake + lastLookup time.Time // These are for Peers, PeerCount (and nothing else). peerOp chan peerOpFunc From 60c2ccd99cd9acdb628a9ba5e16ad0e7e52b7e17 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 11:16:50 +0200 Subject: [PATCH 083/110] made ipc handler generic and reusable --- rpc/comms/comms.go | 38 ++++++++++++++++++++++++++++++++++++++ rpc/comms/ipc_unix.go | 29 +---------------------------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 244f5a7a6..3f458adfd 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -1,7 +1,45 @@ package comms +import ( + "io" + "net" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" +) + type EthereumClient interface { Close() Send(interface{}) error Recv() (interface{}, error) } + +func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) { + codec := c.New(conn) + + for { + req, err := codec.ReadRequest() + if err == io.EOF { + codec.Close() + return + } else if err != nil { + glog.V(logger.Error).Infof("IPC recv err - %v\n", err) + codec.Close() + return + } + + var rpcResponse interface{} + res, err := api.Execute(req) + + rpcResponse = shared.NewRpcResponse(req.Id, req.Jsonrpc, res, err) + err = codec.WriteResponse(rpcResponse) + if err != nil { + glog.V(logger.Error).Infof("comms send err - %v\n", err) + codec.Close() + return + } + } +} diff --git a/rpc/comms/ipc_unix.go b/rpc/comms/ipc_unix.go index 5a94fd1e0..131fb86f2 100644 --- a/rpc/comms/ipc_unix.go +++ b/rpc/comms/ipc_unix.go @@ -3,7 +3,6 @@ package comms import ( - "io" "net" "os" @@ -11,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" ) func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) { @@ -40,32 +38,7 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error { continue } - go func(conn net.Conn) { - codec := codec.New(conn) - - for { - req, err := codec.ReadRequest() - if err == io.EOF { - codec.Close() - return - } else if err != nil { - glog.V(logger.Error).Infof("IPC recv err - %v\n", err) - codec.Close() - return - } - - var rpcResponse interface{} - res, err := api.Execute(req) - - rpcResponse = shared.NewRpcResponse(req.Id, req.Jsonrpc, res, err) - err = codec.WriteResponse(rpcResponse) - if err != nil { - glog.V(logger.Error).Infof("IPC send err - %v\n", err) - codec.Close() - return - } - } - }(conn) + go handle(conn, api, codec) } os.Remove(cfg.Endpoint) From fd764d4ff7bd7e75dfdd7f733f50dd3805d4b3f2 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 13:07:13 +0200 Subject: [PATCH 084/110] added comms http --- rpc/api/mergedapi.go | 4 + rpc/comms/comms.go | 7 +- rpc/comms/http.go | 65 ++++++++++++++++ rpc/comms/http_net.go | 167 ++++++++++++++++++++++++++++++++++++++++++ rpc/shared/types.go | 12 +++ 5 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 rpc/comms/http.go create mode 100644 rpc/comms/http_net.go diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go index b62477a14..8cf4ae96e 100644 --- a/rpc/api/mergedapi.go +++ b/rpc/api/mergedapi.go @@ -1,6 +1,8 @@ package api import ( + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -40,6 +42,8 @@ func (self *MergedApi) Methods() []string { // Call the correct API's Execute method for the given request func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) { + glog.V(logger.Detail).Infof("rpc method: %s", req.Method) + if res, _ := self.handle(req); res != nil { return res, nil } diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 3f458adfd..2af63e55d 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -11,6 +11,11 @@ import ( "github.com/ethereum/go-ethereum/rpc/shared" ) +const ( + jsonrpcver = "2.0" + maxHttpSizeReqLength = 1024 * 1024 // 1MB +) + type EthereumClient interface { Close() Send(interface{}) error @@ -26,7 +31,7 @@ func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) { codec.Close() return } else if err != nil { - glog.V(logger.Error).Infof("IPC recv err - %v\n", err) + glog.V(logger.Error).Infof("comms recv err - %v\n", err) codec.Close() return } diff --git a/rpc/comms/http.go b/rpc/comms/http.go new file mode 100644 index 000000000..1fea8dc1d --- /dev/null +++ b/rpc/comms/http.go @@ -0,0 +1,65 @@ +package comms + +import ( + "fmt" + "net/http" + "strings" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/rs/cors" +) + +var ( + // main HTTP rpc listener + httpListener *stoppableTCPListener + listenerStoppedError = fmt.Errorf("Listener has stopped") +) + +type HttpConfig struct { + ListenAddress string + ListenPort uint + CorsDomain string +} + +func StartHttp(cfg HttpConfig, codec codec.Codec, apis ...api.EthereumApi) error { + if httpListener != nil { + if fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) != httpListener.Addr().String() { + return fmt.Errorf("RPC service already running on %s ", httpListener.Addr().String()) + } + return nil // RPC service already running on given host/port + } + + l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort)) + if err != nil { + glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", cfg.ListenAddress, cfg.ListenPort, err) + return err + } + httpListener = l + + api := api.Merge(apis...) + var handler http.Handler + if len(cfg.CorsDomain) > 0 { + var opts cors.Options + opts.AllowedMethods = []string{"POST"} + opts.AllowedOrigins = strings.Split(cfg.CorsDomain, " ") + + c := cors.New(opts) + handler = newStoppableHandler(c.Handler(gethHttpHandler(codec, api)), l.stop) + } else { + handler = newStoppableHandler(gethHttpHandler(codec, api), l.stop) + } + + go http.Serve(l, handler) + + return nil +} + +func StopHttp() { + if httpListener != nil { + httpListener.Stop() + httpListener = nil + } +} diff --git a/rpc/comms/http_net.go b/rpc/comms/http_net.go new file mode 100644 index 000000000..8d1bacc06 --- /dev/null +++ b/rpc/comms/http_net.go @@ -0,0 +1,167 @@ +package comms + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net" + "net/http" + "time" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" +) + +// When https://github.com/golang/go/issues/4674 is implemented this could be replaced +type stoppableTCPListener struct { + *net.TCPListener + stop chan struct{} // closed when the listener must stop +} + +func newStoppableTCPListener(addr string) (*stoppableTCPListener, error) { + wl, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + + if tcpl, ok := wl.(*net.TCPListener); ok { + stop := make(chan struct{}) + return &stoppableTCPListener{tcpl, stop}, nil + } + + return nil, fmt.Errorf("Unable to create TCP listener for RPC service") +} + +// Stop the listener and all accepted and still active connections. +func (self *stoppableTCPListener) Stop() { + close(self.stop) +} + +func (self *stoppableTCPListener) Accept() (net.Conn, error) { + for { + self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second))) + c, err := self.TCPListener.AcceptTCP() + + select { + case <-self.stop: + if c != nil { // accept timeout + c.Close() + } + self.TCPListener.Close() + return nil, listenerStoppedError + default: + } + + if err != nil { + if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() { + continue // regular timeout + } + } + + return &closableConnection{c, self.stop}, err + } +} + +type closableConnection struct { + *net.TCPConn + closed chan struct{} +} + +func (self *closableConnection) Read(b []byte) (n int, err error) { + select { + case <-self.closed: + self.TCPConn.Close() + return 0, io.EOF + default: + return self.TCPConn.Read(b) + } +} + +// Wraps the default handler and checks if the RPC service was stopped. In that case it returns an +// error indicating that the service was stopped. This will only happen for connections which are +// kept open (HTTP keep-alive) when the RPC service was shutdown. +func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + select { + case <-stop: + w.Header().Set("Content-Type", "application/json") + err := fmt.Errorf("RPC service stopped") + response := shared.NewRpcResponse(-1, jsonrpcver, nil, err) + httpSend(w, response) + default: + h.ServeHTTP(w, r) + } + }) +} + +func httpSend(writer io.Writer, v interface{}) (n int, err error) { + var payload []byte + payload, err = json.MarshalIndent(v, "", "\t") + if err != nil { + glog.V(logger.Error).Infoln("Error marshalling JSON", err) + return 0, err + } + glog.V(logger.Detail).Infof("Sending payload: %s", payload) + + return writer.Write(payload) +} + +func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") + + // Limit request size to resist DoS + if req.ContentLength > maxHttpSizeReqLength { + err := fmt.Errorf("Request too large") + response := shared.NewRpcErrorResponse(-1, jsonrpcver, -32700, err) + httpSend(w, &response) + return + } + + defer req.Body.Close() + payload, err := ioutil.ReadAll(req.Body) + if err != nil { + err := fmt.Errorf("Could not read request body") + response := shared.NewRpcErrorResponse(-1, jsonrpcver, -32700, err) + httpSend(w, &response) + return + } + + c := codec.New(nil) + var rpcReq shared.Request + if err = c.Decode(payload, &rpcReq); err == nil { + reply, err := api.Execute(&rpcReq) + res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) + httpSend(w, &res) + return + } + + var reqBatch []shared.Request + if err = c.Decode(payload, &reqBatch); err == nil { + resBatch := make([]*interface{}, len(reqBatch)) + resCount := 0 + + for i, rpcReq := range reqBatch { + reply, err := api.Execute(&rpcReq) + if rpcReq.Id != nil { // this leaves nil entries in the response batch for later removal + resBatch[i] = shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) + resCount += 1 + } + } + + // make response omitting nil entries + resBatch = resBatch[:resCount] + httpSend(w, resBatch) + return + } + + // invalid request + err = fmt.Errorf("Could not decode request") + res := shared.NewRpcErrorResponse(-1, jsonrpcver, -32600, err) + httpSend(w, res) + }) +} diff --git a/rpc/shared/types.go b/rpc/shared/types.go index 6a29fa88e..dd38a4559 100644 --- a/rpc/shared/types.go +++ b/rpc/shared/types.go @@ -42,6 +42,18 @@ type ErrorObject struct { // Data interface{} `json:"data"` } +// Create RPC error response, this allows for custom error codes +func NewRpcErrorResponse(id interface{}, jsonrpcver string, errCode int, err error) *interface{} { + var response interface{} + + jsonerr := &ErrorObject{errCode, err.Error()} + response = ErrorResponse{Jsonrpc: jsonrpcver, Id: id, Error: jsonerr} + + glog.V(logger.Detail).Infof("Generated error response: %s", response) + return &response +} + +// Create RPC response func NewRpcResponse(id interface{}, jsonrpcver string, reply interface{}, err error) *interface{} { var response interface{} From 5c25403b13a698267230f859e822a7f714082198 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 13:30:53 +0200 Subject: [PATCH 085/110] refactored old rpc structure to new --- cmd/geth/main.go | 1 + cmd/utils/flags.go | 19 +++++++++++++++---- rpc/api/api.go | 4 ++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 89aae43e5..43e45f6cc 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -239,6 +239,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.RPCEnabledFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, + utils.RpcApiFlag, utils.IPCDisabledFlag, utils.IPCApiFlag, utils.IPCPathFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 696dbd142..e0eefb3e3 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/p2p/nat" - "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/comms" @@ -209,13 +208,18 @@ var ( Usage: "Domain on which to send Access-Control-Allow-Origin header", Value: "", } + RpcApiFlag = cli.StringFlag{ + Name: "rpcapi", + Usage: "Specify the API's which are offered over the HTTP RPC interface", + Value: api.DefaultHttpRpcApis, + } IPCDisabledFlag = cli.BoolFlag{ Name: "ipcdisable", Usage: "Disable the IPC-RPC server", } IPCApiFlag = cli.StringFlag{ Name: "ipcapi", - Usage: "Specify the API's which are offered over this interface", + Usage: "Specify the API's which are offered over the IPC interface", Value: api.DefaultIpcApis, } IPCPathFlag = DirectoryFlag{ @@ -457,14 +461,21 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error { } func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error { - config := rpc.RpcConfig{ + config := comms.HttpConfig{ ListenAddress: ctx.GlobalString(RPCListenAddrFlag.Name), ListenPort: uint(ctx.GlobalInt(RPCPortFlag.Name)), CorsDomain: ctx.GlobalString(RPCCORSDomainFlag.Name), } xeth := xeth.New(eth, nil) - return rpc.Start(xeth, config) + codec := codec.JSON + + apis, err := api.ParseApiString(ctx.GlobalString(RpcApiFlag.Name), codec, xeth, eth) + if err != nil { + return err + } + + return comms.StartHttp(config, codec, apis...) } func StartPProf(ctx *cli.Context) { diff --git a/rpc/api/api.go b/rpc/api/api.go index e431e5c1e..dec67fed1 100644 --- a/rpc/api/api.go +++ b/rpc/api/api.go @@ -20,6 +20,10 @@ const ( ) var ( + DefaultHttpRpcApis = strings.Join([]string{ + EthApiName, NetApiName, Web3ApiName, + }, ",") + // List with all API's which are offered over the IPC interface by default DefaultIpcApis = strings.Join([]string{ AdminApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, From c3f6c322c07a96d3930c75d05ed3859e7d80ddbc Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 14:59:39 +0200 Subject: [PATCH 086/110] added DB api --- rpc/api/admin.go | 6 +-- rpc/api/api.go | 5 +- rpc/api/db.go | 128 +++++++++++++++++++++++++++++++++++++++++++++ rpc/api/db_args.go | 110 ++++++++++++++++++++++++++++++++++++++ rpc/api/db_js.go | 41 +++++++++++++++ rpc/api/utils.go | 10 ++++ 6 files changed, 295 insertions(+), 5 deletions(-) create mode 100644 rpc/api/db.go create mode 100644 rpc/api/db_args.go create mode 100644 rpc/api/db_js.go diff --git a/rpc/api/admin.go b/rpc/api/admin.go index a6b9cf050..532bdcadd 100644 --- a/rpc/api/admin.go +++ b/rpc/api/admin.go @@ -222,10 +222,10 @@ func (self *adminApi) ChainSyncStatus(req *shared.Request) (interface{}, error) pending, cached, importing, estimate := self.ethereum.Downloader().Stats() return map[string]interface{}{ - "blocksAvailable": pending, + "blocksAvailable": pending, "blocksWaitingForImport": cached, - "importing": importing, - "estimate": estimate.String(), + "importing": importing, + "estimate": estimate.String(), }, nil } diff --git a/rpc/api/api.go b/rpc/api/api.go index dec67fed1..7fc22a263 100644 --- a/rpc/api/api.go +++ b/rpc/api/api.go @@ -9,6 +9,7 @@ import ( const ( AdminApiName = "admin" EthApiName = "eth" + DbApiName = "db" DebugApiName = "debug" MergedApiName = "merged" MinerApiName = "miner" @@ -21,12 +22,12 @@ const ( var ( DefaultHttpRpcApis = strings.Join([]string{ - EthApiName, NetApiName, Web3ApiName, + DbApiName, EthApiName, NetApiName, Web3ApiName, }, ",") // List with all API's which are offered over the IPC interface by default DefaultIpcApis = strings.Join([]string{ - AdminApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, + AdminApiName, DbApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName, }, ",") ) diff --git a/rpc/api/db.go b/rpc/api/db.go new file mode 100644 index 000000000..745269168 --- /dev/null +++ b/rpc/api/db.go @@ -0,0 +1,128 @@ +package api + +import ( + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" + "github.com/ethereum/go-ethereum/xeth" +) + +const ( + DbApiversion = "1.0" +) + +var ( + // mapping between methods and handlers + DbMapping = map[string]dbhandler{ + "db_getString": (*dbApi).GetString, + "db_putString": (*dbApi).PutString, + "db_getHex": (*dbApi).GetHex, + "db_putHex": (*dbApi).PutHex, + } +) + +// db callback handler +type dbhandler func(*dbApi, *shared.Request) (interface{}, error) + +// db api provider +type dbApi struct { + xeth *xeth.XEth + ethereum *eth.Ethereum + methods map[string]dbhandler + codec codec.ApiCoder +} + +// create a new db api instance +func NewDbApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *dbApi { + return &dbApi{ + xeth: xeth, + ethereum: ethereum, + methods: DbMapping, + codec: coder.New(nil), + } +} + +// collection with supported methods +func (self *dbApi) Methods() []string { + methods := make([]string, len(self.methods)) + i := 0 + for k := range self.methods { + methods[i] = k + i++ + } + return methods +} + +// Execute given request +func (self *dbApi) Execute(req *shared.Request) (interface{}, error) { + if callback, ok := self.methods[req.Method]; ok { + return callback(self, req) + } + + return nil, &shared.NotImplementedError{req.Method} +} + +func (self *dbApi) Name() string { + return DbApiName +} + +func (self *dbApi) ApiVersion() string { + return DbApiversion +} + +func (self *dbApi) GetString(req *shared.Request) (interface{}, error) { + args := new(DbArgs) + if err := self.codec.Decode(req.Params, &args); err != nil { + return nil, shared.NewDecodeParamError(err.Error()) + } + + if err := args.requirements(); err != nil { + return nil, err + } + + ret, err := self.xeth.DbGet([]byte(args.Database + args.Key)) + return string(ret), err +} + +func (self *dbApi) PutString(req *shared.Request) (interface{}, error) { + args := new(DbArgs) + if err := self.codec.Decode(req.Params, &args); err != nil { + return nil, shared.NewDecodeParamError(err.Error()) + } + + if err := args.requirements(); err != nil { + return nil, err + } + + return self.xeth.DbPut([]byte(args.Database+args.Key), args.Value), nil +} + +func (self *dbApi) GetHex(req *shared.Request) (interface{}, error) { + args := new(DbHexArgs) + if err := self.codec.Decode(req.Params, &args); err != nil { + return nil, shared.NewDecodeParamError(err.Error()) + } + + if err := args.requirements(); err != nil { + return nil, err + } + + if res, err := self.xeth.DbGet([]byte(args.Database + args.Key)); err == nil { + return newHexData(res), nil + } else { + return nil, err + } +} + +func (self *dbApi) PutHex(req *shared.Request) (interface{}, error) { + args := new(DbHexArgs) + if err := self.codec.Decode(req.Params, &args); err != nil { + return nil, shared.NewDecodeParamError(err.Error()) + } + + if err := args.requirements(); err != nil { + return nil, err + } + + return self.xeth.DbPut([]byte(args.Database+args.Key), args.Value), nil +} diff --git a/rpc/api/db_args.go b/rpc/api/db_args.go new file mode 100644 index 000000000..459616d87 --- /dev/null +++ b/rpc/api/db_args.go @@ -0,0 +1,110 @@ +package api + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc/shared" +) + +type DbArgs struct { + Database string + Key string + Value []byte +} + +func (args *DbArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 2 { + return shared.NewInsufficientParamsError(len(obj), 2) + } + + var objstr string + var ok bool + + if objstr, ok = obj[0].(string); !ok { + return shared.NewInvalidTypeError("database", "not a string") + } + args.Database = objstr + + if objstr, ok = obj[1].(string); !ok { + return shared.NewInvalidTypeError("key", "not a string") + } + args.Key = objstr + + if len(obj) > 2 { + objstr, ok = obj[2].(string) + if !ok { + return shared.NewInvalidTypeError("value", "not a string") + } + + args.Value = []byte(objstr) + } + + return nil +} + +func (a *DbArgs) requirements() error { + if len(a.Database) == 0 { + return shared.NewValidationError("Database", "cannot be blank") + } + if len(a.Key) == 0 { + return shared.NewValidationError("Key", "cannot be blank") + } + return nil +} + +type DbHexArgs struct { + Database string + Key string + Value []byte +} + +func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 2 { + return shared.NewInsufficientParamsError(len(obj), 2) + } + + var objstr string + var ok bool + + if objstr, ok = obj[0].(string); !ok { + return shared.NewInvalidTypeError("database", "not a string") + } + args.Database = objstr + + if objstr, ok = obj[1].(string); !ok { + return shared.NewInvalidTypeError("key", "not a string") + } + args.Key = objstr + + if len(obj) > 2 { + objstr, ok = obj[2].(string) + if !ok { + return shared.NewInvalidTypeError("value", "not a string") + } + + args.Value = common.FromHex(objstr) + } + + return nil +} + +func (a *DbHexArgs) requirements() error { + if len(a.Database) == 0 { + return shared.NewValidationError("Database", "cannot be blank") + } + if len(a.Key) == 0 { + return shared.NewValidationError("Key", "cannot be blank") + } + return nil +} diff --git a/rpc/api/db_js.go b/rpc/api/db_js.go new file mode 100644 index 000000000..62cdcd20e --- /dev/null +++ b/rpc/api/db_js.go @@ -0,0 +1,41 @@ +package api + +const Db_JS = ` +web3._extend({ + property: 'db', + methods: + [ + new web3._extend.Method({ + name: 'getString', + call: 'db_getString', + params: 2, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputString + }), + new web3._extend.Method({ + name: 'putString', + call: 'db_putString', + params: 3, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputBool + }), + new web3._extend.Method({ + name: 'getHex', + call: 'db_getHex', + params: 2, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputString + }), + new web3._extend.Method({ + name: 'putHex', + call: 'db_putHex', + params: 3, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputBool + }), + ], + properties: + [ + ] +}); +` diff --git a/rpc/api/utils.go b/rpc/api/utils.go index 40bcae52f..a4ce6409a 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -24,6 +24,12 @@ var ( "setSolc", "datadir", }, + "db": []string{ + "getString", + "putString", + "getHex", + "putHex", + }, "debug": []string{ "dumpBlock", "getBlockRlp", @@ -137,6 +143,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth. apis[i] = NewAdminApi(xeth, eth, codec) case DebugApiName: apis[i] = NewDebugApi(xeth, eth, codec) + case DbApiName: + apis[i] = NewDbApi(xeth, eth, codec) case EthApiName: apis[i] = NewEthApi(xeth, codec) case MinerApiName: @@ -165,6 +173,8 @@ func Javascript(name string) string { return Admin_JS case DebugApiName: return Debug_JS + case DbApiName: + return Db_JS case MinerApiName: return Miner_JS case NetApiName: From 5fdf72b1abba65bcaed116791b6b8b70edb17e49 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 15:16:06 +0200 Subject: [PATCH 087/110] fixed web3 rpc test failures --- rpc/api/web3_args.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rpc/api/web3_args.go b/rpc/api/web3_args.go index 5455a6c8e..38af7191e 100644 --- a/rpc/api/web3_args.go +++ b/rpc/api/web3_args.go @@ -1,5 +1,29 @@ package api +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/rpc/shared" +) + type Sha3Args struct { Data string } + +func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + + argstr, ok := obj[0].(string) + if !ok { + return shared.NewInvalidTypeError("data", "is not a string") + } + args.Data = argstr + return nil +} From 9ac1b4e59e3abc2742491f39f4f93bc459846098 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 15:37:25 +0200 Subject: [PATCH 088/110] fixed rpc test failure in net_peerCount --- rpc/api/net.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api/net.go b/rpc/api/net.go index d6888ee4a..247c23827 100644 --- a/rpc/api/net.go +++ b/rpc/api/net.go @@ -77,7 +77,7 @@ func (self *netApi) Version(req *shared.Request) (interface{}, error) { // Number of connected peers func (self *netApi) PeerCount(req *shared.Request) (interface{}, error) { - return self.xeth.PeerCount(), nil + return newHexNum(self.xeth.PeerCount()), nil } func (self *netApi) IsListening(req *shared.Request) (interface{}, error) { From 3e1d635f8d40815ef2262e017a969ed6f5eb2a5d Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 15:40:24 +0200 Subject: [PATCH 089/110] fixed rpc test failure in eth.blockNumber --- rpc/api/eth.go | 88 ++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/rpc/api/eth.go b/rpc/api/eth.go index cb678922b..91577c4d5 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -28,48 +28,49 @@ type ethhandler func(*ethApi, *shared.Request) (interface{}, error) var ( ethMapping = map[string]ethhandler{ - "eth_accounts": (*ethApi).Accounts, - "eth_blockNumber": (*ethApi).BlockNumber, - "eth_getBalance": (*ethApi).GetBalance, - "eth_protocolVersion": (*ethApi).ProtocolVersion, - "eth_coinbase": (*ethApi).Coinbase, - "eth_mining": (*ethApi).IsMining, - "eth_gasPrice": (*ethApi).GasPrice, - "eth_getStorage": (*ethApi).GetStorage, - "eth_storageAt": (*ethApi).GetStorage, - "eth_getStorageAt": (*ethApi).GetStorageAt, - "eth_getTransactionCount": (*ethApi).GetTransactionCount, - "eth_getBlockTransactionCountByHash": (*ethApi).GetBlockTransactionCountByHash, - "eth_getBlockTransactionCountByNumber": (*ethApi).GetBlockTransactionCountByNumber, - "eth_getUncleCountByBlockHash": (*ethApi).GetUncleCountByBlockHash, - "eth_getUncleCountByBlockNumber": (*ethApi).GetUncleCountByBlockNumber, - "eth_getData": (*ethApi).GetData, - "eth_getCode": (*ethApi).GetData, - "eth_sign": (*ethApi).Sign, - "eth_sendRawTransaction": (*ethApi).PushTx, - "eth_sendTransaction": (*ethApi).SendTransaction, - "eth_transact": (*ethApi).SendTransaction, - "eth_estimateGas": (*ethApi).EstimateGas, - "eth_call": (*ethApi).Call, - "eth_flush": (*ethApi).Flush, - "eth_getBlockByHash": (*ethApi).GetBlockByHash, - "eth_getBlockByNumber": (*ethApi).GetBlockByNumber, - "eth_getTransactionByHash": (*ethApi).GetTransactionByHash, - "eth_getTransactionByBlockHashAndIndex": (*ethApi).GetTransactionByBlockHashAndIndex, - "eth_getUncleByBlockHashAndIndex": (*ethApi).GetUncleByBlockHashAndIndex, - "eth_getUncleByBlockNumberAndIndex": (*ethApi).GetUncleByBlockNumberAndIndex, - "eth_getCompilers": (*ethApi).GetCompilers, - "eth_compileSolidity": (*ethApi).CompileSolidity, - "eth_newFilter": (*ethApi).NewFilter, - "eth_newBlockFilter": (*ethApi).NewBlockFilter, - "eth_newPendingTransactionFilter": (*ethApi).NewPendingTransactionFilter, - "eth_uninstallFilter": (*ethApi).UninstallFilter, - "eth_getFilterChanges": (*ethApi).GetFilterChanges, - "eth_getFilterLogs": (*ethApi).GetFilterLogs, - "eth_getLogs": (*ethApi).GetLogs, - "eth_hashrate": (*ethApi).Hashrate, - "eth_getWork": (*ethApi).GetWork, - "eth_submitWork": (*ethApi).SubmitWork, + "eth_accounts": (*ethApi).Accounts, + "eth_blockNumber": (*ethApi).BlockNumber, + "eth_getBalance": (*ethApi).GetBalance, + "eth_protocolVersion": (*ethApi).ProtocolVersion, + "eth_coinbase": (*ethApi).Coinbase, + "eth_mining": (*ethApi).IsMining, + "eth_gasPrice": (*ethApi).GasPrice, + "eth_getStorage": (*ethApi).GetStorage, + "eth_storageAt": (*ethApi).GetStorage, + "eth_getStorageAt": (*ethApi).GetStorageAt, + "eth_getTransactionCount": (*ethApi).GetTransactionCount, + "eth_getBlockTransactionCountByHash": (*ethApi).GetBlockTransactionCountByHash, + "eth_getBlockTransactionCountByNumber": (*ethApi).GetBlockTransactionCountByNumber, + "eth_getUncleCountByBlockHash": (*ethApi).GetUncleCountByBlockHash, + "eth_getUncleCountByBlockNumber": (*ethApi).GetUncleCountByBlockNumber, + "eth_getData": (*ethApi).GetData, + "eth_getCode": (*ethApi).GetData, + "eth_sign": (*ethApi).Sign, + "eth_sendRawTransaction": (*ethApi).PushTx, + "eth_sendTransaction": (*ethApi).SendTransaction, + "eth_transact": (*ethApi).SendTransaction, + "eth_estimateGas": (*ethApi).EstimateGas, + "eth_call": (*ethApi).Call, + "eth_flush": (*ethApi).Flush, + "eth_getBlockByHash": (*ethApi).GetBlockByHash, + "eth_getBlockByNumber": (*ethApi).GetBlockByNumber, + "eth_getTransactionByHash": (*ethApi).GetTransactionByHash, + "eth_getTransactionByBlockNumberAndIndex": (*ethApi).GetTransactionByBlockNumberAndIndex, + "eth_getTransactionByBlockHashAndIndex": (*ethApi).GetTransactionByBlockHashAndIndex, + "eth_getUncleByBlockHashAndIndex": (*ethApi).GetUncleByBlockHashAndIndex, + "eth_getUncleByBlockNumberAndIndex": (*ethApi).GetUncleByBlockNumberAndIndex, + "eth_getCompilers": (*ethApi).GetCompilers, + "eth_compileSolidity": (*ethApi).CompileSolidity, + "eth_newFilter": (*ethApi).NewFilter, + "eth_newBlockFilter": (*ethApi).NewBlockFilter, + "eth_newPendingTransactionFilter": (*ethApi).NewPendingTransactionFilter, + "eth_uninstallFilter": (*ethApi).UninstallFilter, + "eth_getFilterChanges": (*ethApi).GetFilterChanges, + "eth_getFilterLogs": (*ethApi).GetFilterLogs, + "eth_getLogs": (*ethApi).GetLogs, + "eth_hashrate": (*ethApi).Hashrate, + "eth_getWork": (*ethApi).GetWork, + "eth_submitWork": (*ethApi).SubmitWork, } ) @@ -115,7 +116,8 @@ func (self *ethApi) Hashrate(req *shared.Request) (interface{}, error) { } func (self *ethApi) BlockNumber(req *shared.Request) (interface{}, error) { - return self.xeth.CurrentBlock().Number(), nil + num := self.xeth.CurrentBlock().Number() + return newHexNum(num.Bytes()), nil } func (self *ethApi) GetBalance(req *shared.Request) (interface{}, error) { From a4a4e9fcf824189d8d06940492a01effe6e6cf92 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Wed, 17 Jun 2015 16:22:35 +0200 Subject: [PATCH 090/110] removed old rpc structure and added new inproc api client --- cmd/geth/admin.go | 937 --------------------------- cmd/geth/js.go | 189 +++++- cmd/geth/main.go | 9 +- cmd/utils/flags.go | 4 +- core/transaction_pool.go | 2 +- rpc/api.go | 646 ------------------- rpc/api/api.go | 10 +- rpc/api/args.go | 57 ++ rpc/{ => api}/args_test.go | 11 +- rpc/api_test.go | 205 ------ rpc/args.go | 1230 ------------------------------------ rpc/comms/comms.go | 18 +- rpc/comms/http.go | 24 + rpc/comms/http_net.go | 14 +- rpc/comms/inproc.go | 53 ++ rpc/comms/ipc.go | 8 +- rpc/http.go | 163 ----- rpc/jeth.go | 44 +- rpc/responses.go | 316 --------- rpc/responses_test.go | 295 --------- rpc/types.go | 381 ----------- rpc/types_test.go | 204 ------ 22 files changed, 393 insertions(+), 4427 deletions(-) delete mode 100644 cmd/geth/admin.go delete mode 100644 rpc/api.go create mode 100644 rpc/api/args.go rename rpc/{ => api}/args_test.go (99%) delete mode 100644 rpc/api_test.go delete mode 100644 rpc/args.go create mode 100644 rpc/comms/inproc.go delete mode 100644 rpc/http.go delete mode 100644 rpc/responses.go delete mode 100644 rpc/responses_test.go delete mode 100644 rpc/types.go delete mode 100644 rpc/types_test.go diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go deleted file mode 100644 index 33ef69792..000000000 --- a/cmd/geth/admin.go +++ /dev/null @@ -1,937 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "fmt" - "math/big" - "strconv" - "time" - - "github.com/ethereum/ethash" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/common/natspec" - "github.com/ethereum/go-ethereum/common/resolver" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/xeth" - "github.com/robertkrimen/otto" - "gopkg.in/fatih/set.v0" -) - -/* -node admin bindings -*/ - -func (js *jsre) adminBindings() { - ethO, _ := js.re.Get("eth") - eth := ethO.Object() - eth.Set("pendingTransactions", js.pendingTransactions) - eth.Set("resend", js.resend) - eth.Set("sign", js.sign) - - js.re.Set("admin", struct{}{}) - t, _ := js.re.Get("admin") - admin := t.Object() - admin.Set("addPeer", js.addPeer) - admin.Set("startRPC", js.startRPC) - admin.Set("stopRPC", js.stopRPC) - admin.Set("nodeInfo", js.nodeInfo) - admin.Set("peers", js.peers) - admin.Set("newAccount", js.newAccount) - admin.Set("unlock", js.unlock) - admin.Set("import", js.importChain) - admin.Set("export", js.exportChain) - admin.Set("verbosity", js.verbosity) - admin.Set("progress", js.syncProgress) - admin.Set("setSolc", js.setSolc) - - admin.Set("contractInfo", struct{}{}) - t, _ = admin.Get("contractInfo") - cinfo := t.Object() - // newRegistry officially not documented temporary option - cinfo.Set("start", js.startNatSpec) - cinfo.Set("stop", js.stopNatSpec) - cinfo.Set("newRegistry", js.newRegistry) - cinfo.Set("get", js.getContractInfo) - cinfo.Set("register", js.register) - cinfo.Set("registerUrl", js.registerUrl) - // cinfo.Set("verify", js.verify) - - admin.Set("miner", struct{}{}) - t, _ = admin.Get("miner") - miner := t.Object() - miner.Set("start", js.startMining) - miner.Set("stop", js.stopMining) - miner.Set("hashrate", js.hashrate) - miner.Set("setExtra", js.setExtra) - miner.Set("setGasPrice", js.setGasPrice) - miner.Set("startAutoDAG", js.startAutoDAG) - miner.Set("stopAutoDAG", js.stopAutoDAG) - miner.Set("makeDAG", js.makeDAG) - - admin.Set("txPool", struct{}{}) - t, _ = admin.Get("txPool") - txPool := t.Object() - txPool.Set("pending", js.allPendingTransactions) - txPool.Set("queued", js.allQueuedTransactions) - - admin.Set("debug", struct{}{}) - t, _ = admin.Get("debug") - debug := t.Object() - js.re.Set("sleep", js.sleep) - debug.Set("backtrace", js.backtrace) - debug.Set("printBlock", js.printBlock) - debug.Set("dumpBlock", js.dumpBlock) - debug.Set("getBlockRlp", js.getBlockRlp) - debug.Set("setHead", js.setHead) - debug.Set("processBlock", js.debugBlock) - debug.Set("seedhash", js.seedHash) - debug.Set("insertBlock", js.insertBlockRlp) - // undocumented temporary - debug.Set("waitForBlocks", js.waitForBlocks) -} - -// generic helper to getBlock by Number/Height or Hex depending on autodetected input -// if argument is missing the current block is returned -// if block is not found or there is problem with decoding -// the appropriate value is returned and block is guaranteed to be nil -func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) { - var block *types.Block - if len(call.ArgumentList) > 0 { - if call.Argument(0).IsNumber() { - num, _ := call.Argument(0).ToInteger() - block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num)) - } else if call.Argument(0).IsString() { - hash, _ := call.Argument(0).ToString() - block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash)) - } else { - return nil, errors.New("invalid argument for dump. Either hex string or number") - } - } else { - block = js.ethereum.ChainManager().CurrentBlock() - } - - if block == nil { - return nil, errors.New("block not found") - } - return block, nil -} - -func (js *jsre) seedHash(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) > 0 { - if call.Argument(0).IsNumber() { - num, _ := call.Argument(0).ToInteger() - hash, err := ethash.GetSeedHash(uint64(num)) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - v, _ := call.Otto.ToValue(fmt.Sprintf("0x%x", hash)) - return v - } else { - fmt.Println("arg not a number") - } - } else { - fmt.Println("requires number argument") - } - - return otto.UndefinedValue() -} - -func (js *jsre) allPendingTransactions(call otto.FunctionCall) otto.Value { - txs := js.ethereum.TxPool().GetTransactions() - - ltxs := make([]*tx, len(txs)) - for i, tx := range txs { - // no need to check err - ltxs[i] = newTx(tx) - } - - v, _ := call.Otto.ToValue(ltxs) - return v -} - -func (js *jsre) allQueuedTransactions(call otto.FunctionCall) otto.Value { - txs := js.ethereum.TxPool().GetQueuedTransactions() - - ltxs := make([]*tx, len(txs)) - for i, tx := range txs { - // no need to check err - ltxs[i] = newTx(tx) - } - - v, _ := call.Otto.ToValue(ltxs) - return v -} - -func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value { - txs := js.ethereum.TxPool().GetTransactions() - - // grab the accounts from the account manager. This will help with determening which - // transactions should be returned. - accounts, err := js.ethereum.AccountManager().Accounts() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - // Add the accouns to a new set - accountSet := set.New() - for _, account := range accounts { - accountSet.Add(account.Address) - } - - //ltxs := make([]*tx, len(txs)) - var ltxs []*tx - for _, tx := range txs { - if from, _ := tx.From(); accountSet.Has(from) { - ltxs = append(ltxs, newTx(tx)) - } - } - - v, _ := call.Otto.ToValue(ltxs) - return v -} - -func (js *jsre) resend(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) == 0 { - fmt.Println("first argument must be a transaction") - return otto.FalseValue() - } - - v, err := call.Argument(0).Export() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - if tx, ok := v.(*tx); ok { - gl, gp := tx.GasLimit, tx.GasPrice - if len(call.ArgumentList) > 1 { - gp = call.Argument(1).String() - } - if len(call.ArgumentList) > 2 { - gl = call.Argument(2).String() - } - - ret, err := js.xeth.Transact(tx.From, tx.To, tx.Nonce, tx.Value, gl, gp, tx.Data) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - js.ethereum.TxPool().RemoveTransactions(types.Transactions{tx.tx}) - - v, _ := call.Otto.ToValue(ret) - return v - } - - fmt.Println("first argument must be a transaction") - return otto.FalseValue() -} - -func (js *jsre) sign(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) != 2 { - fmt.Println("requires 2 arguments: eth.sign(signer, data)") - return otto.UndefinedValue() - } - signer, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - data, err := call.Argument(1).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - signed, err := js.xeth.Sign(signer, data, false) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - v, _ := call.Otto.ToValue(signed) - return v -} - -func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value { - block, err := js.getBlock(call) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - tstart := time.Now() - old := vm.Debug - - if len(call.ArgumentList) > 1 { - vm.Debug, _ = call.Argument(1).ToBoolean() - } - - _, err = js.ethereum.BlockProcessor().RetryProcess(block) - if err != nil { - fmt.Println(err) - r, _ := call.Otto.ToValue(map[string]interface{}{"success": false, "time": time.Since(tstart).Seconds()}) - return r - } - vm.Debug = old - - r, _ := call.Otto.ToValue(map[string]interface{}{"success": true, "time": time.Since(tstart).Seconds()}) - return r -} - -func (js *jsre) insertBlockRlp(call otto.FunctionCall) otto.Value { - tstart := time.Now() - - var block types.Block - if call.Argument(0).IsString() { - blockRlp, _ := call.Argument(0).ToString() - err := rlp.DecodeBytes(common.Hex2Bytes(blockRlp), &block) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - } - - old := vm.Debug - vm.Debug = true - _, err := js.ethereum.BlockProcessor().RetryProcess(&block) - if err != nil { - fmt.Println(err) - r, _ := call.Otto.ToValue(map[string]interface{}{"success": false, "time": time.Since(tstart).Seconds()}) - return r - } - vm.Debug = old - - r, _ := call.Otto.ToValue(map[string]interface{}{"success": true, "time": time.Since(tstart).Seconds()}) - return r -} - -func (js *jsre) setHead(call otto.FunctionCall) otto.Value { - block, err := js.getBlock(call) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - js.ethereum.ChainManager().SetHead(block) - return otto.UndefinedValue() -} - -func (js *jsre) syncProgress(call otto.FunctionCall) otto.Value { - pending, cached, importing, eta := js.ethereum.Downloader().Stats() - v, _ := call.Otto.ToValue(map[string]interface{}{ - "pending": pending, - "cached": cached, - "importing": importing, - "estimate": (eta / time.Second * time.Second).String(), - }) - return v -} - -func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value { - block, err := js.getBlock(call) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - encoded, _ := rlp.EncodeToBytes(block) - v, _ := call.Otto.ToValue(fmt.Sprintf("%x", encoded)) - return v -} - -func (js *jsre) setExtra(call otto.FunctionCall) otto.Value { - extra, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - if len(extra) > 1024 { - fmt.Println("error: cannot exceed 1024 bytes") - return otto.UndefinedValue() - } - - js.ethereum.Miner().SetExtra([]byte(extra)) - return otto.UndefinedValue() -} - -func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value { - gasPrice, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - js.ethereum.Miner().SetGasPrice(common.String2Big(gasPrice)) - return otto.UndefinedValue() -} - -func (js *jsre) hashrate(call otto.FunctionCall) otto.Value { - v, _ := call.Otto.ToValue(js.ethereum.Miner().HashRate()) - return v -} - -func (js *jsre) makeDAG(call otto.FunctionCall) otto.Value { - blockNumber, err := call.Argument(1).ToInteger() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - err = ethash.MakeDAG(uint64(blockNumber), "") - if err != nil { - return otto.FalseValue() - } - return otto.TrueValue() -} - -func (js *jsre) startAutoDAG(otto.FunctionCall) otto.Value { - js.ethereum.StartAutoDAG() - return otto.TrueValue() -} - -func (js *jsre) stopAutoDAG(otto.FunctionCall) otto.Value { - js.ethereum.StopAutoDAG() - return otto.TrueValue() -} - -func (js *jsre) backtrace(call otto.FunctionCall) otto.Value { - tracestr, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - glog.GetTraceLocation().Set(tracestr) - - return otto.UndefinedValue() -} - -func (js *jsre) verbosity(call otto.FunctionCall) otto.Value { - v, err := call.Argument(0).ToInteger() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - glog.SetV(int(v)) - return otto.UndefinedValue() -} - -func (js *jsre) startMining(call otto.FunctionCall) otto.Value { - var ( - threads int64 - err error - ) - - if len(call.ArgumentList) > 0 { - threads, err = call.Argument(0).ToInteger() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - } else { - threads = int64(js.ethereum.MinerThreads) - } - - // switch on DAG autogeneration when miner starts - js.ethereum.StartAutoDAG() - - err = js.ethereum.StartMining(int(threads)) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - return otto.TrueValue() -} - -func (js *jsre) stopMining(call otto.FunctionCall) otto.Value { - js.ethereum.StopMining() - js.ethereum.StopAutoDAG() - return otto.TrueValue() -} - -func (js *jsre) startRPC(call otto.FunctionCall) otto.Value { - addr, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - port, err := call.Argument(1).ToInteger() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - corsDomain := js.corsDomain - if len(call.ArgumentList) > 2 { - corsDomain, err = call.Argument(2).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - } - - config := rpc.RpcConfig{ - ListenAddress: addr, - ListenPort: uint(port), - CorsDomain: corsDomain, - } - - xeth := xeth.New(js.ethereum, nil) - err = rpc.Start(xeth, config) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - return otto.TrueValue() -} - -func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value { - if rpc.Stop() == nil { - return otto.TrueValue() - } - return otto.FalseValue() -} - -func (js *jsre) addPeer(call otto.FunctionCall) otto.Value { - nodeURL, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - err = js.ethereum.AddPeer(nodeURL) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - return otto.TrueValue() -} - -func (js *jsre) unlock(call otto.FunctionCall) otto.Value { - addr, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - seconds, err := call.Argument(2).ToInteger() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - if seconds == 0 { - seconds = accounts.DefaultAccountUnlockDuration - } - - arg := call.Argument(1) - var passphrase string - if arg.IsUndefined() { - fmt.Println("Please enter a passphrase now.") - passphrase, err = utils.PromptPassword("Passphrase: ", true) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - } else { - passphrase, err = arg.ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - } - am := js.ethereum.AccountManager() - err = am.TimedUnlock(common.HexToAddress(addr), passphrase, time.Duration(seconds)*time.Second) - if err != nil { - fmt.Printf("Unlock account failed '%v'\n", err) - return otto.FalseValue() - } - return otto.TrueValue() -} - -func (js *jsre) newAccount(call otto.FunctionCall) otto.Value { - arg := call.Argument(0) - var passphrase string - if arg.IsUndefined() { - fmt.Println("The new account will be encrypted with a passphrase.") - fmt.Println("Please enter a passphrase now.") - auth, err := utils.PromptPassword("Passphrase: ", true) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - confirm, err := utils.PromptPassword("Repeat Passphrase: ", false) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - if auth != confirm { - fmt.Println("Passphrases did not match.") - return otto.FalseValue() - } - passphrase = auth - } else { - var err error - passphrase, err = arg.ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - } - acct, err := js.ethereum.AccountManager().NewAccount(passphrase) - if err != nil { - fmt.Printf("Could not create the account: %v", err) - return otto.UndefinedValue() - } - v, _ := call.Otto.ToValue(acct.Address.Hex()) - return v -} - -func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value { - v, _ := call.Otto.ToValue(js.ethereum.NodeInfo()) - return v -} - -func (js *jsre) peers(call otto.FunctionCall) otto.Value { - v, _ := call.Otto.ToValue(js.ethereum.PeersInfo()) - return v -} - -func (js *jsre) importChain(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) == 0 { - fmt.Println("require file name. admin.importChain(filename)") - return otto.FalseValue() - } - fn, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - if err := utils.ImportChain(js.ethereum.ChainManager(), fn); err != nil { - fmt.Println("Import error: ", err) - return otto.FalseValue() - } - return otto.TrueValue() -} - -func (js *jsre) exportChain(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) == 0 { - fmt.Println("require file name: admin.exportChain(filename)") - return otto.FalseValue() - } - - fn, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil { - fmt.Println(err) - return otto.FalseValue() - } - return otto.TrueValue() -} - -func (js *jsre) printBlock(call otto.FunctionCall) otto.Value { - block, err := js.getBlock(call) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - fmt.Println(block) - - return otto.UndefinedValue() -} - -func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value { - block, err := js.getBlock(call) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - statedb := state.New(block.Root(), js.ethereum.StateDb()) - dump := statedb.RawDump() - v, _ := call.Otto.ToValue(dump) - return v -} - -func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) > 2 { - fmt.Println("requires 0, 1 or 2 arguments: admin.debug.waitForBlock(minHeight, timeout)") - return otto.FalseValue() - } - var n, timeout int64 - var timer <-chan time.Time - var height *big.Int - var err error - args := len(call.ArgumentList) - if args == 2 { - timeout, err = call.Argument(1).ToInteger() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - timer = time.NewTimer(time.Duration(timeout) * time.Second).C - } - if args >= 1 { - n, err = call.Argument(0).ToInteger() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - height = big.NewInt(n) - } - - if args == 0 { - height = js.xeth.CurrentBlock().Number() - height.Add(height, common.Big1) - } - - wait := js.wait - js.wait <- height - select { - case <-timer: - // if times out make sure the xeth loop does not block - go func() { - select { - case wait <- nil: - case <-wait: - } - }() - return otto.UndefinedValue() - case height = <-wait: - } - v, _ := call.Otto.ToValue(height.Uint64()) - return v -} - -func (js *jsre) sleep(call otto.FunctionCall) otto.Value { - sec, err := call.Argument(0).ToInteger() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - time.Sleep(time.Duration(sec) * time.Second) - return otto.UndefinedValue() -} - -func (js *jsre) setSolc(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) != 1 { - fmt.Println("needs 1 argument: admin.contractInfo.setSolc(solcPath)") - return otto.FalseValue() - } - solcPath, err := call.Argument(0).ToString() - if err != nil { - return otto.FalseValue() - } - solc, err := js.xeth.SetSolc(solcPath) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - fmt.Println(solc.Info()) - return otto.TrueValue() -} - -func (js *jsre) register(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) != 4 { - fmt.Println("requires 4 arguments: admin.contractInfo.register(fromaddress, contractaddress, contract, filename)") - return otto.UndefinedValue() - } - sender, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - address, err := call.Argument(1).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - raw, err := call.Argument(2).Export() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - jsonraw, err := json.Marshal(raw) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - var contract compiler.Contract - err = json.Unmarshal(jsonraw, &contract) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - filename, err := call.Argument(3).ToString() - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - contenthash, err := compiler.ExtractInfo(&contract, filename) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - // sender and contract address are passed as hex strings - codeb := js.xeth.CodeAtBytes(address) - codehash := common.BytesToHash(crypto.Sha3(codeb)) - - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - registry := resolver.New(js.xeth) - - _, err = registry.RegisterContentHash(common.HexToAddress(sender), codehash, contenthash) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - - v, _ := call.Otto.ToValue(contenthash.Hex()) - return v -} - -func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) != 3 { - fmt.Println("requires 3 arguments: admin.contractInfo.register(fromaddress, contenthash, filename)") - return otto.FalseValue() - } - sender, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - contenthash, err := call.Argument(1).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - url, err := call.Argument(2).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - registry := resolver.New(js.xeth) - - _, err = registry.RegisterUrl(common.HexToAddress(sender), common.HexToHash(contenthash), url) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - return otto.TrueValue() -} - -func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value { - if len(call.ArgumentList) != 1 { - fmt.Println("requires 1 argument: admin.contractInfo.register(contractaddress)") - return otto.FalseValue() - } - addr, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - infoDoc, err := natspec.FetchDocsForContract(addr, js.xeth, ds) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - var info compiler.ContractInfo - err = json.Unmarshal(infoDoc, &info) - if err != nil { - fmt.Println(err) - return otto.UndefinedValue() - } - v, _ := call.Otto.ToValue(info) - return v -} - -func (js *jsre) startNatSpec(call otto.FunctionCall) otto.Value { - js.ethereum.NatSpec = true - return otto.TrueValue() -} - -func (js *jsre) stopNatSpec(call otto.FunctionCall) otto.Value { - js.ethereum.NatSpec = false - return otto.TrueValue() -} - -func (js *jsre) newRegistry(call otto.FunctionCall) otto.Value { - - if len(call.ArgumentList) != 1 { - fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)") - return otto.FalseValue() - } - addr, err := call.Argument(0).ToString() - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - registry := resolver.New(js.xeth) - err = registry.CreateContracts(common.HexToAddress(addr)) - if err != nil { - fmt.Println(err) - return otto.FalseValue() - } - - return otto.TrueValue() -} - -// internal transaction type which will allow us to resend transactions using `eth.resend` -type tx struct { - tx *types.Transaction - - To string - From string - Nonce string - Value string - Data string - GasLimit string - GasPrice string -} - -func newTx(t *types.Transaction) *tx { - from, _ := t.From() - var to string - if t := t.To(); t != nil { - to = t.Hex() - } - - return &tx{ - tx: t, - To: to, - From: from.Hex(), - Value: t.Amount.String(), - Nonce: strconv.Itoa(int(t.Nonce())), - Data: "0x" + common.Bytes2Hex(t.Data()), - GasLimit: t.GasLimit.String(), - GasPrice: t.GasPrice().String(), - } -} diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 7e6e10ca9..2ae4817b3 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -33,6 +33,10 @@ import ( "github.com/ethereum/go-ethereum/eth" re "github.com/ethereum/go-ethereum/jsre" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/comms" + "github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/xeth" "github.com/peterh/liner" "github.com/robertkrimen/otto" @@ -70,10 +74,70 @@ type jsre struct { ps1 string atexit func() corsDomain string + client comms.EthereumClient prompter } -func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, interactive bool, f xeth.Frontend) *jsre { +var ( + loadedModulesMethods map[string][]string +) + +func keywordCompleter(line string) []string { + results := make([]string, 0) + + if strings.Contains(line, ".") { + elements := strings.Split(line, ".") + if len(elements) == 2 { + module := elements[0] + partialMethod := elements[1] + if methods, found := loadedModulesMethods[module]; found { + for _, method := range methods { + if strings.HasPrefix(method, partialMethod) { // e.g. debug.se + results = append(results, module+"."+method) + } + } + } + } + } else { + for module, methods := range loadedModulesMethods { + if line == module { // user typed in full module name, show all methods + for _, method := range methods { + results = append(results, module+"."+method) + } + } else if strings.HasPrefix(module, line) { // partial method name, e.g. admi + results = append(results, module) + } + } + } + return results +} + +func apiWordCompleter(line string, pos int) (head string, completions []string, tail string) { + if len(line) == 0 { + return "", nil, "" + } + + i := 0 + for i = pos - 1; i > 0; i-- { + if line[i] == '.' || (line[i] >= 'a' && line[i] <= 'z') || (line[i] >= 'A' && line[i] <= 'Z') { + continue + } + if i >= 3 && line[i] == '3' && line[i-3] == 'w' && line[i-2] == 'e' && line[i-1] == 'b' { + continue + } + i += 1 + break + } + + begin := line[:i] + keyword := line[i:pos] + end := line[pos:] + + completionWords := keywordCompleter(keyword) + return begin, completionWords, end +} + +func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre { js := &jsre{ethereum: ethereum, ps1: "> "} // set default cors domain used by startRpc from CLI flag js.corsDomain = corsDomain @@ -82,10 +146,16 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, intera } js.xeth = xeth.New(ethereum, f) js.wait = js.xeth.UpdateState() + js.client = client + if clt, ok := js.client.(*comms.InProcClient); ok { + clt.Initialize(js.xeth, ethereum) + } + // update state in separare forever blocks js.re = re.New(libPath) - js.apiBindings(ipcpath, f) - js.adminBindings() + if err := js.apiBindings(f); err != nil { + utils.Fatalf("Unable to connect - %v", err) + } if !liner.TerminalSupported() || !interactive { js.prompter = dumbterm{bufio.NewReader(os.Stdin)} @@ -93,6 +163,9 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, intera lr := liner.NewLiner() js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) }) lr.SetCtrlCAborts(true) + js.loadAutoCompletion() + lr.SetWordCompleter(apiWordCompleter) + lr.SetTabCompletionStyle(liner.TabPrints) js.prompter = lr js.atexit = func() { js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) }) @@ -103,8 +176,117 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, intera return js } +func (self *jsre) loadAutoCompletion() { + if modules, err := self.suportedApis(); err == nil { + loadedModulesMethods = make(map[string][]string) + for module, _ := range modules { + loadedModulesMethods[module] = api.AutoCompletion[module] + } + } +} + +func (self *jsre) suportedApis() (map[string]string, error) { + req := shared.Request{ + Id: 1, + Jsonrpc: "2.0", + Method: "modules", + } + + err := self.client.Send(&req) + if err != nil { + return nil, err + } + + res, err := self.client.Recv() + if err != nil { + return nil, err + } + + if sucRes, ok := res.(map[string]string); ok { + if err == nil { + return sucRes, nil + } + } + + return nil, fmt.Errorf("Unable to determine supported API's") +} + +func (js *jsre) apiBindings(f xeth.Frontend) error { + apis, err := js.suportedApis() + if err != nil { + return err + } + + apiNames := make([]string, 0, len(apis)) + for a, _ := range apis { + apiNames = append(apiNames, a) + } + + apiImpl, err := api.ParseApiString(strings.Join(apiNames, ","), codec.JSON, js.xeth, js.ethereum) + if err != nil { + utils.Fatalf("Unable to determine supported api's: %v", err) + } + + jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client) + js.re.Set("jeth", struct{}{}) + t, _ := js.re.Get("jeth") + jethObj := t.Object() + + jethObj.Set("send", jeth.Send) + jethObj.Set("sendAsync", jeth.Send) + + err = js.re.Compile("bignumber.js", re.BigNumber_JS) + if err != nil { + utils.Fatalf("Error loading bignumber.js: %v", err) + } + + err = js.re.Compile("ethereum.js", re.Web3_JS) + if err != nil { + utils.Fatalf("Error loading web3.js: %v", err) + } + + _, err = js.re.Eval("var web3 = require('web3');") + if err != nil { + utils.Fatalf("Error requiring web3: %v", err) + } + + _, err = js.re.Eval("web3.setProvider(jeth)") + if err != nil { + utils.Fatalf("Error setting web3 provider: %v", err) + } + + // load only supported API's in javascript runtime + shortcuts := "var eth = web3.eth; " + for _, apiName := range apiNames { + if apiName == api.Web3ApiName || apiName == api.EthApiName { + continue // manually mapped + } + + if err = js.re.Compile(fmt.Sprintf("%s.js", apiName), api.Javascript(apiName)); err == nil { + shortcuts += fmt.Sprintf("var %s = web3.%s; ", apiName, apiName) + } else { + utils.Fatalf("Error loading %s.js: %v", apiName, err) + } + } + + _, err = js.re.Eval(shortcuts) + + if err != nil { + utils.Fatalf("Error setting namespaces: %v", err) + } + + js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");") + return nil +} + +/* func (js *jsre) apiBindings(ipcpath string, f xeth.Frontend) { xe := xeth.New(js.ethereum, f) + apiNames, err := js.suportedApis(ipcpath) + if err != nil { + return + } + ethApi := rpc.NewEthereumApi(xe) jeth := rpc.NewJeth(ethApi, js.re, ipcpath) @@ -146,6 +328,7 @@ var net = web3.net; js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");") } +*/ var ds, _ = docserver.New("/") diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 43e45f6cc..5c4c33cea 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -38,6 +38,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/comms" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" ) @@ -310,12 +312,14 @@ func console(ctx *cli.Context) { utils.Fatalf("%v", err) } + client := comms.NewInProcClient(codec.JSON) + startEth(ctx, ethereum) repl := newJSRE( ethereum, ctx.String(utils.JSpathFlag.Name), ctx.GlobalString(utils.RPCCORSDomainFlag.Name), - utils.IpcSocketPath(ctx), + client, true, nil, ) @@ -332,12 +336,13 @@ func execJSFiles(ctx *cli.Context) { utils.Fatalf("%v", err) } + client := comms.NewInProcClient(codec.JSON) startEth(ctx, ethereum) repl := newJSRE( ethereum, ctx.String(utils.JSpathFlag.Name), ctx.GlobalString(utils.RPCCORSDomainFlag.Name), - utils.IpcSocketPath(ctx), + client, false, nil, ) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e0eefb3e3..092bc5511 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -211,7 +211,7 @@ var ( RpcApiFlag = cli.StringFlag{ Name: "rpcapi", Usage: "Specify the API's which are offered over the HTTP RPC interface", - Value: api.DefaultHttpRpcApis, + Value: comms.DefaultHttpRpcApis, } IPCDisabledFlag = cli.BoolFlag{ Name: "ipcdisable", @@ -220,7 +220,7 @@ var ( IPCApiFlag = cli.StringFlag{ Name: "ipcapi", Usage: "Specify the API's which are offered over the IPC interface", - Value: api.DefaultIpcApis, + Value: comms.DefaultIpcApis, } IPCPathFlag = DirectoryFlag{ Name: "ipcpath", diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 5ebe3576b..34a1733d7 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -149,7 +149,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error { return ErrInvalidSender } - // Make sure the account exist. Non existant accounts + // Make sure the account exist. Non existent accounts // haven't got funds and well therefor never pass. if !pool.currentState().HasAccount(from) { return ErrNonExistentAccount diff --git a/rpc/api.go b/rpc/api.go deleted file mode 100644 index a344a8294..000000000 --- a/rpc/api.go +++ /dev/null @@ -1,646 +0,0 @@ -package rpc - -import ( - "bytes" - "encoding/json" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/xeth" -) - -type EthereumApi struct { - eth *xeth.XEth -} - -func NewEthereumApi(xeth *xeth.XEth) *EthereumApi { - api := &EthereumApi{ - eth: xeth, - } - - return api -} - -func (api *EthereumApi) xeth() *xeth.XEth { - return api.eth -} - -func (api *EthereumApi) xethAtStateNum(num int64) *xeth.XEth { - return api.xeth().AtStateNum(num) -} - -func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { - // Spec at https://github.com/ethereum/wiki/wiki/JSON-RPC - glog.V(logger.Debug).Infof("%s %s", req.Method, req.Params) - - switch req.Method { - case "web3_sha3": - args := new(Sha3Args) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = common.ToHex(crypto.Sha3(common.FromHex(args.Data))) - case "web3_clientVersion": - *reply = api.xeth().ClientVersion() - case "net_version": - *reply = api.xeth().NetworkVersion() - case "net_listening": - *reply = api.xeth().IsListening() - case "net_peerCount": - *reply = newHexNum(api.xeth().PeerCount()) - case "eth_protocolVersion": - *reply = api.xeth().EthVersion() - case "eth_coinbase": - *reply = newHexData(api.xeth().Coinbase()) - case "eth_mining": - *reply = api.xeth().IsMining() - case "eth_gasPrice": - v := api.xeth().DefaultGasPrice() - *reply = newHexNum(v.Bytes()) - case "eth_accounts": - *reply = api.xeth().Accounts() - case "eth_blockNumber": - v := api.xeth().CurrentBlock().Number() - *reply = newHexNum(v.Bytes()) - case "eth_getBalance": - args := new(GetBalanceArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - *reply = api.xethAtStateNum(args.BlockNumber).BalanceAt(args.Address) - //v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance() - //*reply = common.ToHex(v.Bytes()) - case "eth_getStorage", "eth_storageAt": - args := new(GetStorageArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - *reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() - case "eth_getStorageAt": - args := new(GetStorageAtArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - *reply = api.xethAtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key) - case "eth_getTransactionCount": - args := new(GetTxCountArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address) - *reply = newHexNum(big.NewInt(int64(count)).Bytes()) - case "eth_getBlockTransactionCountByHash": - args := new(HashArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false) - if block == nil { - *reply = nil - } else { - *reply = newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes()) - } - case "eth_getBlockTransactionCountByNumber": - args := new(BlockNumArg) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := NewBlockRes(api.xeth().EthBlockByNumber(args.BlockNumber), false) - if block == nil { - *reply = nil - break - } - - *reply = newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes()) - case "eth_getUncleCountByBlockHash": - args := new(HashArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByHash(args.Hash) - br := NewBlockRes(block, false) - if br == nil { - *reply = nil - break - } - - *reply = newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()) - case "eth_getUncleCountByBlockNumber": - args := new(BlockNumArg) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByNumber(args.BlockNumber) - br := NewBlockRes(block, false) - if br == nil { - *reply = nil - break - } - - *reply = newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()) - - case "eth_getData", "eth_getCode": - args := new(GetDataArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - v := api.xethAtStateNum(args.BlockNumber).CodeAtBytes(args.Address) - *reply = newHexData(v) - - case "eth_sign": - args := new(NewSigArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - v, err := api.xeth().Sign(args.From, args.Data, false) - if err != nil { - return err - } - *reply = v - - case "eth_sendRawTransaction": - args := new(NewDataArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - v, err := api.xeth().PushTx(args.Data) - if err != nil { - return err - } - *reply = v - - case "eth_sendTransaction", "eth_transact": - args := new(NewTxArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - // nonce may be nil ("guess" mode) - var nonce string - if args.Nonce != nil { - nonce = args.Nonce.String() - } - - var gas string - if args.Gas == nil { - gas = "" - } else { - gas = args.Gas.String() - } - - var gasprice string - if args.GasPrice == nil { - gasprice = "" - } else { - gasprice = args.GasPrice.String() - } - - v, err := api.xeth().Transact(args.From, args.To, nonce, args.Value.String(), gas, gasprice, args.Data) - if err != nil { - return err - } - *reply = v - case "eth_estimateGas": - _, gas, err := api.doCall(req.Params) - if err != nil { - return err - } - - // TODO unwrap the parent method's ToHex call - if len(gas) == 0 { - *reply = newHexNum(0) - } else { - *reply = newHexNum(gas) - } - case "eth_call": - v, _, err := api.doCall(req.Params) - if err != nil { - return err - } - - // TODO unwrap the parent method's ToHex call - if v == "0x0" { - *reply = newHexData([]byte{}) - } else { - *reply = newHexData(common.FromHex(v)) - } - case "eth_flush": - return NewNotImplementedError(req.Method) - case "eth_getBlockByHash": - args := new(GetBlockByHashArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByHash(args.BlockHash) - br := NewBlockRes(block, args.IncludeTxs) - - *reply = br - case "eth_getBlockByNumber": - args := new(GetBlockByNumberArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByNumber(args.BlockNumber) - br := NewBlockRes(block, args.IncludeTxs) - // If request was for "pending", nil nonsensical fields - if args.BlockNumber == -2 { - br.BlockHash = nil - br.BlockNumber = nil - br.Miner = nil - br.Nonce = nil - br.LogsBloom = nil - } - *reply = br - case "eth_getTransactionByHash": - args := new(HashArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - tx, bhash, bnum, txi := api.xeth().EthTransactionByHash(args.Hash) - if tx != nil { - v := NewTransactionRes(tx) - // if the blockhash is 0, assume this is a pending transaction - if bytes.Compare(bhash.Bytes(), bytes.Repeat([]byte{0}, 32)) != 0 { - v.BlockHash = newHexData(bhash) - v.BlockNumber = newHexNum(bnum) - v.TxIndex = newHexNum(txi) - } - *reply = v - } - case "eth_getTransactionByBlockHashAndIndex": - args := new(HashIndexArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByHash(args.Hash) - br := NewBlockRes(block, true) - if br == nil { - *reply = nil - break - } - - if args.Index >= int64(len(br.Transactions)) || args.Index < 0 { - // return NewValidationError("Index", "does not exist") - *reply = nil - } else { - *reply = br.Transactions[args.Index] - } - case "eth_getTransactionByBlockNumberAndIndex": - args := new(BlockNumIndexArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByNumber(args.BlockNumber) - v := NewBlockRes(block, true) - if v == nil { - *reply = nil - break - } - - if args.Index >= int64(len(v.Transactions)) || args.Index < 0 { - // return NewValidationError("Index", "does not exist") - *reply = nil - } else { - *reply = v.Transactions[args.Index] - } - case "eth_getUncleByBlockHashAndIndex": - args := new(HashIndexArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false) - if br == nil { - *reply = nil - return nil - } - - if args.Index >= int64(len(br.Uncles)) || args.Index < 0 { - // return NewValidationError("Index", "does not exist") - *reply = nil - } else { - *reply = br.Uncles[args.Index] - } - case "eth_getUncleByBlockNumberAndIndex": - args := new(BlockNumIndexArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - block := api.xeth().EthBlockByNumber(args.BlockNumber) - v := NewBlockRes(block, true) - - if v == nil { - *reply = nil - return nil - } - - if args.Index >= int64(len(v.Uncles)) || args.Index < 0 { - // return NewValidationError("Index", "does not exist") - *reply = nil - } else { - *reply = v.Uncles[args.Index] - } - - case "eth_getCompilers": - var lang string - if solc, _ := api.xeth().Solc(); solc != nil { - lang = "Solidity" - } - c := []string{lang} - *reply = c - - case "eth_compileLLL", "eth_compileSerpent": - return NewNotImplementedError(req.Method) - - case "eth_compileSolidity": - solc, _ := api.xeth().Solc() - if solc == nil { - return NewNotAvailableError(req.Method, "solc (solidity compiler) not found") - } - - args := new(SourceArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - contracts, err := solc.Compile(args.Source) - if err != nil { - return err - } - *reply = contracts - - case "eth_newFilter": - args := new(BlockFilterArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - id := api.xeth().NewLogFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics) - *reply = newHexNum(big.NewInt(int64(id)).Bytes()) - - case "eth_newBlockFilter": - *reply = newHexNum(api.xeth().NewBlockFilter()) - case "eth_newPendingTransactionFilter": - *reply = newHexNum(api.xeth().NewTransactionFilter()) - case "eth_uninstallFilter": - args := new(FilterIdArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = api.xeth().UninstallFilter(args.Id) - case "eth_getFilterChanges": - args := new(FilterIdArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - switch api.xeth().GetFilterType(args.Id) { - case xeth.BlockFilterTy: - *reply = NewHashesRes(api.xeth().BlockFilterChanged(args.Id)) - case xeth.TransactionFilterTy: - *reply = NewHashesRes(api.xeth().TransactionFilterChanged(args.Id)) - case xeth.LogFilterTy: - *reply = NewLogsRes(api.xeth().LogFilterChanged(args.Id)) - default: - *reply = []string{} // reply empty string slice - } - case "eth_getFilterLogs": - args := new(FilterIdArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = NewLogsRes(api.xeth().Logs(args.Id)) - case "eth_getLogs": - args := new(BlockFilterArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = NewLogsRes(api.xeth().AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)) - case "eth_getWork": - api.xeth().SetMining(true, 0) - *reply = api.xeth().RemoteMining().GetWork() - case "eth_submitWork": - args := new(SubmitWorkArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header)) - case "db_putString": - args := new(DbArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - if err := args.requirements(); err != nil { - return err - } - - api.xeth().DbPut([]byte(args.Database+args.Key), args.Value) - - *reply = true - case "db_getString": - args := new(DbArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - if err := args.requirements(); err != nil { - return err - } - - res, _ := api.xeth().DbGet([]byte(args.Database + args.Key)) - *reply = string(res) - case "db_putHex": - args := new(DbHexArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - if err := args.requirements(); err != nil { - return err - } - - api.xeth().DbPut([]byte(args.Database+args.Key), args.Value) - *reply = true - case "db_getHex": - args := new(DbHexArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - if err := args.requirements(); err != nil { - return err - } - - res, _ := api.xeth().DbGet([]byte(args.Database + args.Key)) - *reply = newHexData(res) - - case "shh_version": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Retrieves the currently running whisper protocol version - *reply = api.xeth().WhisperVersion() - - case "shh_post": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Injects a new message into the whisper network - args := new(WhisperMessageArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - err := api.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl) - if err != nil { - return err - } - *reply = true - - case "shh_newIdentity": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Creates a new whisper identity to use for sending/receiving messages - *reply = api.xeth().Whisper().NewIdentity() - - case "shh_hasIdentity": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Checks if an identity if owned or not - args := new(WhisperIdentityArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = api.xeth().Whisper().HasIdentity(args.Identity) - - case "shh_newFilter": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Create a new filter to watch and match messages with - args := new(WhisperFilterArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - id := api.xeth().NewWhisperFilter(args.To, args.From, args.Topics) - *reply = newHexNum(big.NewInt(int64(id)).Bytes()) - - case "shh_uninstallFilter": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Remove an existing filter watching messages - args := new(FilterIdArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = api.xeth().UninstallWhisperFilter(args.Id) - - case "shh_getFilterChanges": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Retrieve all the new messages arrived since the last request - args := new(FilterIdArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = api.xeth().WhisperMessagesChanged(args.Id) - - case "shh_getMessages": - // Short circuit if whisper is not running - if api.xeth().Whisper() == nil { - return NewNotAvailableError(req.Method, "whisper offline") - } - // Retrieve all the cached messages matching a specific, existing filter - args := new(FilterIdArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - *reply = api.xeth().WhisperMessages(args.Id) - - case "eth_hashrate": - *reply = newHexNum(api.xeth().HashRate()) - case "ext_disasm": - args := new(SourceArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return err - } - - *reply = vm.Disasm(common.FromHex(args.Source)) - - // case "eth_register": - // // Placeholder for actual type - // args := new(HashIndexArgs) - // if err := json.Unmarshal(req.Params, &args); err != nil { - // return err - // } - // *reply = api.xeth().Register(args.Hash) - // case "eth_unregister": - // args := new(HashIndexArgs) - // if err := json.Unmarshal(req.Params, &args); err != nil { - // return err - // } - // *reply = api.xeth().Unregister(args.Hash) - // case "eth_watchTx": - // args := new(HashIndexArgs) - // if err := json.Unmarshal(req.Params, &args); err != nil { - // return err - // } - // *reply = api.xeth().PullWatchTx(args.Hash) - default: - return NewNotImplementedError(req.Method) - } - - // glog.V(logger.Detail).Infof("Reply: %v\n", reply) - return nil -} - -func (api *EthereumApi) doCall(params json.RawMessage) (string, string, error) { - args := new(CallArgs) - if err := json.Unmarshal(params, &args); err != nil { - return "", "", err - } - - var gas string - if args.Gas == nil { - gas = "" - } else { - gas = args.Gas.String() - } - - var gasprice string - if args.GasPrice == nil { - gasprice = "" - } else { - gasprice = args.GasPrice.String() - } - - return api.xethAtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), gas, gasprice, args.Data) -} diff --git a/rpc/api/api.go b/rpc/api/api.go index 7fc22a263..10b448594 100644 --- a/rpc/api/api.go +++ b/rpc/api/api.go @@ -18,15 +18,13 @@ const ( TxPoolApiName = "txpool" PersonalApiName = "personal" Web3ApiName = "web3" + + JsonRpcVersion = "2.0" ) var ( - DefaultHttpRpcApis = strings.Join([]string{ - DbApiName, EthApiName, NetApiName, Web3ApiName, - }, ",") - - // List with all API's which are offered over the IPC interface by default - DefaultIpcApis = strings.Join([]string{ + // All API's + AllApis = strings.Join([]string{ AdminApiName, DbApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName, }, ",") diff --git a/rpc/api/args.go b/rpc/api/args.go new file mode 100644 index 000000000..4ef1b26e7 --- /dev/null +++ b/rpc/api/args.go @@ -0,0 +1,57 @@ +package api + +import ( + "encoding/json" + "github.com/ethereum/go-ethereum/rpc/shared" +) + +type CompileArgs struct { + Source string +} + +func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + argstr, ok := obj[0].(string) + if !ok { + return shared.NewInvalidTypeError("arg0", "is not a string") + } + args.Source = argstr + + return nil +} + +type FilterStringArgs struct { + Word string +} + +func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + + var argstr string + argstr, ok := obj[0].(string) + if !ok { + return shared.NewInvalidTypeError("filter", "not a string") + } + switch argstr { + case "latest", "pending": + break + default: + return shared.NewValidationError("Word", "Must be `latest` or `pending`") + } + args.Word = argstr + return nil +} \ No newline at end of file diff --git a/rpc/args_test.go b/rpc/api/args_test.go similarity index 99% rename from rpc/args_test.go rename to rpc/api/args_test.go index fd20dbab8..4153d5432 100644 --- a/rpc/args_test.go +++ b/rpc/api/args_test.go @@ -1,4 +1,4 @@ -package rpc +package api import ( "bytes" @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "testing" + "github.com/ethereum/go-ethereum/rpc/shared" ) func TestBlockheightInvalidString(t *testing.T) { @@ -68,7 +69,7 @@ func ExpectValidationError(err error) string { switch err.(type) { case nil: str = "Expected error but didn't get one" - case *ValidationError: + case *shared.ValidationError: break default: str = fmt.Sprintf("Expected *rpc.ValidationError but got %T with message `%s`", err, err.Error()) @@ -81,7 +82,7 @@ func ExpectInvalidTypeError(err error) string { switch err.(type) { case nil: str = "Expected error but didn't get one" - case *InvalidTypeError: + case *shared.InvalidTypeError: break default: str = fmt.Sprintf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) @@ -94,7 +95,7 @@ func ExpectInsufficientParamsError(err error) string { switch err.(type) { case nil: str = "Expected error but didn't get one" - case *InsufficientParamsError: + case *shared.InsufficientParamsError: break default: str = fmt.Sprintf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) @@ -107,7 +108,7 @@ func ExpectDecodeParamError(err error) string { switch err.(type) { case nil: str = "Expected error but didn't get one" - case *DecodeParamError: + case *shared.DecodeParamError: break default: str = fmt.Sprintf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) diff --git a/rpc/api_test.go b/rpc/api_test.go deleted file mode 100644 index c3546e98f..000000000 --- a/rpc/api_test.go +++ /dev/null @@ -1,205 +0,0 @@ -package rpc - -import ( - "encoding/json" - "strconv" - "testing" - - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/xeth" -) - -func TestWeb3Sha3(t *testing.T) { - jsonstr := `{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f20776f726c64"],"id":64}` - expected := "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad" - - api := &EthereumApi{} - - var req RpcRequest - json.Unmarshal([]byte(jsonstr), &req) - - var response interface{} - _ = api.GetRequestReply(&req, &response) - - if response.(string) != expected { - t.Errorf("Expected %s got %s", expected, response) - } -} - -const solcVersion = "0.9.23" - -func TestCompileSolidity(t *testing.T) { - - solc, err := compiler.New("") - if solc == nil { - t.Skip("no solc found: skip") - } else if solc.Version() != solcVersion { - t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion) - } - source := `contract test {\n` + - " /// @notice Will multiply `a` by 7." + `\n` + - ` function multiply(uint a) returns(uint d) {\n` + - ` return a * 7;\n` + - ` }\n` + - `}\n` - - jsonstr := `{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["` + source + `"],"id":64}` - - expCode := "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056" - expAbiDefinition := `[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]` - expUserDoc := `{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}}` - expDeveloperDoc := `{"methods":{}}` - expCompilerVersion := solc.Version() - expLanguage := "Solidity" - expLanguageVersion := "0" - expSource := source - - api := NewEthereumApi(xeth.NewTest(ð.Ethereum{}, nil)) - - var req RpcRequest - json.Unmarshal([]byte(jsonstr), &req) - - var response interface{} - err = api.GetRequestReply(&req, &response) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - respjson, err := json.Marshal(response) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - var contracts = make(map[string]*compiler.Contract) - err = json.Unmarshal(respjson, &contracts) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - if len(contracts) != 1 { - t.Errorf("expected one contract, got %v", len(contracts)) - } - - contract := contracts["test"] - - if contract.Code != expCode { - t.Errorf("Expected \n%s got \n%s", expCode, contract.Code) - } - - if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` { - t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source)) - } - - if contract.Info.Language != expLanguage { - t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language) - } - - if contract.Info.LanguageVersion != expLanguageVersion { - t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion) - } - - if contract.Info.CompilerVersion != expCompilerVersion { - t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion) - } - - userdoc, err := json.Marshal(contract.Info.UserDoc) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - devdoc, err := json.Marshal(contract.Info.DeveloperDoc) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - abidef, err := json.Marshal(contract.Info.AbiDefinition) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - if string(abidef) != expAbiDefinition { - t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef)) - } - - if string(userdoc) != expUserDoc { - t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc)) - } - - if string(devdoc) != expDeveloperDoc { - t.Errorf("Expected %s got %s", expDeveloperDoc, string(devdoc)) - } -} - -// func TestDbStr(t *testing.T) { -// jsonput := `{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":64}` -// jsonget := `{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":64}` -// expected := "myString" - -// xeth := &xeth.XEth{} -// api := NewEthereumApi(xeth) -// var response interface{} - -// var req RpcRequest -// json.Unmarshal([]byte(jsonput), &req) -// _ = api.GetRequestReply(&req, &response) - -// json.Unmarshal([]byte(jsonget), &req) -// _ = api.GetRequestReply(&req, &response) - -// if response.(string) != expected { -// t.Errorf("Expected %s got %s", expected, response) -// } -// } - -// func TestDbHexStr(t *testing.T) { -// jsonput := `{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","beefKey","0xbeef"],"id":64}` -// jsonget := `{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","beefKey"],"id":64}` -// expected := "0xbeef" - -// xeth := &xeth.XEth{} -// api := NewEthereumApi(xeth) -// defer api.db.Close() -// var response interface{} - -// var req RpcRequest -// json.Unmarshal([]byte(jsonput), &req) -// _ = api.GetRequestReply(&req, &response) - -// json.Unmarshal([]byte(jsonget), &req) -// _ = api.GetRequestReply(&req, &response) - -// if response.(string) != expected { -// t.Errorf("Expected %s got %s", expected, response) -// } -// } - -// func TestFilterClose(t *testing.T) { -// t.Skip() -// api := &EthereumApi{ -// logs: make(map[int]*logFilter), -// messages: make(map[int]*whisperFilter), -// quit: make(chan struct{}), -// } - -// filterTickerTime = 1 -// api.logs[0] = &logFilter{} -// api.messages[0] = &whisperFilter{} -// var wg sync.WaitGroup -// wg.Add(1) -// go api.start() -// go func() { -// select { -// case <-time.After(500 * time.Millisecond): -// api.stop() -// wg.Done() -// } -// }() -// wg.Wait() -// if len(api.logs) != 0 { -// t.Error("expected logs to be empty") -// } - -// if len(api.messages) != 0 { -// t.Error("expected messages to be empty") -// } -// } diff --git a/rpc/args.go b/rpc/args.go deleted file mode 100644 index aa7d20549..000000000 --- a/rpc/args.go +++ /dev/null @@ -1,1230 +0,0 @@ -package rpc - -import ( - "encoding/json" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -const ( - defaultLogLimit = 100 - defaultLogOffset = 0 -) - -func blockHeightFromJson(msg json.RawMessage, number *int64) error { - var raw interface{} - if err := json.Unmarshal(msg, &raw); err != nil { - return NewDecodeParamError(err.Error()) - } - return blockHeight(raw, number) -} - -func blockHeight(raw interface{}, number *int64) error { - // Parse as integer - num, ok := raw.(float64) - if ok { - *number = int64(num) - return nil - } - - // Parse as string/hexstring - str, ok := raw.(string) - if !ok { - return NewInvalidTypeError("", "not a number or string") - } - - switch str { - case "earliest": - *number = 0 - case "latest": - *number = -1 - case "pending": - *number = -2 - default: - if common.HasHexPrefix(str) { - *number = common.String2Big(str).Int64() - } else { - return NewInvalidTypeError("blockNumber", "is not a valid string") - } - } - - return nil -} - -func numString(raw interface{}) (*big.Int, error) { - var number *big.Int - // Parse as integer - num, ok := raw.(float64) - if ok { - number = big.NewInt(int64(num)) - return number, nil - } - - // Parse as string/hexstring - str, ok := raw.(string) - if ok { - number = common.String2Big(str) - return number, nil - } - - return nil, NewInvalidTypeError("", "not a number or string") -} - -// func toNumber(v interface{}) (int64, error) { -// var str string -// if v != nil { -// var ok bool -// str, ok = v.(string) -// if !ok { -// return 0, errors.New("is not a string or undefined") -// } -// } else { -// str = "latest" -// } - -// switch str { -// case "latest": -// return -1, nil -// default: -// return int64(common.Big(v.(string)).Int64()), nil -// } -// } - -// func hashString(raw interface{}, hash *string) error { -// argstr, ok := raw.(string) -// if !ok { -// return NewInvalidTypeError("", "not a string") -// } -// v := common.IsHex(argstr) -// hash = &argstr - -// return nil -// } - -type GetBlockByHashArgs struct { - BlockHash string - IncludeTxs bool -} - -func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - argstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("blockHash", "not a string") - } - args.BlockHash = argstr - - args.IncludeTxs = obj[1].(bool) - - return nil -} - -type GetBlockByNumberArgs struct { - BlockNumber int64 - IncludeTxs bool -} - -func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - args.IncludeTxs = obj[1].(bool) - - return nil -} - -type NewDataArgs struct { - Data string -} - -func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - data, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("data", "not a string") - } - args.Data = data - - if len(args.Data) == 0 { - return NewValidationError("data", "is required") - } - - return nil -} - -type NewTxArgs struct { - From string - To string - Nonce *big.Int - Value *big.Int - Gas *big.Int - GasPrice *big.Int - Data string - - BlockNumber int64 -} - -type NewSigArgs struct { - From string - Data string -} - -func (args *NewSigArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - from, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("from", "not a string") - } - args.From = from - - if len(args.From) == 0 { - return NewValidationError("from", "is required") - } - - data, ok := obj[1].(string) - if !ok { - return NewInvalidTypeError("data", "not a string") - } - args.Data = data - - if len(args.Data) == 0 { - return NewValidationError("data", "is required") - } - - return nil -} - -func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { - var obj []json.RawMessage - var ext struct { - From string - To string - Nonce interface{} - Value interface{} - Gas interface{} - GasPrice interface{} - Data string - } - - // Decode byte slice to array of RawMessages - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - // Decode 0th RawMessage to temporary struct - if err := json.Unmarshal(obj[0], &ext); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(ext.From) == 0 { - return NewValidationError("from", "is required") - } - - args.From = ext.From - args.To = ext.To - args.Data = ext.Data - - var num *big.Int - if ext.Nonce != nil { - num, err = numString(ext.Nonce) - if err != nil { - return err - } - } - args.Nonce = num - - if ext.Value == nil { - num = big.NewInt(0) - } else { - num, err = numString(ext.Value) - if err != nil { - return err - } - } - args.Value = num - - num = nil - if ext.Gas != nil { - if num, err = numString(ext.Gas); err != nil { - return err - } - } else { - num = nil - } - args.Gas = num - - num = nil - if ext.GasPrice != nil { - if num, err = numString(ext.GasPrice); err != nil { - return err - } - } else { - num = nil - } - args.GasPrice = num - - // Check for optional BlockNumber param - if len(obj) > 1 { - if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type CallArgs struct { - From string - To string - Value *big.Int - Gas *big.Int - GasPrice *big.Int - Data string - - BlockNumber int64 -} - -func (args *CallArgs) UnmarshalJSON(b []byte) (err error) { - var obj []json.RawMessage - var ext struct { - From string - To string - Value interface{} - Gas interface{} - GasPrice interface{} - Data string - } - - // Decode byte slice to array of RawMessages - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - // Decode 0th RawMessage to temporary struct - if err := json.Unmarshal(obj[0], &ext); err != nil { - return NewDecodeParamError(err.Error()) - } - - args.From = ext.From - - if len(ext.To) == 0 { - return NewValidationError("to", "is required") - } - args.To = ext.To - - var num *big.Int - if ext.Value == nil { - num = big.NewInt(0) - } else { - if num, err = numString(ext.Value); err != nil { - return err - } - } - args.Value = num - - if ext.Gas != nil { - if num, err = numString(ext.Gas); err != nil { - return err - } - } else { - num = nil - } - args.Gas = num - - if ext.GasPrice != nil { - if num, err = numString(ext.GasPrice); err != nil { - return err - } - } else { - num = nil - } - args.GasPrice = num - - args.Data = ext.Data - - // Check for optional BlockNumber param - if len(obj) > 1 { - if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetStorageArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetStorageAtArgs struct { - Address string - Key string - BlockNumber int64 -} - -func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - addstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - keystr, ok := obj[1].(string) - if !ok { - return NewInvalidTypeError("key", "not a string") - } - args.Key = keystr - - if len(obj) > 2 { - if err := blockHeight(obj[2], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetTxCountArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetBalanceArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetDataArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type BlockNumArg struct { - BlockNumber int64 -} - -func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - return nil -} - -type BlockNumIndexArgs struct { - BlockNumber int64 - Index int64 -} - -func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - var arg1 *big.Int - if arg1, err = numString(obj[1]); err != nil { - return err - } - args.Index = arg1.Int64() - - return nil -} - -type HashArgs struct { - Hash string -} - -func (args *HashArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - arg0, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("hash", "not a string") - } - args.Hash = arg0 - - return nil -} - -type HashIndexArgs struct { - Hash string - Index int64 -} - -func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - arg0, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("hash", "not a string") - } - args.Hash = arg0 - - arg1, ok := obj[1].(string) - if !ok { - return NewInvalidTypeError("index", "not a string") - } - args.Index = common.Big(arg1).Int64() - - return nil -} - -type Sha3Args struct { - Data string -} - -func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - argstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("data", "is not a string") - } - args.Data = argstr - return nil -} - -type BlockFilterArgs struct { - Earliest int64 - Latest int64 - Address []string - Topics [][]string - Skip int - Max int -} - -func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { - var obj []struct { - FromBlock interface{} `json:"fromBlock"` - ToBlock interface{} `json:"toBlock"` - Limit interface{} `json:"limit"` - Offset interface{} `json:"offset"` - Address interface{} `json:"address"` - Topics interface{} `json:"topics"` - } - - if err = json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - // args.Earliest, err = toNumber(obj[0].ToBlock) - // if err != nil { - // return NewDecodeParamError(fmt.Sprintf("FromBlock %v", err)) - // } - // args.Latest, err = toNumber(obj[0].FromBlock) - // if err != nil { - // return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err)) - - var num int64 - var numBig *big.Int - - // if blank then latest - if obj[0].FromBlock == nil { - num = -1 - } else { - if err := blockHeight(obj[0].FromBlock, &num); err != nil { - return err - } - } - // if -2 or other "silly" number, use latest - if num < 0 { - args.Earliest = -1 //latest block - } else { - args.Earliest = num - } - - // if blank than latest - if obj[0].ToBlock == nil { - num = -1 - } else { - if err := blockHeight(obj[0].ToBlock, &num); err != nil { - return err - } - } - args.Latest = num - - if obj[0].Limit == nil { - numBig = big.NewInt(defaultLogLimit) - } else { - if numBig, err = numString(obj[0].Limit); err != nil { - return err - } - } - args.Max = int(numBig.Int64()) - - if obj[0].Offset == nil { - numBig = big.NewInt(defaultLogOffset) - } else { - if numBig, err = numString(obj[0].Offset); err != nil { - return err - } - } - args.Skip = int(numBig.Int64()) - - if obj[0].Address != nil { - marg, ok := obj[0].Address.([]interface{}) - if ok { - v := make([]string, len(marg)) - for i, arg := range marg { - argstr, ok := arg.(string) - if !ok { - return NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string") - } - v[i] = argstr - } - args.Address = v - } else { - argstr, ok := obj[0].Address.(string) - if ok { - v := make([]string, 1) - v[0] = argstr - args.Address = v - } else { - return NewInvalidTypeError("address", "is not a string or array") - } - } - } - - if obj[0].Topics != nil { - other, ok := obj[0].Topics.([]interface{}) - if ok { - topicdbl := make([][]string, len(other)) - for i, iv := range other { - if argstr, ok := iv.(string); ok { - // Found a string, push into first element of array - topicsgl := make([]string, 1) - topicsgl[0] = argstr - topicdbl[i] = topicsgl - } else if argarray, ok := iv.([]interface{}); ok { - // Found an array of other - topicdbl[i] = make([]string, len(argarray)) - for j, jv := range argarray { - if v, ok := jv.(string); ok { - topicdbl[i][j] = v - } else if jv == nil { - topicdbl[i][j] = "" - } else { - return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string") - } - } - } else if iv == nil { - topicdbl[i] = []string{""} - } else { - return NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array") - } - } - args.Topics = topicdbl - return nil - } else { - return NewInvalidTypeError("topic", "is not a string or array") - } - } - - return nil -} - -type DbArgs struct { - Database string - Key string - Value []byte -} - -func (args *DbArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - var objstr string - var ok bool - - if objstr, ok = obj[0].(string); !ok { - return NewInvalidTypeError("database", "not a string") - } - args.Database = objstr - - if objstr, ok = obj[1].(string); !ok { - return NewInvalidTypeError("key", "not a string") - } - args.Key = objstr - - if len(obj) > 2 { - objstr, ok = obj[2].(string) - if !ok { - return NewInvalidTypeError("value", "not a string") - } - - args.Value = []byte(objstr) - } - - return nil -} - -func (a *DbArgs) requirements() error { - if len(a.Database) == 0 { - return NewValidationError("Database", "cannot be blank") - } - if len(a.Key) == 0 { - return NewValidationError("Key", "cannot be blank") - } - return nil -} - -type DbHexArgs struct { - Database string - Key string - Value []byte -} - -func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return NewInsufficientParamsError(len(obj), 2) - } - - var objstr string - var ok bool - - if objstr, ok = obj[0].(string); !ok { - return NewInvalidTypeError("database", "not a string") - } - args.Database = objstr - - if objstr, ok = obj[1].(string); !ok { - return NewInvalidTypeError("key", "not a string") - } - args.Key = objstr - - if len(obj) > 2 { - objstr, ok = obj[2].(string) - if !ok { - return NewInvalidTypeError("value", "not a string") - } - - args.Value = common.FromHex(objstr) - } - - return nil -} - -func (a *DbHexArgs) requirements() error { - if len(a.Database) == 0 { - return NewValidationError("Database", "cannot be blank") - } - if len(a.Key) == 0 { - return NewValidationError("Key", "cannot be blank") - } - return nil -} - -type WhisperMessageArgs struct { - Payload string - To string - From string - Topics []string - Priority uint32 - Ttl uint32 -} - -func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) { - var obj []struct { - Payload string - To string - From string - Topics []string - Priority interface{} - Ttl interface{} - } - - if err = json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - args.Payload = obj[0].Payload - args.To = obj[0].To - args.From = obj[0].From - args.Topics = obj[0].Topics - - var num *big.Int - if num, err = numString(obj[0].Priority); err != nil { - return err - } - args.Priority = uint32(num.Int64()) - - if num, err = numString(obj[0].Ttl); err != nil { - return err - } - args.Ttl = uint32(num.Int64()) - - return nil -} - -type CompileArgs struct { - Source string -} - -func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - argstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("arg0", "is not a string") - } - args.Source = argstr - - return nil -} - -type FilterStringArgs struct { - Word string -} - -func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - var argstr string - argstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("filter", "not a string") - } - switch argstr { - case "latest", "pending": - break - default: - return NewValidationError("Word", "Must be `latest` or `pending`") - } - args.Word = argstr - return nil -} - -type FilterIdArgs struct { - Id int -} - -func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - var num *big.Int - if num, err = numString(obj[0]); err != nil { - return err - } - args.Id = int(num.Int64()) - - return nil -} - -type WhisperIdentityArgs struct { - Identity string -} - -func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - argstr, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("arg0", "not a string") - } - // if !common.IsHex(argstr) { - // return NewValidationError("arg0", "not a hexstring") - // } - args.Identity = argstr - - return nil -} - -type WhisperFilterArgs struct { - To string - From string - Topics [][]string -} - -// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a -// JSON message blob into a WhisperFilterArgs structure. -func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { - // Unmarshal the JSON message and sanity check - var obj []struct { - To interface{} `json:"to"` - From interface{} `json:"from"` - Topics interface{} `json:"topics"` - } - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - // Retrieve the simple data contents of the filter arguments - if obj[0].To == nil { - args.To = "" - } else { - argstr, ok := obj[0].To.(string) - if !ok { - return NewInvalidTypeError("to", "is not a string") - } - args.To = argstr - } - if obj[0].From == nil { - args.From = "" - } else { - argstr, ok := obj[0].From.(string) - if !ok { - return NewInvalidTypeError("from", "is not a string") - } - args.From = argstr - } - // Construct the nested topic array - if obj[0].Topics != nil { - // Make sure we have an actual topic array - list, ok := obj[0].Topics.([]interface{}) - if !ok { - return NewInvalidTypeError("topics", "is not an array") - } - // Iterate over each topic and handle nil, string or array - topics := make([][]string, len(list)) - for idx, field := range list { - switch value := field.(type) { - case nil: - topics[idx] = []string{} - - case string: - topics[idx] = []string{value} - - case []interface{}: - topics[idx] = make([]string, len(value)) - for i, nested := range value { - switch value := nested.(type) { - case nil: - topics[idx][i] = "" - - case string: - topics[idx][i] = value - - default: - return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", idx, i), "is not a string") - } - } - default: - return NewInvalidTypeError(fmt.Sprintf("topic[%d]", idx), "not a string or array") - } - } - args.Topics = topics - } - return nil -} - -type SubmitWorkArgs struct { - Nonce uint64 - Header string - Digest string -} - -func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err = json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 3 { - return NewInsufficientParamsError(len(obj), 3) - } - - var objstr string - var ok bool - if objstr, ok = obj[0].(string); !ok { - return NewInvalidTypeError("nonce", "not a string") - } - - args.Nonce = common.String2Big(objstr).Uint64() - if objstr, ok = obj[1].(string); !ok { - return NewInvalidTypeError("header", "not a string") - } - - args.Header = objstr - - if objstr, ok = obj[2].(string); !ok { - return NewInvalidTypeError("digest", "not a string") - } - - args.Digest = objstr - - return nil -} - -type SourceArgs struct { - Source string -} - -func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return NewInsufficientParamsError(len(obj), 1) - } - - arg0, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("source code", "not a string") - } - args.Source = arg0 - - return nil -} diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 2af63e55d..050e7b4e2 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -9,16 +9,32 @@ import ( "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" + "strings" ) const ( - jsonrpcver = "2.0" maxHttpSizeReqLength = 1024 * 1024 // 1MB ) +var ( + // List with all API's which are offered over the in proc interface by default + DefaultInProcApis = api.AllApis + + // List with all API's which are offered over the IPC interface by default + DefaultIpcApis = api.AllApis + + // List with API's which are offered over thr HTTP/RPC interface by default + DefaultHttpRpcApis = strings.Join([]string{ + api.DbApiName, api.EthApiName, api.NetApiName, api.Web3ApiName, + }, ",") +) + type EthereumClient interface { + // Close underlaying connection Close() + // Send request Send(interface{}) error + // Receive response Recv() (interface{}, error) } diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 1fea8dc1d..c0ea2cc78 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -63,3 +63,27 @@ func StopHttp() { httpListener = nil } } + + +type httpClient struct { + codec codec.ApiCoder +} + +// Create a new in process client +func NewHttpClient(cfg HttpConfig, codec codec.Codec) *httpClient { + return &httpClient{ + codec: codec.New(nil), + } +} + +func (self *httpClient) Close() { + // do nothing +} + +func (self *httpClient) Send(req interface{}) error { + return nil +} + +func (self *httpClient) Recv() (interface{}, error) { + return nil, nil +} \ No newline at end of file diff --git a/rpc/comms/http_net.go b/rpc/comms/http_net.go index 8d1bacc06..f326f1a7e 100644 --- a/rpc/comms/http_net.go +++ b/rpc/comms/http_net.go @@ -90,7 +90,7 @@ func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { case <-stop: w.Header().Set("Content-Type", "application/json") err := fmt.Errorf("RPC service stopped") - response := shared.NewRpcResponse(-1, jsonrpcver, nil, err) + response := shared.NewRpcResponse(-1, api.JsonRpcVersion, nil, err) httpSend(w, response) default: h.ServeHTTP(w, r) @@ -110,14 +110,14 @@ func httpSend(writer io.Writer, v interface{}) (n int, err error) { return writer.Write(payload) } -func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { +func gethHttpHandler(codec codec.Codec, a api.EthereumApi) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") // Limit request size to resist DoS if req.ContentLength > maxHttpSizeReqLength { err := fmt.Errorf("Request too large") - response := shared.NewRpcErrorResponse(-1, jsonrpcver, -32700, err) + response := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32700, err) httpSend(w, &response) return } @@ -126,7 +126,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { payload, err := ioutil.ReadAll(req.Body) if err != nil { err := fmt.Errorf("Could not read request body") - response := shared.NewRpcErrorResponse(-1, jsonrpcver, -32700, err) + response := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32700, err) httpSend(w, &response) return } @@ -134,7 +134,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { c := codec.New(nil) var rpcReq shared.Request if err = c.Decode(payload, &rpcReq); err == nil { - reply, err := api.Execute(&rpcReq) + reply, err := a.Execute(&rpcReq) res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) httpSend(w, &res) return @@ -146,7 +146,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { resCount := 0 for i, rpcReq := range reqBatch { - reply, err := api.Execute(&rpcReq) + reply, err := a.Execute(&rpcReq) if rpcReq.Id != nil { // this leaves nil entries in the response batch for later removal resBatch[i] = shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) resCount += 1 @@ -161,7 +161,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { // invalid request err = fmt.Errorf("Could not decode request") - res := shared.NewRpcErrorResponse(-1, jsonrpcver, -32600, err) + res := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32600, err) httpSend(w, res) }) } diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go new file mode 100644 index 000000000..89cb93cdc --- /dev/null +++ b/rpc/comms/inproc.go @@ -0,0 +1,53 @@ +package comms + +import ( + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/shared" + "fmt" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/xeth" + "github.com/ethereum/go-ethereum/eth" +) + +type InProcClient struct { + api api.EthereumApi + codec codec.Codec + lastId interface{} + lastJsonrpc string + lastErr error + lastRes interface{} +} + +// Create a new in process client +func NewInProcClient(codec codec.Codec) *InProcClient { + return &InProcClient{ + codec: codec, + } +} + +func (self *InProcClient) Close() { + // do nothing +} + +// Need to setup api support +func (self *InProcClient) Initialize(xeth *xeth.XEth, eth *eth.Ethereum) { + if apis, err := api.ParseApiString(api.AllApis, self.codec, xeth, eth); err == nil { + self.api = api.Merge(apis...) + } +} + +func (self *InProcClient) Send(req interface{}) error { + if r, ok := req.(*shared.Request); ok { + self.lastId = r.Id + self.lastJsonrpc = r.Jsonrpc + self.lastRes, self.lastErr = self.api.Execute(r) + return self.lastErr + } + + return fmt.Errorf("Invalid request (%T)", req) +} + +func (self *InProcClient) Recv() (interface{}, error) { + return self.lastRes, self.lastErr + //return *shared.NewRpcResponse(self.lastId, self.lastJsonrpc, self.lastRes, self.lastErr), nil +} diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go index a75039d17..a07203803 100644 --- a/rpc/comms/ipc.go +++ b/rpc/comms/ipc.go @@ -10,19 +10,19 @@ type IpcConfig struct { } type ipcClient struct { - c codec.ApiCoder + codec codec.ApiCoder } func (self *ipcClient) Close() { - self.c.Close() + self.codec.Close() } func (self *ipcClient) Send(req interface{}) error { - return self.c.WriteResponse(req) + return self.codec.WriteResponse(req) } func (self *ipcClient) Recv() (interface{}, error) { - return self.c.ReadResponse() + return self.codec.ReadResponse() } // Create a new IPC client, UNIX domain socket on posix, named pipe on Windows diff --git a/rpc/http.go b/rpc/http.go deleted file mode 100644 index f37e102f5..000000000 --- a/rpc/http.go +++ /dev/null @@ -1,163 +0,0 @@ -package rpc - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "strings" - - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/xeth" - "github.com/rs/cors" -) - -var rpclistener *stoppableTCPListener - -const ( - jsonrpcver = "2.0" - maxSizeReqLength = 1024 * 1024 // 1MB -) - -func Start(pipe *xeth.XEth, config RpcConfig) error { - if rpclistener != nil { - if fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort) != rpclistener.Addr().String() { - return fmt.Errorf("RPC service already running on %s ", rpclistener.Addr().String()) - } - return nil // RPC service already running on given host/port - } - - l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) - if err != nil { - glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err) - return err - } - rpclistener = l - - var handler http.Handler - if len(config.CorsDomain) > 0 { - var opts cors.Options - opts.AllowedMethods = []string{"POST"} - opts.AllowedOrigins = strings.Split(config.CorsDomain, " ") - - c := cors.New(opts) - handler = newStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) - } else { - handler = newStoppableHandler(JSONRPC(pipe), l.stop) - } - - go http.Serve(l, handler) - - return nil -} - -func Stop() error { - if rpclistener != nil { - rpclistener.Stop() - rpclistener = nil - } - - return nil -} - -// JSONRPC returns a handler that implements the Ethereum JSON-RPC API. -func JSONRPC(pipe *xeth.XEth) http.Handler { - api := NewEthereumApi(pipe) - - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Header().Set("Content-Type", "application/json") - - // Limit request size to resist DoS - if req.ContentLength > maxSizeReqLength { - jsonerr := &RpcErrorObject{-32700, "Request too large"} - send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) - return - } - - // Read request body - defer req.Body.Close() - body, err := ioutil.ReadAll(req.Body) - if err != nil { - jsonerr := &RpcErrorObject{-32700, "Could not read request body"} - send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) - } - - // Try to parse the request as a single - var reqSingle RpcRequest - if err := json.Unmarshal(body, &reqSingle); err == nil { - response := RpcResponse(api, &reqSingle) - if reqSingle.Id != nil { - send(w, &response) - } - return - } - - // Try to parse the request to batch - var reqBatch []RpcRequest - if err := json.Unmarshal(body, &reqBatch); err == nil { - // Build response batch - resBatch := make([]*interface{}, len(reqBatch)) - resCount := 0 - - for i, request := range reqBatch { - response := RpcResponse(api, &request) - // this leaves nil entries in the response batch for later removal - if request.Id != nil { - resBatch[i] = response - resCount = resCount + 1 - } - } - - // make response omitting nil entries - respBatchComp := make([]*interface{}, resCount) - for _, v := range resBatch { - if v != nil { - respBatchComp[len(respBatchComp)-resCount] = v - resCount = resCount - 1 - } - } - - send(w, respBatchComp) - return - } - - // Not a batch or single request, error - jsonerr := &RpcErrorObject{-32600, "Could not decode request"} - send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) - }) -} - -func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} { - var reply, response interface{} - reserr := api.GetRequestReply(request, &reply) - switch reserr.(type) { - case nil: - response = &RpcSuccessResponse{Jsonrpc: jsonrpcver, Id: request.Id, Result: reply} - case *NotImplementedError, *NotAvailableError: - jsonerr := &RpcErrorObject{-32601, reserr.Error()} - response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr} - case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError: - jsonerr := &RpcErrorObject{-32602, reserr.Error()} - response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr} - default: - jsonerr := &RpcErrorObject{-32603, reserr.Error()} - response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr} - } - - glog.V(logger.Detail).Infof("Generated response: %T %s", response, response) - return &response -} - -func send(writer io.Writer, v interface{}) (n int, err error) { - var payload []byte - payload, err = json.MarshalIndent(v, "", "\t") - if err != nil { - glog.V(logger.Error).Infoln("Error marshalling JSON", err) - return 0, err - } - glog.V(logger.Detail).Infof("Sending payload: %s", payload) - - return writer.Write(payload) -} diff --git a/rpc/jeth.go b/rpc/jeth.go index e578775bb..08d6a9878 100644 --- a/rpc/jeth.go +++ b/rpc/jeth.go @@ -1,31 +1,28 @@ package rpc import ( - "encoding/json" - "fmt" - - "reflect" - "github.com/ethereum/go-ethereum/jsre" - "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/comms" "github.com/ethereum/go-ethereum/rpc/shared" "github.com/robertkrimen/otto" + "encoding/json" + "fmt" ) type Jeth struct { - ethApi *EthereumApi - re *jsre.JSRE - ipcpath string + ethApi api.EthereumApi + re *jsre.JSRE + client comms.EthereumClient } -func NewJeth(ethApi *EthereumApi, re *jsre.JSRE, ipcpath string) *Jeth { - return &Jeth{ethApi, re, ipcpath} +func NewJeth(ethApi api.EthereumApi, re *jsre.JSRE, client comms.EthereumClient) *Jeth { + return &Jeth{ethApi, re, client} } func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) { - rpcerr := &RpcErrorObject{code, msg} - call.Otto.Set("ret_jsonrpc", jsonrpcver) + rpcerr := &shared.ErrorObject{code, msg} + call.Otto.Set("ret_jsonrpc", api.JsonRpcVersion) call.Otto.Set("ret_id", id) call.Otto.Set("ret_error", rpcerr) response, _ = call.Otto.Run(` @@ -34,6 +31,7 @@ func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface return } + func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { reqif, err := call.Argument(0).Export() if err != nil { @@ -41,11 +39,11 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { } jsonreq, err := json.Marshal(reqif) - var reqs []RpcRequest + var reqs []shared.Request batch := true err = json.Unmarshal(jsonreq, &reqs) if err != nil { - reqs = make([]RpcRequest, 1) + reqs = make([]shared.Request, 1) err = json.Unmarshal(jsonreq, &reqs[0]) batch = false } @@ -55,12 +53,18 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { for i, req := range reqs { var respif interface{} - err = self.ethApi.GetRequestReply(&req, &respif) + err := self.client.Send(&req)//self.ethApi.Execute(&req) + if err != nil { + fmt.Println("Error request:", err) + return self.err(call, -32603, err.Error(), req.Id) + } + respif, err = self.client.Recv() if err != nil { fmt.Println("Error response:", err) return self.err(call, -32603, err.Error(), req.Id) } - call.Otto.Set("ret_jsonrpc", jsonrpcver) + + call.Otto.Set("ret_jsonrpc", api.JsonRpcVersion) call.Otto.Set("ret_id", req.Id) res, _ := json.Marshal(respif) @@ -88,6 +92,7 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { return } +/* func (self *Jeth) SendIpc(call otto.FunctionCall) (response otto.Value) { reqif, err := call.Argument(0).Export() if err != nil { @@ -102,11 +107,11 @@ func (self *Jeth) SendIpc(call otto.FunctionCall) (response otto.Value) { defer client.Close() jsonreq, err := json.Marshal(reqif) - var reqs []RpcRequest + var reqs []shared.Request batch := true err = json.Unmarshal(jsonreq, &reqs) if err != nil { - reqs = make([]RpcRequest, 1) + reqs = make([]shared.Request, 1) err = json.Unmarshal(jsonreq, &reqs[0]) batch = false } @@ -169,3 +174,4 @@ func (self *Jeth) SendIpc(call otto.FunctionCall) (response otto.Value) { return } +*/ diff --git a/rpc/responses.go b/rpc/responses.go deleted file mode 100644 index 9fdf60c02..000000000 --- a/rpc/responses.go +++ /dev/null @@ -1,316 +0,0 @@ -package rpc - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" -) - -type BlockRes struct { - fullTx bool - - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []*TransactionRes `json:"transactions"` - Uncles []*UncleRes `json:"uncles"` -} - -func (b *BlockRes) MarshalJSON() ([]byte, error) { - if b.fullTx { - var ext struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []*TransactionRes `json:"transactions"` - Uncles []*hexdata `json:"uncles"` - } - - ext.BlockNumber = b.BlockNumber - ext.BlockHash = b.BlockHash - ext.ParentHash = b.ParentHash - ext.Nonce = b.Nonce - ext.Sha3Uncles = b.Sha3Uncles - ext.LogsBloom = b.LogsBloom - ext.TransactionRoot = b.TransactionRoot - ext.StateRoot = b.StateRoot - ext.Miner = b.Miner - ext.Difficulty = b.Difficulty - ext.TotalDifficulty = b.TotalDifficulty - ext.Size = b.Size - ext.ExtraData = b.ExtraData - ext.GasLimit = b.GasLimit - ext.GasUsed = b.GasUsed - ext.UnixTimestamp = b.UnixTimestamp - ext.Transactions = b.Transactions - ext.Uncles = make([]*hexdata, len(b.Uncles)) - for i, u := range b.Uncles { - ext.Uncles[i] = u.BlockHash - } - return json.Marshal(ext) - } else { - var ext struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []*hexdata `json:"transactions"` - Uncles []*hexdata `json:"uncles"` - } - - ext.BlockNumber = b.BlockNumber - ext.BlockHash = b.BlockHash - ext.ParentHash = b.ParentHash - ext.Nonce = b.Nonce - ext.Sha3Uncles = b.Sha3Uncles - ext.LogsBloom = b.LogsBloom - ext.TransactionRoot = b.TransactionRoot - ext.StateRoot = b.StateRoot - ext.Miner = b.Miner - ext.Difficulty = b.Difficulty - ext.TotalDifficulty = b.TotalDifficulty - ext.Size = b.Size - ext.ExtraData = b.ExtraData - ext.GasLimit = b.GasLimit - ext.GasUsed = b.GasUsed - ext.UnixTimestamp = b.UnixTimestamp - ext.Transactions = make([]*hexdata, len(b.Transactions)) - for i, tx := range b.Transactions { - ext.Transactions[i] = tx.Hash - } - ext.Uncles = make([]*hexdata, len(b.Uncles)) - for i, u := range b.Uncles { - ext.Uncles[i] = u.BlockHash - } - return json.Marshal(ext) - } -} - -func NewBlockRes(block *types.Block, fullTx bool) *BlockRes { - if block == nil { - return nil - } - - res := new(BlockRes) - res.fullTx = fullTx - res.BlockNumber = newHexNum(block.Number()) - res.BlockHash = newHexData(block.Hash()) - res.ParentHash = newHexData(block.ParentHash()) - res.Nonce = newHexData(block.Nonce()) - res.Sha3Uncles = newHexData(block.Header().UncleHash) - res.LogsBloom = newHexData(block.Bloom()) - res.TransactionRoot = newHexData(block.Header().TxHash) - res.StateRoot = newHexData(block.Root()) - res.Miner = newHexData(block.Header().Coinbase) - res.Difficulty = newHexNum(block.Difficulty()) - res.TotalDifficulty = newHexNum(block.Td) - res.Size = newHexNum(block.Size().Int64()) - res.ExtraData = newHexData(block.Header().Extra) - res.GasLimit = newHexNum(block.GasLimit()) - res.GasUsed = newHexNum(block.GasUsed()) - res.UnixTimestamp = newHexNum(block.Time()) - - res.Transactions = make([]*TransactionRes, len(block.Transactions())) - for i, tx := range block.Transactions() { - res.Transactions[i] = NewTransactionRes(tx) - res.Transactions[i].BlockHash = res.BlockHash - res.Transactions[i].BlockNumber = res.BlockNumber - res.Transactions[i].TxIndex = newHexNum(i) - } - - res.Uncles = make([]*UncleRes, len(block.Uncles())) - for i, uncle := range block.Uncles() { - res.Uncles[i] = NewUncleRes(uncle) - } - - return res -} - -type TransactionRes struct { - Hash *hexdata `json:"hash"` - Nonce *hexnum `json:"nonce"` - BlockHash *hexdata `json:"blockHash"` - BlockNumber *hexnum `json:"blockNumber"` - TxIndex *hexnum `json:"transactionIndex"` - From *hexdata `json:"from"` - To *hexdata `json:"to"` - Value *hexnum `json:"value"` - Gas *hexnum `json:"gas"` - GasPrice *hexnum `json:"gasPrice"` - Input *hexdata `json:"input"` -} - -func NewTransactionRes(tx *types.Transaction) *TransactionRes { - if tx == nil { - return nil - } - - var v = new(TransactionRes) - v.Hash = newHexData(tx.Hash()) - v.Nonce = newHexNum(tx.Nonce()) - // v.BlockHash = - // v.BlockNumber = - // v.TxIndex = - from, _ := tx.From() - v.From = newHexData(from) - v.To = newHexData(tx.To()) - v.Value = newHexNum(tx.Value()) - v.Gas = newHexNum(tx.Gas()) - v.GasPrice = newHexNum(tx.GasPrice()) - v.Input = newHexData(tx.Data()) - return v -} - -type UncleRes struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - ReceiptHash *hexdata `json:"receiptHash"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` -} - -func NewUncleRes(h *types.Header) *UncleRes { - if h == nil { - return nil - } - - var v = new(UncleRes) - v.BlockNumber = newHexNum(h.Number) - v.BlockHash = newHexData(h.Hash()) - v.ParentHash = newHexData(h.ParentHash) - v.Sha3Uncles = newHexData(h.UncleHash) - v.Nonce = newHexData(h.Nonce[:]) - v.LogsBloom = newHexData(h.Bloom) - v.TransactionRoot = newHexData(h.TxHash) - v.StateRoot = newHexData(h.Root) - v.Miner = newHexData(h.Coinbase) - v.Difficulty = newHexNum(h.Difficulty) - v.ExtraData = newHexData(h.Extra) - v.GasLimit = newHexNum(h.GasLimit) - v.GasUsed = newHexNum(h.GasUsed) - v.UnixTimestamp = newHexNum(h.Time) - v.ReceiptHash = newHexData(h.ReceiptHash) - - return v -} - -// type FilterLogRes struct { -// Hash string `json:"hash"` -// Address string `json:"address"` -// Data string `json:"data"` -// BlockNumber string `json:"blockNumber"` -// TransactionHash string `json:"transactionHash"` -// BlockHash string `json:"blockHash"` -// TransactionIndex string `json:"transactionIndex"` -// LogIndex string `json:"logIndex"` -// } - -// type FilterWhisperRes struct { -// Hash string `json:"hash"` -// From string `json:"from"` -// To string `json:"to"` -// Expiry string `json:"expiry"` -// Sent string `json:"sent"` -// Ttl string `json:"ttl"` -// Topics string `json:"topics"` -// Payload string `json:"payload"` -// WorkProved string `json:"workProved"` -// } - -type LogRes struct { - Address *hexdata `json:"address"` - Topics []*hexdata `json:"topics"` - Data *hexdata `json:"data"` - BlockNumber *hexnum `json:"blockNumber"` - LogIndex *hexnum `json:"logIndex"` - BlockHash *hexdata `json:"blockHash"` - TransactionHash *hexdata `json:"transactionHash"` - TransactionIndex *hexnum `json:"transactionIndex"` -} - -func NewLogRes(log *state.Log) LogRes { - var l LogRes - l.Topics = make([]*hexdata, len(log.Topics)) - for j, topic := range log.Topics { - l.Topics[j] = newHexData(topic) - } - l.Address = newHexData(log.Address) - l.Data = newHexData(log.Data) - l.BlockNumber = newHexNum(log.Number) - l.LogIndex = newHexNum(log.Index) - l.TransactionHash = newHexData(log.TxHash) - l.TransactionIndex = newHexNum(log.TxIndex) - l.BlockHash = newHexData(log.BlockHash) - - return l -} - -func NewLogsRes(logs state.Logs) (ls []LogRes) { - ls = make([]LogRes, len(logs)) - - for i, log := range logs { - ls[i] = NewLogRes(log) - } - - return -} - -func NewHashesRes(hs []common.Hash) []string { - hashes := make([]string, len(hs)) - - for i, hash := range hs { - hashes[i] = hash.Hex() - } - - return hashes -} diff --git a/rpc/responses_test.go b/rpc/responses_test.go deleted file mode 100644 index 66323e5f5..000000000 --- a/rpc/responses_test.go +++ /dev/null @@ -1,295 +0,0 @@ -package rpc - -import ( - "encoding/json" - "fmt" - "math/big" - "regexp" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" -) - -const ( - reHash = `"0x[0-9a-f]{64}"` // 32 bytes - reHashOpt = `"(0x[0-9a-f]{64})"|null` // 32 bytes or null - reAddress = `"0x[0-9a-f]{40}"` // 20 bytes - reAddressOpt = `"0x[0-9a-f]{40}"|null` // 20 bytes or null - reNum = `"0x([1-9a-f][0-9a-f]{0,15})|0"` // must not have left-padded zeros - reNumNonZero = `"0x([1-9a-f][0-9a-f]{0,15})"` // non-zero required must not have left-padded zeros - reNumOpt = `"0x([1-9a-f][0-9a-f]{0,15})|0"|null` // must not have left-padded zeros or null - reData = `"0x[0-9a-f]*"` // can be "empty" - // reListHash = `[("\w":"0x[0-9a-f]{64}",?)*]` - // reListObj = `[("\w":(".+"|null),?)*]` -) - -func TestNewBlockRes(t *testing.T) { - tests := map[string]string{ - "number": reNum, - "hash": reHash, - "parentHash": reHash, - "nonce": reData, - "sha3Uncles": reHash, - "logsBloom": reData, - "transactionsRoot": reHash, - "stateRoot": reHash, - "miner": reAddress, - "difficulty": `"0x1"`, - "totalDifficulty": reNum, - "size": reNumNonZero, - "extraData": reData, - "gasLimit": reNum, - // "minGasPrice": "0x", - "gasUsed": reNum, - "timestamp": reNum, - // "transactions": reListHash, - // "uncles": reListHash, - } - - block := makeBlock() - v := NewBlockRes(block, false) - j, _ := json.Marshal(v) - - for k, re := range tests { - match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) - if !match { - t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) - } - } -} - -func TestNewBlockResTxFull(t *testing.T) { - tests := map[string]string{ - "number": reNum, - "hash": reHash, - "parentHash": reHash, - "nonce": reData, - "sha3Uncles": reHash, - "logsBloom": reData, - "transactionsRoot": reHash, - "stateRoot": reHash, - "miner": reAddress, - "difficulty": `"0x1"`, - "totalDifficulty": reNum, - "size": reNumNonZero, - "extraData": reData, - "gasLimit": reNum, - // "minGasPrice": "0x", - "gasUsed": reNum, - "timestamp": reNum, - // "transactions": reListHash, - // "uncles": reListHash, - } - - block := makeBlock() - v := NewBlockRes(block, true) - j, _ := json.Marshal(v) - - for k, re := range tests { - match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) - if !match { - t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) - } - } -} - -func TestBlockNil(t *testing.T) { - var block *types.Block - block = nil - u := NewBlockRes(block, false) - j, _ := json.Marshal(u) - if string(j) != "null" { - t.Errorf("Expected null but got %v", string(j)) - } -} - -func TestNewTransactionRes(t *testing.T) { - to := common.HexToAddress("0x02") - amount := big.NewInt(1) - gasAmount := big.NewInt(1) - gasPrice := big.NewInt(1) - data := []byte{1, 2, 3} - tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) - - tests := map[string]string{ - "hash": reHash, - "nonce": reNum, - "blockHash": reHashOpt, - "blockNum": reNumOpt, - "transactionIndex": reNumOpt, - "from": reAddress, - "to": reAddressOpt, - "value": reNum, - "gas": reNum, - "gasPrice": reNum, - "input": reData, - } - - v := NewTransactionRes(tx) - v.BlockHash = newHexData(common.HexToHash("0x030201")) - v.BlockNumber = newHexNum(5) - v.TxIndex = newHexNum(0) - j, _ := json.Marshal(v) - for k, re := range tests { - match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) - if !match { - t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j)) - } - } - -} - -func TestTransactionNil(t *testing.T) { - var tx *types.Transaction - tx = nil - u := NewTransactionRes(tx) - j, _ := json.Marshal(u) - if string(j) != "null" { - t.Errorf("Expected null but got %v", string(j)) - } -} - -func TestNewUncleRes(t *testing.T) { - header := makeHeader() - u := NewUncleRes(header) - tests := map[string]string{ - "number": reNum, - "hash": reHash, - "parentHash": reHash, - "nonce": reData, - "sha3Uncles": reHash, - "receiptHash": reHash, - "transactionsRoot": reHash, - "stateRoot": reHash, - "miner": reAddress, - "difficulty": reNum, - "extraData": reData, - "gasLimit": reNum, - "gasUsed": reNum, - "timestamp": reNum, - } - - j, _ := json.Marshal(u) - for k, re := range tests { - match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) - if !match { - t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j)) - } - } -} - -func TestUncleNil(t *testing.T) { - var header *types.Header - header = nil - u := NewUncleRes(header) - j, _ := json.Marshal(u) - if string(j) != "null" { - t.Errorf("Expected null but got %v", string(j)) - } -} - -func TestNewLogRes(t *testing.T) { - log := makeStateLog(0) - tests := map[string]string{ - "address": reAddress, - // "topics": "[.*]" - "data": reData, - "blockNumber": reNum, - // "hash": reHash, - // "logIndex": reNum, - // "blockHash": reHash, - // "transactionHash": reHash, - "transactionIndex": reNum, - } - - v := NewLogRes(log) - j, _ := json.Marshal(v) - - for k, re := range tests { - match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) - if !match { - t.Error(fmt.Sprintf("`%s` output json does not match format %s. Got %s", k, re, j)) - } - } - -} - -func TestNewLogsRes(t *testing.T) { - logs := make([]*state.Log, 3) - logs[0] = makeStateLog(1) - logs[1] = makeStateLog(2) - logs[2] = makeStateLog(3) - tests := map[string]string{} - - v := NewLogsRes(logs) - j, _ := json.Marshal(v) - - for k, re := range tests { - match, _ := regexp.MatchString(fmt.Sprintf(`[{.*"%s":%s.*}]`, k, re), string(j)) - if !match { - t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) - } - } - -} - -func makeStateLog(num int) *state.Log { - address := common.HexToAddress("0x0") - data := []byte{1, 2, 3} - number := uint64(num) - topics := make([]common.Hash, 3) - topics = append(topics, common.HexToHash("0x00")) - topics = append(topics, common.HexToHash("0x10")) - topics = append(topics, common.HexToHash("0x20")) - log := state.NewLog(address, topics, data, number) - return log -} - -func makeHeader() *types.Header { - header := &types.Header{ - ParentHash: common.StringToHash("0x00"), - UncleHash: common.StringToHash("0x00"), - Coinbase: common.StringToAddress("0x00"), - Root: common.StringToHash("0x00"), - TxHash: common.StringToHash("0x00"), - ReceiptHash: common.StringToHash("0x00"), - // Bloom: - Difficulty: big.NewInt(88888888), - Number: big.NewInt(16), - GasLimit: big.NewInt(70000), - GasUsed: big.NewInt(25000), - Time: 124356789, - Extra: nil, - MixDigest: common.StringToHash("0x00"), - Nonce: [8]byte{0, 1, 2, 3, 4, 5, 6, 7}, - } - return header -} - -func makeBlock() *types.Block { - parentHash := common.HexToHash("0x01") - coinbase := common.HexToAddress("0x01") - root := common.HexToHash("0x01") - difficulty := common.Big1 - nonce := uint64(1) - block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, nil) - - txto := common.HexToAddress("0x02") - txamount := big.NewInt(1) - txgasAmount := big.NewInt(1) - txgasPrice := big.NewInt(1) - txdata := []byte{1, 2, 3} - - tx := types.NewTransactionMessage(txto, txamount, txgasAmount, txgasPrice, txdata) - txs := make([]*types.Transaction, 1) - txs[0] = tx - block.SetTransactions(txs) - - uncles := make([]*types.Header, 1) - uncles[0] = makeHeader() - block.SetUncles(uncles) - - return block -} diff --git a/rpc/types.go b/rpc/types.go deleted file mode 100644 index 1f49a3dea..000000000 --- a/rpc/types.go +++ /dev/null @@ -1,381 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -package rpc - -import ( - "encoding/binary" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - "strings" - - "errors" - "net" - "net/http" - "time" - - "io" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -type hexdata struct { - data []byte - isNil bool -} - -func (d *hexdata) String() string { - return "0x" + common.Bytes2Hex(d.data) -} - -func (d *hexdata) MarshalJSON() ([]byte, error) { - if d.isNil { - return json.Marshal(nil) - } - return json.Marshal(d.String()) -} - -func newHexData(input interface{}) *hexdata { - d := new(hexdata) - - if input == nil { - d.isNil = true - return d - } - switch input := input.(type) { - case []byte: - d.data = input - case common.Hash: - d.data = input.Bytes() - case *common.Hash: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case common.Address: - d.data = input.Bytes() - case *common.Address: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case types.Bloom: - d.data = input.Bytes() - case *types.Bloom: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case *big.Int: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case int64: - d.data = big.NewInt(input).Bytes() - case uint64: - buff := make([]byte, 8) - binary.BigEndian.PutUint64(buff, input) - d.data = buff - case int: - d.data = big.NewInt(int64(input)).Bytes() - case uint: - d.data = big.NewInt(int64(input)).Bytes() - case int8: - d.data = big.NewInt(int64(input)).Bytes() - case uint8: - d.data = big.NewInt(int64(input)).Bytes() - case int16: - d.data = big.NewInt(int64(input)).Bytes() - case uint16: - buff := make([]byte, 2) - binary.BigEndian.PutUint16(buff, input) - d.data = buff - case int32: - d.data = big.NewInt(int64(input)).Bytes() - case uint32: - buff := make([]byte, 4) - binary.BigEndian.PutUint32(buff, input) - d.data = buff - case string: // hexstring - // aaargh ffs TODO: avoid back-and-forth hex encodings where unneeded - bytes, err := hex.DecodeString(strings.TrimPrefix(input, "0x")) - if err != nil { - d.isNil = true - } else { - d.data = bytes - } - default: - d.isNil = true - } - - return d -} - -type hexnum struct { - data []byte - isNil bool -} - -func (d *hexnum) String() string { - // Get hex string from bytes - out := common.Bytes2Hex(d.data) - // Trim leading 0s - out = strings.TrimLeft(out, "0") - // Output "0x0" when value is 0 - if len(out) == 0 { - out = "0" - } - return "0x" + out -} - -func (d *hexnum) MarshalJSON() ([]byte, error) { - if d.isNil { - return json.Marshal(nil) - } - return json.Marshal(d.String()) -} - -func newHexNum(input interface{}) *hexnum { - d := new(hexnum) - - d.data = newHexData(input).data - - return d -} - -type RpcConfig struct { - ListenAddress string - ListenPort uint - CorsDomain string -} - -type InvalidTypeError struct { - method string - msg string -} - -func (e *InvalidTypeError) Error() string { - return fmt.Sprintf("invalid type on field %s: %s", e.method, e.msg) -} - -func NewInvalidTypeError(method, msg string) *InvalidTypeError { - return &InvalidTypeError{ - method: method, - msg: msg, - } -} - -type InsufficientParamsError struct { - have int - want int -} - -func (e *InsufficientParamsError) Error() string { - return fmt.Sprintf("insufficient params, want %d have %d", e.want, e.have) -} - -func NewInsufficientParamsError(have int, want int) *InsufficientParamsError { - return &InsufficientParamsError{ - have: have, - want: want, - } -} - -type NotImplementedError struct { - Method string -} - -func (e *NotImplementedError) Error() string { - return fmt.Sprintf("%s method not implemented", e.Method) -} - -func NewNotImplementedError(method string) *NotImplementedError { - return &NotImplementedError{ - Method: method, - } -} - -type NotAvailableError struct { - Method string - Reason string -} - -func (e *NotAvailableError) Error() string { - return fmt.Sprintf("%s method not available: %s", e.Method, e.Reason) -} - -func NewNotAvailableError(method string, reason string) *NotAvailableError { - return &NotAvailableError{ - Method: method, - Reason: reason, - } -} - -type DecodeParamError struct { - err string -} - -func (e *DecodeParamError) Error() string { - return fmt.Sprintf("could not decode, %s", e.err) - -} - -func NewDecodeParamError(errstr string) error { - return &DecodeParamError{ - err: errstr, - } -} - -type ValidationError struct { - ParamName string - msg string -} - -func (e *ValidationError) Error() string { - return fmt.Sprintf("%s not valid, %s", e.ParamName, e.msg) -} - -func NewValidationError(param string, msg string) error { - return &ValidationError{ - ParamName: param, - msg: msg, - } -} - -type RpcRequest struct { - Id interface{} `json:"id"` - Jsonrpc string `json:"jsonrpc"` - Method string `json:"method"` - Params json.RawMessage `json:"params"` -} - -type RpcSuccessResponse struct { - Id interface{} `json:"id"` - Jsonrpc string `json:"jsonrpc"` - Result interface{} `json:"result"` -} - -type RpcErrorResponse struct { - Id interface{} `json:"id"` - Jsonrpc string `json:"jsonrpc"` - Error *RpcErrorObject `json:"error"` -} - -type RpcErrorObject struct { - Code int `json:"code"` - Message string `json:"message"` - // Data interface{} `json:"data"` -} - -type listenerHasStoppedError struct { - msg string -} - -func (self listenerHasStoppedError) Error() string { - return self.msg -} - -var listenerStoppedError = listenerHasStoppedError{"Listener stopped"} - -// When https://github.com/golang/go/issues/4674 is fixed this could be replaced -type stoppableTCPListener struct { - *net.TCPListener - stop chan struct{} // closed when the listener must stop -} - -// Wraps the default handler and checks if the RPC service was stopped. In that case it returns an -// error indicating that the service was stopped. This will only happen for connections which are -// kept open (HTTP keep-alive) when the RPC service was shutdown. -func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - select { - case <-stop: - w.Header().Set("Content-Type", "application/json") - jsonerr := &RpcErrorObject{-32603, "RPC service stopped"} - send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) - default: - h.ServeHTTP(w, r) - } - }) -} - -// Stop the listener and all accepted and still active connections. -func (self *stoppableTCPListener) Stop() { - close(self.stop) -} - -func newStoppableTCPListener(addr string) (*stoppableTCPListener, error) { - wl, err := net.Listen("tcp", addr) - if err != nil { - return nil, err - } - - if tcpl, ok := wl.(*net.TCPListener); ok { - stop := make(chan struct{}) - l := &stoppableTCPListener{tcpl, stop} - return l, nil - } - - return nil, errors.New("Unable to create TCP listener for RPC service") -} - -func (self *stoppableTCPListener) Accept() (net.Conn, error) { - for { - self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second))) - c, err := self.TCPListener.AcceptTCP() - - select { - case <-self.stop: - if c != nil { // accept timeout - c.Close() - } - self.TCPListener.Close() - return nil, listenerStoppedError - default: - } - - if err != nil { - if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() { - continue // regular timeout - } - } - - return &closableConnection{c, self.stop}, err - } -} - -type closableConnection struct { - *net.TCPConn - closed chan struct{} -} - -func (self *closableConnection) Read(b []byte) (n int, err error) { - select { - case <-self.closed: - self.TCPConn.Close() - return 0, io.EOF - default: - return self.TCPConn.Read(b) - } -} diff --git a/rpc/types_test.go b/rpc/types_test.go deleted file mode 100644 index 9ef7b8d38..000000000 --- a/rpc/types_test.go +++ /dev/null @@ -1,204 +0,0 @@ -package rpc - -import ( - "bytes" - "encoding/json" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -func TestInvalidTypeError(t *testing.T) { - err := NewInvalidTypeError("testField", "not string") - expected := "invalid type on field testField: not string" - - if err.Error() != expected { - t.Error(err.Error()) - } -} - -func TestInsufficientParamsError(t *testing.T) { - err := NewInsufficientParamsError(0, 1) - expected := "insufficient params, want 1 have 0" - - if err.Error() != expected { - t.Error(err.Error()) - } -} - -func TestNotImplementedError(t *testing.T) { - err := NewNotImplementedError("foo") - expected := "foo method not implemented" - - if err.Error() != expected { - t.Error(err.Error()) - } -} - -func TestDecodeParamError(t *testing.T) { - err := NewDecodeParamError("foo") - expected := "could not decode, foo" - - if err.Error() != expected { - t.Error(err.Error()) - } -} - -func TestValidationError(t *testing.T) { - err := NewValidationError("foo", "should be `bar`") - expected := "foo not valid, should be `bar`" - - if err.Error() != expected { - t.Error(err.Error()) - } -} - -func TestHexdataMarshalNil(t *testing.T) { - hd := newHexData([]byte{}) - hd.isNil = true - v, _ := json.Marshal(hd) - if string(v) != "null" { - t.Errorf("Expected null, got %s", v) - } -} - -func TestHexnumMarshalNil(t *testing.T) { - hn := newHexNum([]byte{}) - hn.isNil = true - v, _ := json.Marshal(hn) - if string(v) != "null" { - t.Errorf("Expected null, got %s", v) - } -} - -func TestHexdataNil(t *testing.T) { - v := newHexData(nil) - if v.isNil != true { - t.Errorf("Expected isNil to be true, but is %v", v.isNil) - } -} - -func TestHexdataPtrHash(t *testing.T) { - in := common.Hash{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} - v := newHexData(&in) - if bytes.Compare(in.Bytes(), v.data) != 0 { - t.Errorf("Got % x expected % x", in, v.data) - } -} - -func TestHexdataPtrHashNil(t *testing.T) { - var in *common.Hash - in = nil - v := newHexData(in) - if !v.isNil { - t.Errorf("Expect isNil to be true, but is %v", v.isNil) - } -} - -func TestHexdataPtrAddress(t *testing.T) { - in := common.Address{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} - v := newHexData(&in) - if bytes.Compare(in.Bytes(), v.data) != 0 { - t.Errorf("Got % x expected % x", in, v.data) - } -} - -func TestHexdataPtrAddressNil(t *testing.T) { - var in *common.Address - in = nil - v := newHexData(in) - if !v.isNil { - t.Errorf("Expect isNil to be true, but is %v", v.isNil) - } -} - -func TestHexdataPtrBloom(t *testing.T) { - in := types.Bloom{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} - v := newHexData(&in) - if bytes.Compare(in.Bytes(), v.data) != 0 { - t.Errorf("Got % x expected % x", in, v.data) - } -} - -func TestHexdataPtrBloomNil(t *testing.T) { - var in *types.Bloom - in = nil - v := newHexData(in) - if !v.isNil { - t.Errorf("Expect isNil to be true, but is %v", v.isNil) - } -} - -func TestHexdataBigintNil(t *testing.T) { - var in *big.Int - in = nil - v := newHexData(in) - if !v.isNil { - t.Errorf("Expect isNil to be true, but is %v", v.isNil) - } -} - -func TestHexdataUint(t *testing.T) { - var in = uint(16) - var expected = []byte{0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} - -func TestHexdataInt8(t *testing.T) { - var in = int8(16) - var expected = []byte{0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} - -func TestHexdataUint8(t *testing.T) { - var in = uint8(16) - var expected = []byte{0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} - -func TestHexdataInt16(t *testing.T) { - var in = int16(16) - var expected = []byte{0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} - -func TestHexdataUint16(t *testing.T) { - var in = uint16(16) - var expected = []byte{0x0, 0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} - -func TestHexdataInt32(t *testing.T) { - var in = int32(16) - var expected = []byte{0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} - -func TestHexdataUint32(t *testing.T) { - var in = uint32(16) - var expected = []byte{0x0, 0x0, 0x0, 0x10} - v := newHexData(in) - if bytes.Compare(expected, v.data) != 0 { - t.Errorf("Expected % x got % x", expected, v.data) - } -} From 603192cfa7eb081d9504170677045794cff3b7ab Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Wed, 17 Jun 2015 16:33:34 +0200 Subject: [PATCH 091/110] cleanup comments/code --- cmd/geth/js.go | 51 ------------------------- rpc/comms/inproc.go | 20 +++++----- rpc/jeth.go | 93 ++------------------------------------------- 3 files changed, 13 insertions(+), 151 deletions(-) diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 2ae4817b3..bb5143170 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -279,57 +279,6 @@ func (js *jsre) apiBindings(f xeth.Frontend) error { return nil } -/* -func (js *jsre) apiBindings(ipcpath string, f xeth.Frontend) { - xe := xeth.New(js.ethereum, f) - apiNames, err := js.suportedApis(ipcpath) - if err != nil { - return - } - - ethApi := rpc.NewEthereumApi(xe) - jeth := rpc.NewJeth(ethApi, js.re, ipcpath) - - js.re.Set("jeth", struct{}{}) - t, _ := js.re.Get("jeth") - jethObj := t.Object() - - jethObj.Set("send", jeth.Send) - jethObj.Set("sendAsync", jeth.Send) - - err := js.re.Compile("bignumber.js", re.BigNumber_JS) - if err != nil { - utils.Fatalf("Error loading bignumber.js: %v", err) - } - - err = js.re.Compile("ethereum.js", re.Web3_JS) - if err != nil { - utils.Fatalf("Error loading ethereum.js: %v", err) - } - - _, err = js.re.Eval("var web3 = require('web3');") - if err != nil { - utils.Fatalf("Error requiring web3: %v", err) - } - - _, err = js.re.Eval("web3.setProvider(jeth)") - if err != nil { - utils.Fatalf("Error setting web3 provider: %v", err) - } - _, err = js.re.Eval(` -var eth = web3.eth; -var shh = web3.shh; -var db = web3.db; -var net = web3.net; - `) - if err != nil { - utils.Fatalf("Error setting namespaces: %v", err) - } - - js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");") -} -*/ - var ds, _ = docserver.New("/") func (self *jsre) ConfirmTransaction(tx string) bool { diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go index 89cb93cdc..1fdbf8ace 100644 --- a/rpc/comms/inproc.go +++ b/rpc/comms/inproc.go @@ -1,21 +1,22 @@ package comms import ( - "github.com/ethereum/go-ethereum/rpc/api" - "github.com/ethereum/go-ethereum/rpc/shared" "fmt" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/xeth" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" + "github.com/ethereum/go-ethereum/xeth" ) type InProcClient struct { - api api.EthereumApi - codec codec.Codec - lastId interface{} + api api.EthereumApi + codec codec.Codec + lastId interface{} lastJsonrpc string - lastErr error - lastRes interface{} + lastErr error + lastRes interface{} } // Create a new in process client @@ -49,5 +50,4 @@ func (self *InProcClient) Send(req interface{}) error { func (self *InProcClient) Recv() (interface{}, error) { return self.lastRes, self.lastErr - //return *shared.NewRpcResponse(self.lastId, self.lastJsonrpc, self.lastRes, self.lastErr), nil } diff --git a/rpc/jeth.go b/rpc/jeth.go index 08d6a9878..e656e8fa9 100644 --- a/rpc/jeth.go +++ b/rpc/jeth.go @@ -1,13 +1,13 @@ package rpc import ( + "encoding/json" + "github.com/ethereum/go-ethereum/jsre" "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/comms" "github.com/ethereum/go-ethereum/rpc/shared" "github.com/robertkrimen/otto" - "encoding/json" - "fmt" ) type Jeth struct { @@ -31,7 +31,6 @@ func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface return } - func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { reqif, err := call.Argument(0).Export() if err != nil { @@ -53,14 +52,12 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { for i, req := range reqs { var respif interface{} - err := self.client.Send(&req)//self.ethApi.Execute(&req) + err := self.client.Send(&req) if err != nil { - fmt.Println("Error request:", err) return self.err(call, -32603, err.Error(), req.Id) } respif, err = self.client.Recv() if err != nil { - fmt.Println("Error response:", err) return self.err(call, -32603, err.Error(), req.Id) } @@ -91,87 +88,3 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { return } - -/* -func (self *Jeth) SendIpc(call otto.FunctionCall) (response otto.Value) { - reqif, err := call.Argument(0).Export() - if err != nil { - return self.err(call, -32700, err.Error(), nil) - } - - client, err := comms.NewIpcClient(comms.IpcConfig{self.ipcpath}, codec.JSON) - if err != nil { - fmt.Println("Unable to connect to geth.") - return self.err(call, -32603, err.Error(), -1) - } - defer client.Close() - - jsonreq, err := json.Marshal(reqif) - var reqs []shared.Request - batch := true - err = json.Unmarshal(jsonreq, &reqs) - if err != nil { - reqs = make([]shared.Request, 1) - err = json.Unmarshal(jsonreq, &reqs[0]) - batch = false - } - - call.Otto.Set("response_len", len(reqs)) - call.Otto.Run("var ret_response = new Array(response_len);") - - for i, req := range reqs { - err := client.Send(&req) - if err != nil { - fmt.Println("Error send request:", err) - return self.err(call, -32603, err.Error(), req.Id) - } - - respif, err := client.Recv() - if err != nil { - fmt.Println("Error recv response:", err) - return self.err(call, -32603, err.Error(), req.Id) - } - - if res, ok := respif.(shared.SuccessResponse); ok { - call.Otto.Set("ret_id", res.Id) - call.Otto.Set("ret_jsonrpc", res.Jsonrpc) - resObj, _ := json.Marshal(res.Result) - call.Otto.Set("ret_result", string(resObj)) - call.Otto.Set("response_idx", i) - - response, err = call.Otto.Run(` - ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) }; - `) - } else if res, ok := respif.(shared.ErrorResponse); ok { - fmt.Printf("Error: %s (%d)\n", res.Error.Message, res.Error.Code) - - call.Otto.Set("ret_id", res.Id) - call.Otto.Set("ret_jsonrpc", res.Jsonrpc) - call.Otto.Set("ret_error", res.Error) - call.Otto.Set("response_idx", i) - - response, _ = call.Otto.Run(` - ret_response = { jsonrpc: ret_jsonrpc, id: ret_id, error: ret_error }; - `) - return - } else { - fmt.Printf("unexpected response\n", reflect.TypeOf(respif)) - } - } - - if !batch { - call.Otto.Run("ret_response = ret_response[0];") - } - - if call.Argument(1).IsObject() { - call.Otto.Set("callback", call.Argument(1)) - call.Otto.Run(` - if (Object.prototype.toString.call(callback) == '[object Function]') { - callback(null, ret_response); - } - `) - } - - return -} -*/ From 36a6b16a3bec15131318ebed1c8c2f9204a5a328 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Thu, 18 Jun 2015 09:46:20 +0200 Subject: [PATCH 092/110] removed console command --- Makefile | 5 - cmd/console/admin.go | 9 - cmd/console/contracts.go | 6 - cmd/console/js.go | 454 --------------------------------------- cmd/console/main.go | 103 --------- 5 files changed, 577 deletions(-) delete mode 100644 cmd/console/admin.go delete mode 100644 cmd/console/contracts.go delete mode 100644 cmd/console/js.go delete mode 100644 cmd/console/main.go diff --git a/Makefile b/Makefile index b243d2679..03e3bf4c6 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,6 @@ geth: @echo "Done building." @echo "Run \"$(GOBIN)/geth\" to launch geth." -console: - build/env.sh go install -v $(shell build/ldflags.sh) ./cmd/console - @echo "Done building." - @echo "Run \"$(GOBIN)/console\" to launch the console." - mist: build/env.sh go install -v $(shell build/ldflags.sh) ./cmd/mist @echo "Done building." diff --git a/cmd/console/admin.go b/cmd/console/admin.go deleted file mode 100644 index dee88e3a0..000000000 --- a/cmd/console/admin.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -/* -node admin bindings -*/ - -func (js *jsre) adminBindings() { - -} diff --git a/cmd/console/contracts.go b/cmd/console/contracts.go deleted file mode 100644 index 1f27838d1..000000000 --- a/cmd/console/contracts.go +++ /dev/null @@ -1,6 +0,0 @@ -package main - -var ( - globalRegistrar = `var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]);` - globalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b" -) diff --git a/cmd/console/js.go b/cmd/console/js.go deleted file mode 100644 index 15ea9bedd..000000000 --- a/cmd/console/js.go +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301 USA - -package main - -import ( - "bufio" - "fmt" - "math/big" - "os" - "os/signal" - "path/filepath" - "strings" - - "encoding/json" - - "sort" - - "github.com/codegangsta/cli" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common/docserver" - re "github.com/ethereum/go-ethereum/jsre" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/rpc/api" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/comms" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/peterh/liner" - "github.com/robertkrimen/otto" -) - -type prompter interface { - AppendHistory(string) - Prompt(p string) (string, error) - PasswordPrompt(p string) (string, error) -} - -type dumbterm struct{ r *bufio.Reader } - -func (r dumbterm) Prompt(p string) (string, error) { - fmt.Print(p) - line, err := r.r.ReadString('\n') - return strings.TrimSuffix(line, "\n"), err -} - -func (r dumbterm) PasswordPrompt(p string) (string, error) { - fmt.Println("!! Unsupported terminal, password will echo.") - fmt.Print(p) - input, err := bufio.NewReader(os.Stdin).ReadString('\n') - fmt.Println() - return input, err -} - -func (r dumbterm) AppendHistory(string) {} - -type jsre struct { - re *re.JSRE - wait chan *big.Int - ps1 string - atexit func() - datadir string - prompter -} - -var ( - loadedModulesMethods map[string][]string -) - -func loadAutoCompletion(js *jsre, ipcpath string) { - modules, err := js.suportedApis(ipcpath) - if err != nil { - utils.Fatalf("Unable to determine supported modules - %v", err) - } - - loadedModulesMethods = make(map[string][]string) - for module, _ := range modules { - loadedModulesMethods[module] = api.AutoCompletion[module] - } -} - -func keywordCompleter(line string) []string { - results := make([]string, 0) - - if strings.Contains(line, ".") { - elements := strings.Split(line, ".") - if len(elements) == 2 { - module := elements[0] - partialMethod := elements[1] - if methods, found := loadedModulesMethods[module]; found { - for _, method := range methods { - if strings.HasPrefix(method, partialMethod) { // e.g. debug.se - results = append(results, module+"."+method) - } - } - } - } - } else { - for module, methods := range loadedModulesMethods { - if line == module { // user typed in full module name, show all methods - for _, method := range methods { - results = append(results, module+"."+method) - } - } else if strings.HasPrefix(module, line) { // partial method name, e.g. admi - results = append(results, module) - } - } - } - return results -} - -func apiWordCompleter(line string, pos int) (head string, completions []string, tail string) { - if len(line) == 0 { - return "", nil, "" - } - - i := 0 - for i = pos - 1; i > 0; i-- { - if line[i] == '.' || (line[i] >= 'a' && line[i] <= 'z') || (line[i] >= 'A' && line[i] <= 'Z') { - continue - } - if i >= 3 && line[i] == '3' && line[i-3] == 'w' && line[i-2] == 'e' && line[i-1] == 'b' { - continue - } - i += 1 - break - } - - begin := line[:i] - keyword := line[i:pos] - end := line[pos:] - - completionWords := keywordCompleter(keyword) - return begin, completionWords, end -} - -func newJSRE(libPath, ipcpath string) *jsre { - js := &jsre{ps1: "> "} - js.wait = make(chan *big.Int) - - // update state in separare forever blocks - js.re = re.New(libPath) - js.apiBindings(ipcpath) - - if !liner.TerminalSupported() { - js.prompter = dumbterm{bufio.NewReader(os.Stdin)} - } else { - lr := liner.NewLiner() - js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) }) - lr.SetCtrlCAborts(true) - loadAutoCompletion(js, ipcpath) - lr.SetWordCompleter(apiWordCompleter) - lr.SetTabCompletionStyle(liner.TabPrints) - js.prompter = lr - js.atexit = func() { - js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) }) - lr.Close() - close(js.wait) - } - } - return js -} - -func (js *jsre) apiBindings(ipcpath string) { - ethApi := rpc.NewEthereumApi(nil) - jeth := rpc.NewJeth(ethApi, js.re, ipcpath) - - js.re.Set("jeth", struct{}{}) - t, _ := js.re.Get("jeth") - jethObj := t.Object() - jethObj.Set("send", jeth.SendIpc) - jethObj.Set("sendAsync", jeth.SendIpc) - - err := js.re.Compile("bignumber.js", re.BigNumber_JS) - if err != nil { - utils.Fatalf("Error loading bignumber.js: %v", err) - } - - err = js.re.Compile("ethereum.js", re.Web3_JS) - if err != nil { - utils.Fatalf("Error loading web3.js: %v", err) - } - - _, err = js.re.Eval("var web3 = require('web3');") - if err != nil { - utils.Fatalf("Error requiring web3: %v", err) - } - - _, err = js.re.Eval("web3.setProvider(jeth)") - if err != nil { - utils.Fatalf("Error setting web3 provider: %v", err) - } - - apis, err := js.suportedApis(ipcpath) - if err != nil { - utils.Fatalf("Unable to determine supported api's: %v", err) - } - - // load only supported API's in javascript runtime - shortcuts := "var eth = web3.eth; " - for apiName, _ := range apis { - if apiName == api.Web3ApiName || apiName == api.EthApiName { - continue // manually mapped - } - - if err = js.re.Compile(fmt.Sprintf("%s.js", apiName), api.Javascript(apiName)); err == nil { - shortcuts += fmt.Sprintf("var %s = web3.%s; ", apiName, apiName) - } else { - utils.Fatalf("Error loading %s.js: %v", apiName, err) - } - } - - _, err = js.re.Eval(shortcuts) - - if err != nil { - utils.Fatalf("Error setting namespaces: %v", err) - } - - js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");") -} - -var ds, _ = docserver.New("/") - -/* -func (self *jsre) ConfirmTransaction(tx string) bool { - if self.ethereum.NatSpec { - notice := natspec.GetNotice(self.xeth, tx, ds) - fmt.Println(notice) - answer, _ := self.Prompt("Confirm Transaction [y/n]") - return strings.HasPrefix(strings.Trim(answer, " "), "y") - } else { - return true - } -} - -func (self *jsre) UnlockAccount(addr []byte) bool { - fmt.Printf("Please unlock account %x.\n", addr) - pass, err := self.PasswordPrompt("Passphrase: ") - if err != nil { - return false - } - // TODO: allow retry - if err := self.ethereum.AccountManager().Unlock(common.BytesToAddress(addr), pass); err != nil { - return false - } else { - fmt.Println("Account is now unlocked for this session.") - return true - } -} -*/ - -func (self *jsre) exec(filename string) error { - if err := self.re.Exec(filename); err != nil { - self.re.Stop(false) - return fmt.Errorf("Javascript Error: %v", err) - } - self.re.Stop(true) - return nil -} - -func (self *jsre) suportedApis(ipcpath string) (map[string]string, error) { - config := comms.IpcConfig{ - Endpoint: ipcpath, - } - - client, err := comms.NewIpcClient(config, codec.JSON) - if err != nil { - return nil, err - } - - req := shared.Request{ - Id: 1, - Jsonrpc: "2.0", - Method: "modules", - } - - err = client.Send(req) - if err != nil { - return nil, err - } - - res, err := client.Recv() - if err != nil { - return nil, err - } - - if sucRes, ok := res.(shared.SuccessResponse); ok { - data, _ := json.Marshal(sucRes.Result) - apis := make(map[string]string) - err = json.Unmarshal(data, &apis) - if err == nil { - return apis, nil - } - } - - return nil, fmt.Errorf("Unable to determine supported API's") -} - -// show summary of current geth instance -func (self *jsre) welcome(ipcpath string) { - self.re.Eval(`console.log('instance: ' + web3.version.client);`) - self.re.Eval(`console.log(' datadir: ' + admin.datadir);`) - self.re.Eval(`console.log("coinbase: " + eth.coinbase);`) - self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`) - self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString() - + " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`) - - if modules, err := self.suportedApis(ipcpath); err == nil { - loadedModules := make([]string, 0) - for api, version := range modules { - loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version)) - } - sort.Strings(loadedModules) - - self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " "))) - self.re.Eval(`console.log(" modules: " + modules);`) - } -} - -func (self *jsre) batch(args cli.Args) { - statement := strings.Join(args, " ") - val, err := self.re.Run(statement) - - if err != nil { - fmt.Printf("error: %v", err) - } else if val.IsDefined() && val.IsObject() { - obj, _ := self.re.Get("ret_result") - fmt.Printf("%v", obj) - } else if val.IsDefined() { - fmt.Printf("%v", val) - } - - if self.atexit != nil { - self.atexit() - } - - self.re.Stop(false) -} - -func (self *jsre) interactive(ipcpath string) { - self.welcome(ipcpath) - - // Read input lines. - prompt := make(chan string) - inputln := make(chan string) - go func() { - defer close(inputln) - for { - line, err := self.Prompt(<-prompt) - if err != nil { - return - } - inputln <- line - } - }() - // Wait for Ctrl-C, too. - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt) - - defer func() { - if self.atexit != nil { - self.atexit() - } - self.re.Stop(false) - }() - for { - prompt <- self.ps1 - select { - case <-sig: - fmt.Println("caught interrupt, exiting") - return - case input, ok := <-inputln: - if !ok || indentCount <= 0 && input == "exit" { - return - } - if input == "" { - continue - } - str += input + "\n" - self.setIndent() - if indentCount <= 0 { - hist := str[:len(str)-1] - self.AppendHistory(hist) - self.parseInput(str) - str = "" - } - } - } -} - -func (self *jsre) withHistory(op func(*os.File)) { - hist, err := os.OpenFile(filepath.Join(self.datadir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm) - if err != nil { - fmt.Printf("unable to open history file: %v\n", err) - return - } - op(hist) - hist.Close() -} - -func (self *jsre) parseInput(code string) { - defer func() { - if r := recover(); r != nil { - fmt.Println("[native] error", r) - } - }() - value, err := self.re.Run(code) - if err != nil { - if ottoErr, ok := err.(*otto.Error); ok { - fmt.Println(ottoErr.String()) - } else { - fmt.Println(err) - } - return - } - self.printValue(value) -} - -var indentCount = 0 -var str = "" - -func (self *jsre) setIndent() { - open := strings.Count(str, "{") - open += strings.Count(str, "(") - closed := strings.Count(str, "}") - closed += strings.Count(str, ")") - indentCount = open - closed - if indentCount <= 0 { - self.ps1 = "> " - } else { - self.ps1 = strings.Join(make([]string, indentCount*2), "..") - self.ps1 += " " - } -} - -func (self *jsre) printValue(v interface{}) { - val, err := self.re.PrettyPrint(v) - if err == nil { - fmt.Printf("%v", val) - } -} diff --git a/cmd/console/main.go b/cmd/console/main.go deleted file mode 100644 index 00a9ca9c4..000000000 --- a/cmd/console/main.go +++ /dev/null @@ -1,103 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/** - * @authors - * Jeffrey Wilcke - */ -package main - -import ( - "fmt" - "io" - "os" - - "github.com/codegangsta/cli" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/logger" - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" -) - -const ( - ClientIdentifier = "Geth console" - Version = "0.9.27" -) - -var ( - gitCommit string // set via linker flag - nodeNameVersion string - app = utils.NewApp(Version, "the geth console") -) - -func init() { - if gitCommit == "" { - nodeNameVersion = Version - } else { - nodeNameVersion = Version + "-" + gitCommit[:8] - } - - app.Action = run - app.Flags = []cli.Flag{ - utils.IPCPathFlag, - utils.VerbosityFlag, - utils.JSpathFlag, - } - - app.Before = func(ctx *cli.Context) error { - utils.SetupLogger(ctx) - return nil - } -} - -func main() { - // Wrap the standard output with a colorified stream (windows) - if isatty.IsTerminal(os.Stdout.Fd()) { - if pr, pw, err := os.Pipe(); err == nil { - go io.Copy(colorable.NewColorableStdout(), pr) - os.Stdout = pw - } - } - - var interrupted = false - utils.RegisterInterrupt(func(os.Signal) { - interrupted = true - }) - utils.HandleInterrupt() - - if err := app.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, "Error: ", err) - } - - // we need to run the interrupt callbacks in case gui is closed - // this skips if we got here by actual interrupt stopping the GUI - if !interrupted { - utils.RunInterruptCallbacks(os.Interrupt) - } - logger.Flush() -} - -func run(ctx *cli.Context) { - jspath := ctx.GlobalString(utils.JSpathFlag.Name) - ipcpath := utils.IpcSocketPath(ctx) - repl := newJSRE(jspath, ipcpath) - - if ctx.Args().Present() { - repl.batch(ctx.Args()) - } else { - repl.interactive(ipcpath) - } -} From f20256377731097c9478ede750efffd46d83b494 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Thu, 18 Jun 2015 18:23:13 +0200 Subject: [PATCH 093/110] added attach over ipc command --- cmd/geth/js.go | 89 +++++++++++++++++++++++++++++----------- cmd/geth/main.go | 46 +++++++++++++++++++++ rpc/comms/comms.go | 27 +++++++++++- rpc/comms/http.go | 3 +- rpc/comms/inproc.go | 18 ++++++++ rpc/comms/ipc.go | 68 ++++++++++++++++++++++++++++-- rpc/comms/ipc_unix.go | 12 +++++- rpc/comms/ipc_windows.go | 10 ++++- 8 files changed, 238 insertions(+), 35 deletions(-) diff --git a/cmd/geth/js.go b/cmd/geth/js.go index bb5143170..38ef59583 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -26,6 +26,8 @@ import ( "path/filepath" "strings" + "sort" + "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/docserver" @@ -36,7 +38,6 @@ import ( "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/comms" - "github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/xeth" "github.com/peterh/liner" "github.com/robertkrimen/otto" @@ -137,6 +138,40 @@ func apiWordCompleter(line string, pos int) (head string, completions []string, return begin, completionWords, end } +func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre { + js := &jsre{ps1: "> "} + js.wait = make(chan *big.Int) + js.client = client + + if f == nil { + f = js + } + + // update state in separare forever blocks + js.re = re.New(libPath) + if err := js.apiBindings(f); err != nil { + utils.Fatalf("Unable to initialize console - %v", err) + } + + if !liner.TerminalSupported() || !interactive { + js.prompter = dumbterm{bufio.NewReader(os.Stdin)} + } else { + lr := liner.NewLiner() + //js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) }) + lr.SetCtrlCAborts(true) + js.loadAutoCompletion() + lr.SetWordCompleter(apiWordCompleter) + lr.SetTabCompletionStyle(liner.TabPrints) + js.prompter = lr + js.atexit = func() { + js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) }) + lr.Close() + close(js.wait) + } + } + return js +} + func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre { js := &jsre{ethereum: ethereum, ps1: "> "} // set default cors domain used by startRpc from CLI flag @@ -177,7 +212,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.Et } func (self *jsre) loadAutoCompletion() { - if modules, err := self.suportedApis(); err == nil { + if modules, err := self.supportedApis(); err == nil { loadedModulesMethods = make(map[string][]string) for module, _ := range modules { loadedModulesMethods[module] = api.AutoCompletion[module] @@ -185,34 +220,33 @@ func (self *jsre) loadAutoCompletion() { } } -func (self *jsre) suportedApis() (map[string]string, error) { - req := shared.Request{ - Id: 1, - Jsonrpc: "2.0", - Method: "modules", - } +// show summary of current geth instance +func (self *jsre) welcome() { + self.re.Eval(`console.log('instance: ' + web3.version.client);`) + self.re.Eval(`console.log(' datadir: ' + admin.datadir);`) + self.re.Eval(`console.log("coinbase: " + eth.coinbase);`) + self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`) + self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString() + + " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`) - err := self.client.Send(&req) - if err != nil { - return nil, err - } - - res, err := self.client.Recv() - if err != nil { - return nil, err - } - - if sucRes, ok := res.(map[string]string); ok { - if err == nil { - return sucRes, nil + if modules, err := self.supportedApis(); err == nil { + loadedModules := make([]string, 0) + for api, version := range modules { + loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version)) } - } + sort.Strings(loadedModules) - return nil, fmt.Errorf("Unable to determine supported API's") + self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " "))) + self.re.Eval(`console.log(" modules: " + modules);`) + } +} + +func (self *jsre) supportedApis() (map[string]string, error) { + return self.client.SupportedModules() } func (js *jsre) apiBindings(f xeth.Frontend) error { - apis, err := js.suportedApis() + apis, err := js.supportedApis() if err != nil { return err } @@ -366,7 +400,12 @@ func (self *jsre) interactive() { } func (self *jsre) withHistory(op func(*os.File)) { - hist, err := os.OpenFile(filepath.Join(self.ethereum.DataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm) + datadir := common.DefaultDataDir() + if self.ethereum != nil { + datadir = self.ethereum.DataDir + } + + hist, err := os.OpenFile(filepath.Join(datadir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm) if err != nil { fmt.Printf("unable to open history file: %v\n", err) return diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 5c4c33cea..f1e8ace3d 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -204,6 +204,16 @@ nodes. The Geth console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console +`}, + { + Action: attach, + Name: "attach", + Usage: `Geth Console: interactive JavaScript environment`, + Description: ` +The Geth console is an interactive shell for the JavaScript runtime environment +which exposes a node admin interface as well as the Ðapp JavaScript API. +See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console. +This command allows to open a console on a running geth node. `, }, { @@ -297,6 +307,40 @@ func run(ctx *cli.Context) { ethereum.WaitForShutdown() } +func attach(ctx *cli.Context) { + // Wrap the standard output with a colorified stream (windows) + if isatty.IsTerminal(os.Stdout.Fd()) { + if pr, pw, err := os.Pipe(); err == nil { + go io.Copy(colorable.NewColorableStdout(), pr) + os.Stdout = pw + } + } + + var client comms.EthereumClient + var err error + if ctx.Args().Present() { + client, err = comms.ClientFromEndpoint(ctx.Args().First(), codec.JSON) + } else { + cfg := comms.IpcConfig{ + Endpoint: ctx.GlobalString(utils.IPCPathFlag.Name), + } + client, err = comms.NewIpcClient(cfg, codec.JSON) + } + + if err != nil { + utils.Fatalf("Unable to attach to geth node - %v", err) + } + + repl := newLightweightJSRE( + ctx.String(utils.JSpathFlag.Name), + client, + true, + nil) + + repl.welcome() + repl.interactive() +} + func console(ctx *cli.Context) { // Wrap the standard output with a colorified stream (windows) if isatty.IsTerminal(os.Stdout.Fd()) { @@ -323,6 +367,8 @@ func console(ctx *cli.Context) { true, nil, ) + + repl.welcome() repl.interactive() ethereum.Stop() diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 050e7b4e2..7aa94b1ea 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -4,12 +4,14 @@ import ( "io" "net" + "fmt" + "strings" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" - "strings" ) const ( @@ -26,7 +28,7 @@ var ( // List with API's which are offered over thr HTTP/RPC interface by default DefaultHttpRpcApis = strings.Join([]string{ api.DbApiName, api.EthApiName, api.NetApiName, api.Web3ApiName, - }, ",") + }, ",") ) type EthereumClient interface { @@ -36,6 +38,8 @@ type EthereumClient interface { Send(interface{}) error // Receive response Recv() (interface{}, error) + // List with modules this client supports + SupportedModules() (map[string]string, error) } func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) { @@ -64,3 +68,22 @@ func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) { } } } + +// Endpoint must be in the form of: +// ${protocol}:${path} +// e.g. ipc:/tmp/geth.ipc +// rpc:localhost:8545 +func ClientFromEndpoint(endpoint string, c codec.Codec) (EthereumClient, error) { + if strings.HasPrefix(endpoint, "ipc:") { + cfg := IpcConfig{ + Endpoint: endpoint[4:], + } + return NewIpcClient(cfg, codec.JSON) + } + + if strings.HasPrefix(endpoint, "rpc:") { + + } + + return nil, fmt.Errorf("Invalid endpoint") +} diff --git a/rpc/comms/http.go b/rpc/comms/http.go index c0ea2cc78..04630d937 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -64,7 +64,6 @@ func StopHttp() { } } - type httpClient struct { codec codec.ApiCoder } @@ -86,4 +85,4 @@ func (self *httpClient) Send(req interface{}) error { func (self *httpClient) Recv() (interface{}, error) { return nil, nil -} \ No newline at end of file +} diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go index 1fdbf8ace..b9c4e93d9 100644 --- a/rpc/comms/inproc.go +++ b/rpc/comms/inproc.go @@ -51,3 +51,21 @@ func (self *InProcClient) Send(req interface{}) error { func (self *InProcClient) Recv() (interface{}, error) { return self.lastRes, self.lastErr } + +func (self *InProcClient) SupportedModules() (map[string]string, error) { + req := shared.Request{ + Id: 1, + Jsonrpc: "2.0", + Method: "modules", + } + + if res, err := self.api.Execute(&req); err == nil { + if result, ok := res.(map[string]string); ok { + return result, nil + } + } else { + return nil, err + } + + return nil, fmt.Errorf("Invalid response") +} diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go index a07203803..7e7375eaf 100644 --- a/rpc/comms/ipc.go +++ b/rpc/comms/ipc.go @@ -1,8 +1,13 @@ package comms import ( + "fmt" + "net" + "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" + "encoding/json" ) type IpcConfig struct { @@ -10,19 +15,74 @@ type IpcConfig struct { } type ipcClient struct { - codec codec.ApiCoder + endpoint string + codec codec.Codec + coder codec.ApiCoder } func (self *ipcClient) Close() { - self.codec.Close() + self.coder.Close() } func (self *ipcClient) Send(req interface{}) error { - return self.codec.WriteResponse(req) + var err error + if r, ok := req.(*shared.Request); ok { + if err = self.coder.WriteResponse(r); err != nil { + if _, ok := err.(*net.OpError); ok { // connection lost, retry once + if err = self.reconnect(); err == nil { + err = self.coder.WriteResponse(r) + } + } + } + return err + } + + return fmt.Errorf("Invalid request (%T)", req) } func (self *ipcClient) Recv() (interface{}, error) { - return self.codec.ReadResponse() + res, err := self.coder.ReadResponse() + if err != nil { + return nil, err + } + + if r, ok := res.(shared.SuccessResponse); ok { + return r.Result, nil + } + + if r, ok := res.(shared.ErrorResponse); ok { + return r.Error, nil + } + + return res, err +} + +func (self *ipcClient) SupportedModules() (map[string]string, error) { + req := shared.Request{ + Id: 1, + Jsonrpc: "2.0", + Method: "modules", + } + + if err := self.coder.WriteResponse(req); err != nil { + return nil, err + } + + res, err := self.coder.ReadResponse() + if err != nil { + return nil, err + } + + if sucRes, ok := res.(shared.SuccessResponse); ok { + data, _ := json.Marshal(sucRes.Result) + modules := make(map[string]string) + err = json.Unmarshal(data, &modules) + if err == nil { + return modules, nil + } + } + + return nil, fmt.Errorf("Invalid response") } // Create a new IPC client, UNIX domain socket on posix, named pipe on Windows diff --git a/rpc/comms/ipc_unix.go b/rpc/comms/ipc_unix.go index 131fb86f2..b5eec92db 100644 --- a/rpc/comms/ipc_unix.go +++ b/rpc/comms/ipc_unix.go @@ -18,7 +18,17 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) { return nil, err } - return &ipcClient{codec.New(c)}, nil + return &ipcClient{cfg.Endpoint, codec, codec.New(c)}, nil +} + +func (self *ipcClient) reconnect() error { + self.coder.Close() + c, err := net.DialUnix("unix", nil, &net.UnixAddr{self.endpoint, "unix"}) + if err == nil { + self.coder = self.codec.New(c) + } + + return err } func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error { diff --git a/rpc/comms/ipc_windows.go b/rpc/comms/ipc_windows.go index c48dfb7fb..08f79274a 100644 --- a/rpc/comms/ipc_windows.go +++ b/rpc/comms/ipc_windows.go @@ -641,7 +641,15 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) { return nil, err } - return &ipcClient{codec.New(c)}, nil + return &ipcClient{cfg.Endpoint, codec, codec.New(c)}, nil +} + +func (self *ipcClient) reconnect() error { + c, err := Dial(self.endpoint) + if err == nil { + self.coder = self.codec.New(c) + } + return err } func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error { From ce5c94e4719586bbf81906cb90104babf79af0fe Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Fri, 19 Jun 2015 12:32:40 +0200 Subject: [PATCH 094/110] added attach over http/rpc support --- rpc/comms/comms.go | 23 +++++++++ rpc/comms/http.go | 114 +++++++++++++++++++++++++++++++++++++++++++-- rpc/comms/ipc.go | 3 +- 3 files changed, 134 insertions(+), 6 deletions(-) diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 7aa94b1ea..29ad11b3c 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -7,6 +7,8 @@ import ( "fmt" "strings" + "strconv" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/api" @@ -82,7 +84,28 @@ func ClientFromEndpoint(endpoint string, c codec.Codec) (EthereumClient, error) } if strings.HasPrefix(endpoint, "rpc:") { + parts := strings.Split(endpoint, ":") + addr := "http://localhost" + port := uint(8545) + if len(parts) >= 3 { + addr = parts[1] + ":" + parts[2] + } + if len(parts) >= 4 { + p, err := strconv.Atoi(parts[3]) + + if err != nil { + return nil, err + } + port = uint(p) + } + + cfg := HttpConfig{ + ListenAddress: addr, + ListenPort: port, + } + + return NewHttpClient(cfg, codec.JSON), nil } return nil, fmt.Errorf("Invalid endpoint") diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 04630d937..6a543c0ed 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -5,10 +5,14 @@ import ( "net/http" "strings" + "bytes" + "io/ioutil" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" "github.com/rs/cors" ) @@ -65,13 +69,19 @@ func StopHttp() { } type httpClient struct { - codec codec.ApiCoder + address string + port uint + codec codec.ApiCoder + lastRes interface{} + lastErr error } // Create a new in process client -func NewHttpClient(cfg HttpConfig, codec codec.Codec) *httpClient { +func NewHttpClient(cfg HttpConfig, c codec.Codec) *httpClient { return &httpClient{ - codec: codec.New(nil), + address: cfg.ListenAddress, + port: cfg.ListenPort, + codec: c.New(nil), } } @@ -80,9 +90,103 @@ func (self *httpClient) Close() { } func (self *httpClient) Send(req interface{}) error { - return nil + var body []byte + var err error + + self.lastRes = nil + self.lastErr = nil + + if body, err = self.codec.Encode(req); err != nil { + return err + } + + httpReq, err := http.NewRequest("POST", fmt.Sprintf("%s:%d", self.address, self.port), bytes.NewBuffer(body)) + if err != nil { + return err + } + httpReq.Header.Set("Content-Type", "application/json") + + client := http.Client{} + resp, err := client.Do(httpReq) + if err != nil { + return err + } + + defer resp.Body.Close() + + if resp.Status == "200 OK" { + reply, _ := ioutil.ReadAll(resp.Body) + var rpcSuccessResponse shared.SuccessResponse + if err = self.codec.Decode(reply, &rpcSuccessResponse); err == nil { + self.lastRes = rpcSuccessResponse.Result + self.lastErr = err + return nil + } else { + var rpcErrorResponse shared.ErrorResponse + if err = self.codec.Decode(reply, &rpcErrorResponse); err == nil { + self.lastRes = rpcErrorResponse.Error + self.lastErr = err + return nil + } else { + return err + } + } + } + + return fmt.Errorf("Not implemented") } func (self *httpClient) Recv() (interface{}, error) { - return nil, nil + return self.lastRes, self.lastErr +} + +func (self *httpClient) SupportedModules() (map[string]string, error) { + var body []byte + var err error + + payload := shared.Request{ + Id: 1, + Jsonrpc: "2.0", + Method: "modules", + } + + if body, err = self.codec.Encode(payload); err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", fmt.Sprintf("%s:%d", self.address, self.port), bytes.NewBuffer(body)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + if resp.Status == "200 OK" { + reply, _ := ioutil.ReadAll(resp.Body) + var rpcRes shared.SuccessResponse + if err = self.codec.Decode(reply, &rpcRes); err != nil { + return nil, err + } + + result := make(map[string]string) + if modules, ok := rpcRes.Result.(map[string]interface{}); ok { + for a, v := range modules { + result[a] = fmt.Sprintf("%s", v) + } + return result, nil + } + err = fmt.Errorf("Unable to parse module response - %v", rpcRes.Result) + } else { + fmt.Printf("resp.Status = %s\n", resp.Status) + fmt.Printf("err = %v\n", err) + } + + return nil, err } diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go index 7e7375eaf..7f5219300 100644 --- a/rpc/comms/ipc.go +++ b/rpc/comms/ipc.go @@ -4,10 +4,11 @@ import ( "fmt" "net" + "encoding/json" + "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" - "encoding/json" ) type IpcConfig struct { From 29297d3b82eae4d4d23e86cfebec61abf96fffda Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Fri, 19 Jun 2015 13:05:38 +0200 Subject: [PATCH 095/110] fixed bug where history file was create in cwd --- cmd/geth/js.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 38ef59583..6e4e3e0c1 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -157,7 +157,7 @@ func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive js.prompter = dumbterm{bufio.NewReader(os.Stdin)} } else { lr := liner.NewLiner() - //js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) }) + js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) }) lr.SetCtrlCAborts(true) js.loadAutoCompletion() lr.SetWordCompleter(apiWordCompleter) From 3ff272b618b8bd63c9e3068d5f4be5d0b7c7c676 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Fri, 19 Jun 2015 13:40:21 +0200 Subject: [PATCH 096/110] moved solidity test to new rpc structure --- rpc/api/api_test.go | 110 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/rpc/api/api_test.go b/rpc/api/api_test.go index f1a47944d..3e464c281 100644 --- a/rpc/api/api_test.go +++ b/rpc/api/api_test.go @@ -4,6 +4,12 @@ import ( "testing" "github.com/ethereum/go-ethereum/rpc/codec" + "encoding/json" + "strconv" + "github.com/ethereum/go-ethereum/common/compiler" + "github.com/ethereum/go-ethereum/rpc/shared" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/xeth" ) func TestParseApiString(t *testing.T) { @@ -40,3 +46,107 @@ func TestParseApiString(t *testing.T) { } } + +const solcVersion = "0.9.23" + +func TestCompileSolidity(t *testing.T) { + + solc, err := compiler.New("") + if solc == nil { + t.Skip("no solc found: skip") + } else if solc.Version() != solcVersion { + t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion) + } + source := `contract test {\n` + + " /// @notice Will multiply `a` by 7." + `\n` + + ` function multiply(uint a) returns(uint d) {\n` + + ` return a * 7;\n` + + ` }\n` + + `}\n` + + jsonstr := `{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["` + source + `"],"id":64}` + + expCode := "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056" + expAbiDefinition := `[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]` + expUserDoc := `{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}}` + expDeveloperDoc := `{"methods":{}}` + expCompilerVersion := solc.Version() + expLanguage := "Solidity" + expLanguageVersion := "0" + expSource := source + + xeth := xeth.NewTest(ð.Ethereum{}, nil) + api := NewEthApi(xeth, codec.JSON) + + var rpcRequest shared.Request + json.Unmarshal([]byte(jsonstr), &rpcRequest) + + response, err := api.CompileSolidity(&rpcRequest) + if err != nil { + t.Errorf("Execution failed, %v", err) + } + + respjson, err := json.Marshal(response) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + var contracts = make(map[string]*compiler.Contract) + err = json.Unmarshal(respjson, &contracts) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + if len(contracts) != 1 { + t.Errorf("expected one contract, got %v", len(contracts)) + } + + contract := contracts["test"] + + if contract.Code != expCode { + t.Errorf("Expected \n%s got \n%s", expCode, contract.Code) + } + + if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` { + t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source)) + } + + if contract.Info.Language != expLanguage { + t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language) + } + + if contract.Info.LanguageVersion != expLanguageVersion { + t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion) + } + + if contract.Info.CompilerVersion != expCompilerVersion { + t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion) + } + + userdoc, err := json.Marshal(contract.Info.UserDoc) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + devdoc, err := json.Marshal(contract.Info.DeveloperDoc) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + abidef, err := json.Marshal(contract.Info.AbiDefinition) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + if string(abidef) != expAbiDefinition { + t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef)) + } + + if string(userdoc) != expUserDoc { + t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc)) + } + + if string(devdoc) != expDeveloperDoc { + t.Errorf("Expected %s got %s", expDeveloperDoc, string(devdoc)) + } +} From f87501b1c547a1d9cd882497ffafbab4f9941ef1 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Fri, 19 Jun 2015 14:04:18 +0200 Subject: [PATCH 097/110] added batch support to console and attach actions --- cmd/geth/js.go | 19 +++++++++++++++++++ cmd/geth/main.go | 17 +++++++++++++---- cmd/utils/flags.go | 4 ++++ rpc/api/api_test.go | 15 ++++++++------- rpc/api/eth.go | 1 - rpc/api/eth_args.go | 36 ++++++++++++++++++------------------ 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 6e4e3e0c1..761943b63 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -220,6 +220,25 @@ func (self *jsre) loadAutoCompletion() { } } +func (self *jsre) batch(statement string) { + val, err := self.re.Run(statement) + + if err != nil { + fmt.Printf("error: %v", err) + } else if val.IsDefined() && val.IsObject() { + obj, _ := self.re.Get("ret_result") + fmt.Printf("%v", obj) + } else if val.IsDefined() { + fmt.Printf("%v", val) + } + + if self.atexit != nil { + self.atexit() + } + + self.re.Stop(false) +} + // show summary of current geth instance func (self *jsre) welcome() { self.re.Eval(`console.log('instance: ' + web3.version.client);`) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index f1e8ace3d..e5c3614fc 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -255,6 +255,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.IPCDisabledFlag, utils.IPCApiFlag, utils.IPCPathFlag, + utils.ExecFlag, utils.WhisperEnabledFlag, utils.VMDebugFlag, utils.ProtocolVersionFlag, @@ -337,8 +338,12 @@ func attach(ctx *cli.Context) { true, nil) - repl.welcome() - repl.interactive() + if ctx.GlobalString(utils.ExecFlag.Name) != "" { + repl.batch(ctx.GlobalString(utils.ExecFlag.Name)) + } else { + repl.welcome() + repl.interactive() + } } func console(ctx *cli.Context) { @@ -368,8 +373,12 @@ func console(ctx *cli.Context) { nil, ) - repl.welcome() - repl.interactive() + if ctx.GlobalString(utils.ExecFlag.Name) != "" { + repl.batch(ctx.GlobalString(utils.ExecFlag.Name)) + } else { + repl.welcome() + repl.interactive() + } ethereum.Stop() ethereum.WaitForShutdown() diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 092bc5511..a9d449d1f 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -227,6 +227,10 @@ var ( Usage: "Filename for IPC socket/pipe", Value: DirectoryString{common.DefaultIpcPath()}, } + ExecFlag = cli.StringFlag{ + Name: "exec", + Usage: "Execute javascript statement (only in combination with console/attach)", + } // Network Settings MaxPeersFlag = cli.IntFlag{ Name: "maxpeers", diff --git a/rpc/api/api_test.go b/rpc/api/api_test.go index 3e464c281..7e273ef28 100644 --- a/rpc/api/api_test.go +++ b/rpc/api/api_test.go @@ -3,12 +3,13 @@ package api import ( "testing" - "github.com/ethereum/go-ethereum/rpc/codec" "encoding/json" "strconv" + "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/xeth" ) @@ -58,11 +59,11 @@ func TestCompileSolidity(t *testing.T) { t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion) } source := `contract test {\n` + - " /// @notice Will multiply `a` by 7." + `\n` + - ` function multiply(uint a) returns(uint d) {\n` + - ` return a * 7;\n` + - ` }\n` + - `}\n` + " /// @notice Will multiply `a` by 7." + `\n` + + ` function multiply(uint a) returns(uint d) {\n` + + ` return a * 7;\n` + + ` }\n` + + `}\n` jsonstr := `{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["` + source + `"],"id":64}` diff --git a/rpc/api/eth.go b/rpc/api/eth.go index 91577c4d5..cafa05e34 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -250,7 +250,6 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { return v, nil } - func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) { args := new(NewDataArgs) if err := self.codec.Decode(req.Params, &args); err != nil { diff --git a/rpc/api/eth_args.go b/rpc/api/eth_args.go index 54eb7201d..02f438f0c 100644 --- a/rpc/api/eth_args.go +++ b/rpc/api/eth_args.go @@ -227,32 +227,32 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { } type NewDataArgs struct { - Data string + Data string } func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} + var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } - // Check for sufficient params - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } + // Check for sufficient params + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } - data, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("data", "not a string") - } - args.Data = data + data, ok := obj[0].(string) + if !ok { + return shared.NewInvalidTypeError("data", "not a string") + } + args.Data = data - if len(args.Data) == 0 { - return shared.NewValidationError("data", "is required") - } + if len(args.Data) == 0 { + return shared.NewValidationError("data", "is required") + } - return nil + return nil } type NewSigArgs struct { From 2737baa6577a337f33f020d587af100c9bda3585 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 22 Jun 2015 08:14:39 +0200 Subject: [PATCH 098/110] fixed unittests --- cmd/geth/js_test.go | 17 ++++++++++------- rpc/api/admin.go | 29 ----------------------------- 2 files changed, 10 insertions(+), 36 deletions(-) diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go index 20bde01f3..fba575030 100644 --- a/cmd/geth/js_test.go +++ b/cmd/geth/js_test.go @@ -20,6 +20,8 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/rpc/comms" + "github.com/ethereum/go-ethereum/rpc/codec" ) const ( @@ -105,7 +107,8 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) { t.Errorf("Error creating DocServer: %v", err) } tf := &testjethre{ds: ds, stateDb: ethereum.ChainManager().State().Copy()} - repl := newJSRE(ethereum, assetPath, "", "", false, tf) + client := comms.NewInProcClient(codec.JSON) + repl := newJSRE(ethereum, assetPath, "", client, false, tf) tf.jsre = repl return tmp, tf, ethereum } @@ -125,7 +128,7 @@ func TestNodeInfo(t *testing.T) { defer ethereum.Stop() defer os.RemoveAll(tmp) want := `{"DiscPort":0,"IP":"0.0.0.0","ListenAddr":"","Name":"test","NodeID":"4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5","NodeUrl":"enode://4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5@0.0.0.0:0","TCPPort":0,"Td":"131072"}` - checkEvalJSON(t, repl, `admin.nodeInfo()`, want) + checkEvalJSON(t, repl, `admin.nodeInfo`, want) } func TestAccounts(t *testing.T) { @@ -139,7 +142,7 @@ func TestAccounts(t *testing.T) { checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`"]`) checkEvalJSON(t, repl, `eth.coinbase`, `"`+testAddress+`"`) - val, err := repl.re.Run(`admin.newAccount("password")`) + val, err := repl.re.Run(`personal.newAccount("password")`) if err != nil { t.Errorf("expected no error, got %v", err) } @@ -161,7 +164,7 @@ func TestBlockChain(t *testing.T) { defer ethereum.Stop() defer os.RemoveAll(tmp) // get current block dump before export/import. - val, err := repl.re.Run("JSON.stringify(admin.debug.dumpBlock())") + val, err := repl.re.Run("JSON.stringify(debug.dumpBlock(eth.blockNumber))") if err != nil { t.Errorf("expected no error, got %v", err) } @@ -178,14 +181,14 @@ func TestBlockChain(t *testing.T) { ethereum.ChainManager().Reset() - checkEvalJSON(t, repl, `admin.export(`+tmpfileq+`)`, `true`) + checkEvalJSON(t, repl, `admin.exportChain(`+tmpfileq+`)`, `true`) if _, err := os.Stat(tmpfile); err != nil { t.Fatal(err) } // check import, verify that dumpBlock gives the same result. - checkEvalJSON(t, repl, `admin.import(`+tmpfileq+`)`, `true`) - checkEvalJSON(t, repl, `admin.debug.dumpBlock()`, beforeExport) + checkEvalJSON(t, repl, `admin.importChain(`+tmpfileq+`)`, `true`) + checkEvalJSON(t, repl, `debug.dumpBlock(eth.blockNumber)`, beforeExport) } func TestMining(t *testing.T) { diff --git a/rpc/api/admin.go b/rpc/api/admin.go index 532bdcadd..368375c93 100644 --- a/rpc/api/admin.go +++ b/rpc/api/admin.go @@ -23,8 +23,6 @@ const ( var ( // mapping between methods and handlers AdminMapping = map[string]adminhandler{ - // "admin_startRPC": (*adminApi).StartRPC, - // "admin_stopRPC": (*adminApi).StopRPC, "admin_addPeer": (*adminApi).AddPeer, "admin_peers": (*adminApi).Peers, "admin_nodeInfo": (*adminApi).NodeInfo, @@ -103,33 +101,6 @@ func (self *adminApi) Peers(req *shared.Request) (interface{}, error) { return self.ethereum.PeersInfo(), nil } -func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { - return false, nil - // Enable when http rpc interface is refactored to prevent import cycles - // args := new(StartRpcArgs) - // if err := self.codec.Decode(req.Params, &args); err != nil { - // return nil, shared.NewDecodeParamError(err.Error()) - // } - // - // cfg := rpc.RpcConfig{ - // ListenAddress: args.Address, - // ListenPort: args.Port, - // } - // - // err := rpc.Start(self.xeth, cfg) - // if err == nil { - // return true, nil - // } - // return false, err -} - -func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) { - return false, nil - // Enable when http rpc interface is refactored to prevent import cycles - // rpc.Stop() - // return true, nil -} - func (self *adminApi) NodeInfo(req *shared.Request) (interface{}, error) { return self.ethereum.NodeInfo(), nil } From 2e0b56a72b3eafc89938003da29c06496ac9ad4e Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 22 Jun 2015 12:47:32 +0200 Subject: [PATCH 099/110] added RPC start/stop support --- cmd/geth/js.go | 7 +++-- cmd/geth/js_test.go | 2 +- cmd/utils/flags.go | 4 +-- rpc/api/admin.go | 60 ++++++++++++++++++++++++++++++---------- rpc/api/admin_args.go | 52 ++++++++++++++++++++++++++++++++++ rpc/api/admin_js.go | 14 ++++++++++ rpc/api/api.go | 43 +--------------------------- rpc/api/args.go | 3 +- rpc/api/args_test.go | 1 + rpc/api/db.go | 2 +- rpc/api/debug.go | 2 +- rpc/api/eth.go | 2 +- rpc/api/mergedapi.go | 8 +++--- rpc/api/mergedapi_js.go | 1 - rpc/api/miner.go | 2 +- rpc/api/net.go | 2 +- rpc/api/personal.go | 2 +- rpc/api/shh.go | 2 +- rpc/api/txpool.go | 2 +- rpc/api/utils.go | 43 ++++++++++++++-------------- rpc/api/web3.go | 2 +- rpc/comms/comms.go | 9 +++--- rpc/comms/http.go | 4 +-- rpc/comms/http_net.go | 11 ++++---- rpc/comms/inproc.go | 11 ++------ rpc/comms/ipc.go | 4 +-- rpc/comms/ipc_unix.go | 4 +-- rpc/comms/ipc_windows.go | 3 +- rpc/jeth.go | 9 +++--- rpc/shared/types.go | 15 ++++++++++ rpc/shared/utils.go | 28 +++++++++++++++++++ 31 files changed, 224 insertions(+), 130 deletions(-) delete mode 100644 rpc/api/mergedapi_js.go create mode 100644 rpc/shared/utils.go diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 761943b63..c0c77c02a 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -41,6 +41,7 @@ import ( "github.com/ethereum/go-ethereum/xeth" "github.com/peterh/liner" "github.com/robertkrimen/otto" + "github.com/ethereum/go-ethereum/rpc/shared" ) type prompter interface { @@ -183,7 +184,9 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.Et js.wait = js.xeth.UpdateState() js.client = client if clt, ok := js.client.(*comms.InProcClient); ok { - clt.Initialize(js.xeth, ethereum) + if offeredApis, err := api.ParseApiString(shared.AllApis, codec.JSON, js.xeth, ethereum); err == nil { + clt.Initialize(api.Merge(offeredApis...)) + } } // update state in separare forever blocks @@ -311,7 +314,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error { // load only supported API's in javascript runtime shortcuts := "var eth = web3.eth; " for _, apiName := range apiNames { - if apiName == api.Web3ApiName || apiName == api.EthApiName { + if apiName == shared.Web3ApiName || apiName == shared.EthApiName { continue // manually mapped } diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go index fba575030..cfbe26bee 100644 --- a/cmd/geth/js_test.go +++ b/cmd/geth/js_test.go @@ -210,7 +210,7 @@ func TestRPC(t *testing.T) { defer ethereum.Stop() defer os.RemoveAll(tmp) - checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004)`, `true`) + checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004, "*", "web3,eth,net")`, `true`) } func TestCheckTestAccountBalance(t *testing.T) { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a9d449d1f..15a577a07 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -461,7 +461,7 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error { return err } - return comms.StartIpc(config, codec, apis...) + return comms.StartIpc(config, codec, api.Merge(apis...)) } func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error { @@ -479,7 +479,7 @@ func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error { return err } - return comms.StartHttp(config, codec, apis...) + return comms.StartHttp(config, codec, api.Merge(apis...)) } func StartPProf(ctx *cli.Context) { diff --git a/rpc/api/admin.go b/rpc/api/admin.go index 368375c93..7e79fd4d0 100644 --- a/rpc/api/admin.go +++ b/rpc/api/admin.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/comms" "github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/xeth" ) @@ -32,6 +33,8 @@ var ( "admin_chainSyncStatus": (*adminApi).ChainSyncStatus, "admin_setSolc": (*adminApi).SetSolc, "admin_datadir": (*adminApi).DataDir, + "admin_startRPC": (*adminApi).StartRPC, + "admin_stopRPC": (*adminApi).StopRPC, } ) @@ -42,25 +45,25 @@ type adminhandler func(*adminApi, *shared.Request) (interface{}, error) type adminApi struct { xeth *xeth.XEth ethereum *eth.Ethereum - methods map[string]adminhandler - codec codec.ApiCoder + codec codec.Codec + coder codec.ApiCoder } // create a new admin api instance -func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *adminApi { +func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *adminApi { return &adminApi{ xeth: xeth, ethereum: ethereum, - methods: AdminMapping, - codec: coder.New(nil), + codec: codec, + coder: codec.New(nil), } } // collection with supported methods func (self *adminApi) Methods() []string { - methods := make([]string, len(self.methods)) + methods := make([]string, len(AdminMapping)) i := 0 - for k := range self.methods { + for k := range AdminMapping { methods[i] = k i++ } @@ -69,7 +72,7 @@ func (self *adminApi) Methods() []string { // Execute given request func (self *adminApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { + if callback, ok := AdminMapping[req.Method]; ok { return callback(self, req) } @@ -77,7 +80,7 @@ func (self *adminApi) Execute(req *shared.Request) (interface{}, error) { } func (self *adminApi) Name() string { - return AdminApiName + return shared.AdminApiName } func (self *adminApi) ApiVersion() string { @@ -86,7 +89,7 @@ func (self *adminApi) ApiVersion() string { func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) { args := new(AddPeerArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -120,7 +123,7 @@ func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool { func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) { args := new(ImportExportChainArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -163,7 +166,7 @@ func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) { func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) { args := new(ImportExportChainArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -181,7 +184,7 @@ func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) { func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) { args := new(VerbosityArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -202,7 +205,7 @@ func (self *adminApi) ChainSyncStatus(req *shared.Request) (interface{}, error) func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { args := new(SetSolcArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -212,3 +215,32 @@ func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { } return solc.Info(), nil } + +func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { + var err error + args := new(StartRPCArgs) + if err := self.coder.Decode(req.Params, &args); err != nil { + return nil, shared.NewDecodeParamError(err.Error()) + } + + cfg := comms.HttpConfig{ + ListenAddress: args.ListenAddress, + ListenPort: args.ListenPort, + CorsDomain: args.CorsDomain, + } + + if apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum); err == nil { + err = comms.StartHttp(cfg, self.codec, Merge(apis...)) + } + + if err == nil { + return true, nil + } + + return false, err +} + +func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) { + comms.StopHttp() + return true, nil +} diff --git a/rpc/api/admin_args.go b/rpc/api/admin_args.go index 56bb57e20..5437971ca 100644 --- a/rpc/api/admin_args.go +++ b/rpc/api/admin_args.go @@ -95,3 +95,55 @@ func (args *SetSolcArgs) UnmarshalJSON(b []byte) (err error) { return shared.NewInvalidTypeError("path", "not a string") } + +type StartRPCArgs struct { + ListenAddress string + ListenPort uint + CorsDomain string + Apis string +} + +func (args *StartRPCArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + args.ListenAddress = "127.0.0.1" + args.ListenPort = 8545 + args.Apis = "net,eth,web3" + + if len(obj) >= 1 { + if addr, ok := obj[0].(string); ok { + args.ListenAddress = addr + } else { + return shared.NewInvalidTypeError("listenAddress", "not a string") + } + } + + if len(obj) >= 2 { + if port, ok := obj[1].(float64); ok && port >= 0 && port <= 64*1024 { + args.ListenPort = uint(port) + } else { + return shared.NewInvalidTypeError("listenPort", "not a valid port number") + } + } + + if len(obj) >= 3 { + if corsDomain, ok := obj[2].(string); ok { + args.CorsDomain = corsDomain + } else { + return shared.NewInvalidTypeError("corsDomain", "not a string") + } + } + + if len(obj) >= 4 { + if apis, ok := obj[3].(string); ok { + args.Apis = apis + } else { + return shared.NewInvalidTypeError("apis", "not a string") + } + } + + return nil +} diff --git a/rpc/api/admin_js.go b/rpc/api/admin_js.go index c3e713c67..97642ade7 100644 --- a/rpc/api/admin_js.go +++ b/rpc/api/admin_js.go @@ -39,6 +39,20 @@ web3._extend({ params: 1, inputFormatter: [web3._extend.utils.formatInputString], outputFormatter: web3._extend.formatters.formatOutputString + }), + new web3._extend.Method({ + name: 'startRPC', + call: 'admin_startRPC', + params: 4, + inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputInteger,web3._extend.utils.formatInputString,web3._extend.utils.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputBool + }), + new web3._extend.Method({ + name: 'stopRPC', + call: 'admin_stopRPC', + params: 0, + inputFormatter: [], + outputFormatter: web3._extend.formatters.formatOutputBool }) ], properties: diff --git a/rpc/api/api.go b/rpc/api/api.go index 10b448594..ca1ccb9a5 100644 --- a/rpc/api/api.go +++ b/rpc/api/api.go @@ -1,51 +1,10 @@ package api import ( - "strings" - "github.com/ethereum/go-ethereum/rpc/shared" ) -const ( - AdminApiName = "admin" - EthApiName = "eth" - DbApiName = "db" - DebugApiName = "debug" - MergedApiName = "merged" - MinerApiName = "miner" - NetApiName = "net" - ShhApiName = "shh" - TxPoolApiName = "txpool" - PersonalApiName = "personal" - Web3ApiName = "web3" - - JsonRpcVersion = "2.0" -) - -var ( - // All API's - AllApis = strings.Join([]string{ - AdminApiName, DbApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, - ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName, - }, ",") -) - -// Ethereum RPC API interface -type EthereumApi interface { - // API identifier - Name() string - - // API version - ApiVersion() string - - // Execute the given request and returns the response or an error - Execute(*shared.Request) (interface{}, error) - - // List of supported RCP methods this API provides - Methods() []string -} - // Merge multiple API's to a single API instance -func Merge(apis ...EthereumApi) EthereumApi { +func Merge(apis ...shared.EthereumApi) shared.EthereumApi { return newMergedApi(apis...) } diff --git a/rpc/api/args.go b/rpc/api/args.go index 4ef1b26e7..fc85448e6 100644 --- a/rpc/api/args.go +++ b/rpc/api/args.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -54,4 +55,4 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { } args.Word = argstr return nil -} \ No newline at end of file +} diff --git a/rpc/api/args_test.go b/rpc/api/args_test.go index 4153d5432..a30f247bc 100644 --- a/rpc/api/args_test.go +++ b/rpc/api/args_test.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "testing" + "github.com/ethereum/go-ethereum/rpc/shared" ) diff --git a/rpc/api/db.go b/rpc/api/db.go index 745269168..6f10d6447 100644 --- a/rpc/api/db.go +++ b/rpc/api/db.go @@ -63,7 +63,7 @@ func (self *dbApi) Execute(req *shared.Request) (interface{}, error) { } func (self *dbApi) Name() string { - return DbApiName + return shared.DbApiName } func (self *dbApi) ApiVersion() string { diff --git a/rpc/api/debug.go b/rpc/api/debug.go index 5b6a449dc..b451d8662 100644 --- a/rpc/api/debug.go +++ b/rpc/api/debug.go @@ -71,7 +71,7 @@ func (self *debugApi) Execute(req *shared.Request) (interface{}, error) { } func (self *debugApi) Name() string { - return DebugApiName + return shared.DebugApiName } func (self *debugApi) ApiVersion() string { diff --git a/rpc/api/eth.go b/rpc/api/eth.go index cafa05e34..0bb8d449b 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -100,7 +100,7 @@ func (self *ethApi) Execute(req *shared.Request) (interface{}, error) { } func (self *ethApi) Name() string { - return EthApiName + return shared.EthApiName } func (self *ethApi) ApiVersion() string { diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go index 8cf4ae96e..bc4fa32e8 100644 --- a/rpc/api/mergedapi.go +++ b/rpc/api/mergedapi.go @@ -13,14 +13,14 @@ const ( // combines multiple API's type MergedApi struct { apis map[string]string - methods map[string]EthereumApi + methods map[string]shared.EthereumApi } // create new merged api instance -func newMergedApi(apis ...EthereumApi) *MergedApi { +func newMergedApi(apis ...shared.EthereumApi) *MergedApi { mergedApi := new(MergedApi) mergedApi.apis = make(map[string]string, len(apis)) - mergedApi.methods = make(map[string]EthereumApi) + mergedApi.methods = make(map[string]shared.EthereumApi) for _, api := range apis { mergedApi.apis[api.Name()] = api.ApiVersion() @@ -54,7 +54,7 @@ func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) { } func (self *MergedApi) Name() string { - return MergedApiName + return shared.MergedApiName } func (self *MergedApi) ApiVersion() string { diff --git a/rpc/api/mergedapi_js.go b/rpc/api/mergedapi_js.go deleted file mode 100644 index 778f64ec1..000000000 --- a/rpc/api/mergedapi_js.go +++ /dev/null @@ -1 +0,0 @@ -package api diff --git a/rpc/api/miner.go b/rpc/api/miner.go index 0b5e74f52..7a84cb9ae 100644 --- a/rpc/api/miner.go +++ b/rpc/api/miner.go @@ -66,7 +66,7 @@ func (self *minerApi) Methods() []string { } func (self *minerApi) Name() string { - return MinerApiName + return shared.MinerApiName } func (self *minerApi) ApiVersion() string { diff --git a/rpc/api/net.go b/rpc/api/net.go index 247c23827..761654661 100644 --- a/rpc/api/net.go +++ b/rpc/api/net.go @@ -63,7 +63,7 @@ func (self *netApi) Execute(req *shared.Request) (interface{}, error) { } func (self *netApi) Name() string { - return NetApiName + return shared.NetApiName } func (self *netApi) ApiVersion() string { diff --git a/rpc/api/personal.go b/rpc/api/personal.go index 7a6c91c82..b4a63ea7a 100644 --- a/rpc/api/personal.go +++ b/rpc/api/personal.go @@ -66,7 +66,7 @@ func (self *personalApi) Execute(req *shared.Request) (interface{}, error) { } func (self *personalApi) Name() string { - return PersonalApiName + return shared.PersonalApiName } func (self *personalApi) ApiVersion() string { diff --git a/rpc/api/shh.go b/rpc/api/shh.go index e83a7b22e..18a8fd15d 100644 --- a/rpc/api/shh.go +++ b/rpc/api/shh.go @@ -72,7 +72,7 @@ func (self *shhApi) Execute(req *shared.Request) (interface{}, error) { } func (self *shhApi) Name() string { - return ShhApiName + return shared.ShhApiName } func (self *shhApi) ApiVersion() string { diff --git a/rpc/api/txpool.go b/rpc/api/txpool.go index 64550bdaf..25ad6e9b2 100644 --- a/rpc/api/txpool.go +++ b/rpc/api/txpool.go @@ -60,7 +60,7 @@ func (self *txPoolApi) Execute(req *shared.Request) (interface{}, error) { } func (self *txPoolApi) Name() string { - return TxPoolApiName + return shared.TxPoolApiName } func (self *txPoolApi) ApiVersion() string { diff --git a/rpc/api/utils.go b/rpc/api/utils.go index a4ce6409a..9995e1f7c 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/xeth" ) @@ -23,6 +24,8 @@ var ( "chainSyncStatus", "setSolc", "datadir", + "startRPC", + "stopRPC", }, "db": []string{ "getString", @@ -129,35 +132,35 @@ var ( ) // Parse a comma separated API string to individual api's -func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]EthereumApi, error) { +func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]shared.EthereumApi, error) { if len(strings.TrimSpace(apistr)) == 0 { return nil, fmt.Errorf("Empty apistr provided") } names := strings.Split(apistr, ",") - apis := make([]EthereumApi, len(names)) + apis := make([]shared.EthereumApi, len(names)) for i, name := range names { switch strings.ToLower(strings.TrimSpace(name)) { - case AdminApiName: + case shared.AdminApiName: apis[i] = NewAdminApi(xeth, eth, codec) - case DebugApiName: + case shared.DebugApiName: apis[i] = NewDebugApi(xeth, eth, codec) - case DbApiName: + case shared.DbApiName: apis[i] = NewDbApi(xeth, eth, codec) - case EthApiName: + case shared.EthApiName: apis[i] = NewEthApi(xeth, codec) - case MinerApiName: + case shared.MinerApiName: apis[i] = NewMinerApi(eth, codec) - case NetApiName: + case shared.NetApiName: apis[i] = NewNetApi(xeth, eth, codec) - case ShhApiName: + case shared.ShhApiName: apis[i] = NewShhApi(xeth, eth, codec) - case TxPoolApiName: + case shared.TxPoolApiName: apis[i] = NewTxPoolApi(xeth, eth, codec) - case PersonalApiName: + case shared.PersonalApiName: apis[i] = NewPersonalApi(xeth, eth, codec) - case Web3ApiName: + case shared.Web3ApiName: apis[i] = NewWeb3Api(xeth, codec) default: return nil, fmt.Errorf("Unknown API '%s'", name) @@ -169,21 +172,21 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth. func Javascript(name string) string { switch strings.ToLower(strings.TrimSpace(name)) { - case AdminApiName: + case shared.AdminApiName: return Admin_JS - case DebugApiName: + case shared.DebugApiName: return Debug_JS - case DbApiName: + case shared.DbApiName: return Db_JS - case MinerApiName: + case shared.MinerApiName: return Miner_JS - case NetApiName: + case shared.NetApiName: return Net_JS - case ShhApiName: + case shared.ShhApiName: return Shh_JS - case TxPoolApiName: + case shared.TxPoolApiName: return TxPool_JS - case PersonalApiName: + case shared.PersonalApiName: return Personal_JS } diff --git a/rpc/api/web3.go b/rpc/api/web3.go index ed5008446..4c20baa25 100644 --- a/rpc/api/web3.go +++ b/rpc/api/web3.go @@ -60,7 +60,7 @@ func (self *web3Api) Execute(req *shared.Request) (interface{}, error) { } func (self *web3Api) Name() string { - return Web3ApiName + return shared.Web3ApiName } func (self *web3Api) ApiVersion() string { diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 29ad11b3c..bfe625758 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -22,14 +21,14 @@ const ( var ( // List with all API's which are offered over the in proc interface by default - DefaultInProcApis = api.AllApis + DefaultInProcApis = shared.AllApis // List with all API's which are offered over the IPC interface by default - DefaultIpcApis = api.AllApis + DefaultIpcApis = shared.AllApis // List with API's which are offered over thr HTTP/RPC interface by default DefaultHttpRpcApis = strings.Join([]string{ - api.DbApiName, api.EthApiName, api.NetApiName, api.Web3ApiName, + shared.DbApiName, shared.EthApiName, shared.NetApiName, shared.Web3ApiName, }, ",") ) @@ -44,7 +43,7 @@ type EthereumClient interface { SupportedModules() (map[string]string, error) } -func handle(conn net.Conn, api api.EthereumApi, c codec.Codec) { +func handle(conn net.Conn, api shared.EthereumApi, c codec.Codec) { codec := c.New(conn) for { diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 6a543c0ed..ebee791bd 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" "github.com/rs/cors" @@ -28,7 +27,7 @@ type HttpConfig struct { CorsDomain string } -func StartHttp(cfg HttpConfig, codec codec.Codec, apis ...api.EthereumApi) error { +func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error { if httpListener != nil { if fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) != httpListener.Addr().String() { return fmt.Errorf("RPC service already running on %s ", httpListener.Addr().String()) @@ -43,7 +42,6 @@ func StartHttp(cfg HttpConfig, codec codec.Codec, apis ...api.EthereumApi) error } httpListener = l - api := api.Merge(apis...) var handler http.Handler if len(cfg.CorsDomain) > 0 { var opts cors.Options diff --git a/rpc/comms/http_net.go b/rpc/comms/http_net.go index f326f1a7e..acc5f99a9 100644 --- a/rpc/comms/http_net.go +++ b/rpc/comms/http_net.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -90,7 +89,7 @@ func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { case <-stop: w.Header().Set("Content-Type", "application/json") err := fmt.Errorf("RPC service stopped") - response := shared.NewRpcResponse(-1, api.JsonRpcVersion, nil, err) + response := shared.NewRpcResponse(-1, shared.JsonRpcVersion, nil, err) httpSend(w, response) default: h.ServeHTTP(w, r) @@ -110,14 +109,14 @@ func httpSend(writer io.Writer, v interface{}) (n int, err error) { return writer.Write(payload) } -func gethHttpHandler(codec codec.Codec, a api.EthereumApi) http.Handler { +func gethHttpHandler(codec codec.Codec, a shared.EthereumApi) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") // Limit request size to resist DoS if req.ContentLength > maxHttpSizeReqLength { err := fmt.Errorf("Request too large") - response := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32700, err) + response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err) httpSend(w, &response) return } @@ -126,7 +125,7 @@ func gethHttpHandler(codec codec.Codec, a api.EthereumApi) http.Handler { payload, err := ioutil.ReadAll(req.Body) if err != nil { err := fmt.Errorf("Could not read request body") - response := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32700, err) + response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err) httpSend(w, &response) return } @@ -161,7 +160,7 @@ func gethHttpHandler(codec codec.Codec, a api.EthereumApi) http.Handler { // invalid request err = fmt.Errorf("Could not decode request") - res := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32600, err) + res := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32600, err) httpSend(w, res) }) } diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go index b9c4e93d9..5c84b8fd8 100644 --- a/rpc/comms/inproc.go +++ b/rpc/comms/inproc.go @@ -3,15 +3,12 @@ package comms import ( "fmt" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" ) type InProcClient struct { - api api.EthereumApi + api shared.EthereumApi codec codec.Codec lastId interface{} lastJsonrpc string @@ -31,10 +28,8 @@ func (self *InProcClient) Close() { } // Need to setup api support -func (self *InProcClient) Initialize(xeth *xeth.XEth, eth *eth.Ethereum) { - if apis, err := api.ParseApiString(api.AllApis, self.codec, xeth, eth); err == nil { - self.api = api.Merge(apis...) - } +func (self *InProcClient) Initialize(offeredApi shared.EthereumApi) { + self.api = offeredApi } func (self *InProcClient) Send(req interface{}) error { diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go index 7f5219300..068a1288f 100644 --- a/rpc/comms/ipc.go +++ b/rpc/comms/ipc.go @@ -6,7 +6,6 @@ import ( "encoding/json" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -92,7 +91,6 @@ func NewIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) { } // Start IPC server -func StartIpc(cfg IpcConfig, codec codec.Codec, apis ...api.EthereumApi) error { - offeredApi := api.Merge(apis...) +func StartIpc(cfg IpcConfig, codec codec.Codec, offeredApi shared.EthereumApi) error { return startIpc(cfg, codec, offeredApi) } diff --git a/rpc/comms/ipc_unix.go b/rpc/comms/ipc_unix.go index b5eec92db..295eb916b 100644 --- a/rpc/comms/ipc_unix.go +++ b/rpc/comms/ipc_unix.go @@ -8,8 +8,8 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" ) func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) { @@ -31,7 +31,7 @@ func (self *ipcClient) reconnect() error { return err } -func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error { +func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error { os.Remove(cfg.Endpoint) // in case it still exists from a previous run l, err := net.ListenUnix("unix", &net.UnixAddr{Name: cfg.Endpoint, Net: "unix"}) diff --git a/rpc/comms/ipc_windows.go b/rpc/comms/ipc_windows.go index 08f79274a..44c82ef8a 100644 --- a/rpc/comms/ipc_windows.go +++ b/rpc/comms/ipc_windows.go @@ -14,7 +14,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -652,7 +651,7 @@ func (self *ipcClient) reconnect() error { return err } -func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error { +func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error { os.Remove(cfg.Endpoint) // in case it still exists from a previous run l, err := Listen(cfg.Endpoint) diff --git a/rpc/jeth.go b/rpc/jeth.go index e656e8fa9..33fcd6efd 100644 --- a/rpc/jeth.go +++ b/rpc/jeth.go @@ -4,25 +4,24 @@ import ( "encoding/json" "github.com/ethereum/go-ethereum/jsre" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/comms" "github.com/ethereum/go-ethereum/rpc/shared" "github.com/robertkrimen/otto" ) type Jeth struct { - ethApi api.EthereumApi + ethApi shared.EthereumApi re *jsre.JSRE client comms.EthereumClient } -func NewJeth(ethApi api.EthereumApi, re *jsre.JSRE, client comms.EthereumClient) *Jeth { +func NewJeth(ethApi shared.EthereumApi, re *jsre.JSRE, client comms.EthereumClient) *Jeth { return &Jeth{ethApi, re, client} } func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) { rpcerr := &shared.ErrorObject{code, msg} - call.Otto.Set("ret_jsonrpc", api.JsonRpcVersion) + call.Otto.Set("ret_jsonrpc", shared.JsonRpcVersion) call.Otto.Set("ret_id", id) call.Otto.Set("ret_error", rpcerr) response, _ = call.Otto.Run(` @@ -61,7 +60,7 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { return self.err(call, -32603, err.Error(), req.Id) } - call.Otto.Set("ret_jsonrpc", api.JsonRpcVersion) + call.Otto.Set("ret_jsonrpc", shared.JsonRpcVersion) call.Otto.Set("ret_id", req.Id) res, _ := json.Marshal(respif) diff --git a/rpc/shared/types.go b/rpc/shared/types.go index dd38a4559..7c4b04e83 100644 --- a/rpc/shared/types.go +++ b/rpc/shared/types.go @@ -7,6 +7,21 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" ) +// Ethereum RPC API interface +type EthereumApi interface { + // API identifier + Name() string + + // API version + ApiVersion() string + + // Execute the given request and returns the response or an error + Execute(*Request) (interface{}, error) + + // List of supported RCP methods this API provides + Methods() []string +} + // RPC request type Request struct { Id interface{} `json:"id"` diff --git a/rpc/shared/utils.go b/rpc/shared/utils.go new file mode 100644 index 000000000..7953d6c22 --- /dev/null +++ b/rpc/shared/utils.go @@ -0,0 +1,28 @@ +package shared + +import "strings" + +const ( + AdminApiName = "admin" + EthApiName = "eth" + DbApiName = "db" + DebugApiName = "debug" + MergedApiName = "merged" + MinerApiName = "miner" + NetApiName = "net" + ShhApiName = "shh" + TxPoolApiName = "txpool" + PersonalApiName = "personal" + Web3ApiName = "web3" + + JsonRpcVersion = "2.0" +) + +var ( + // All API's + AllApis = strings.Join([]string{ + AdminApiName, DbApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, + ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName, + }, ",") +) + From d36c25bcbcbc1986ab238465a187789c82818238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 22 Jun 2015 14:07:08 +0300 Subject: [PATCH 100/110] eth/fetcher: handle and test block announce DOS attacks --- eth/fetcher/fetcher.go | 46 +++++++++++++++++++++++++++++++------ eth/fetcher/fetcher_test.go | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index b80182a45..8d707da5c 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -20,6 +20,7 @@ const ( fetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block maxUncleDist = 7 // Maximum allowed backward distance from the chain head maxQueueDist = 32 // Maximum allowed distance from the chain head to queue + announceLimit = 256 // Maximum number of unique blocks a peer may have announced ) var ( @@ -74,6 +75,7 @@ type Fetcher struct { quit chan struct{} // Announce states + announces map[string]int // Per peer announce counts to prevent memory exhaustion announced map[common.Hash][]*announce // Announced blocks, scheduled for fetching fetching map[common.Hash]*announce // Announced blocks, currently fetching @@ -98,6 +100,7 @@ func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlo filter: make(chan chan []*types.Block), done: make(chan common.Hash), quit: make(chan struct{}), + announces: make(map[string]int), announced: make(map[common.Hash][]*announce), fetching: make(map[common.Hash]*announce), queue: prque.New(), @@ -189,8 +192,7 @@ func (f *Fetcher) loop() { // Clean up any expired block fetches for hash, announce := range f.fetching { if time.Since(announce.time) > fetchTimeout { - delete(f.announced, hash) - delete(f.fetching, hash) + f.forgetBlock(hash) } } // Import any queued blocks that could potentially fit @@ -217,10 +219,17 @@ func (f *Fetcher) loop() { return case notification := <-f.notify: - // A block was announced, schedule if it's not yet downloading + // A block was announced, make sure the peer isn't DOSing us + count := f.announces[notification.origin] + 1 + if count > announceLimit { + glog.V(logger.Debug).Infof("Peer %s: exceeded outstanding announces (%d)", notification.origin, announceLimit) + break + } + // All is well, schedule the announce if block's not yet downloading if _, ok := f.fetching[notification.hash]; ok { break } + f.announces[notification.origin] = count f.announced[notification.hash] = append(f.announced[notification.hash], notification) if len(f.announced) == 1 { f.reschedule(fetch) @@ -232,8 +241,7 @@ func (f *Fetcher) loop() { case hash := <-f.done: // A pending import finished, remove all traces of the notification - delete(f.announced, hash) - delete(f.fetching, hash) + f.forgetBlock(hash) delete(f.queued, hash) case <-fetch.C: @@ -242,12 +250,15 @@ func (f *Fetcher) loop() { for hash, announces := range f.announced { if time.Since(announces[0].time) > arriveTimeout-gatherSlack { + // Pick a random peer to retrieve from, reset all others announce := announces[rand.Intn(len(announces))] + f.forgetBlock(hash) + + // If the block still didn't arrive, queue for fetching if f.getBlock(hash) == nil { request[announce.origin] = append(request[announce.origin], hash) f.fetching[hash] = announce } - delete(f.announced, hash) } } // Send out all block requests @@ -285,7 +296,7 @@ func (f *Fetcher) loop() { if f.getBlock(hash) == nil { explicit = append(explicit, block) } else { - delete(f.fetching, hash) + f.forgetBlock(hash) } } else { download = append(download, block) @@ -377,3 +388,24 @@ func (f *Fetcher) insert(peer string, block *types.Block) { go f.broadcastBlock(block, false) }() } + +// forgetBlock removes all traces of a block from the fetcher's internal state. +func (f *Fetcher) forgetBlock(hash common.Hash) { + // Remove all pending announces and decrement DOS counters + for _, announce := range f.announced[hash] { + f.announces[announce.origin]-- + if f.announces[announce.origin] == 0 { + delete(f.announces, announce.origin) + } + } + delete(f.announced, hash) + + // Remove any pending fetches and decrement the DOS counters + if announce := f.fetching[hash]; announce != nil { + f.announces[announce.origin]-- + if f.announces[announce.origin] == 0 { + delete(f.announces, announce.origin) + } + delete(f.fetching, hash) + } +} diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 0d069ac65..d594d830c 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -395,3 +395,46 @@ func TestDistantDiscarding(t *testing.T) { t.Fatalf("fetcher queued future block") } } + +// Tests that a peer is unable to use unbounded memory with sending infinite +// block announcements to a node, but that even in the face of such an attack, +// the fetcher remains operational. +func TestAnnounceMemoryExhaustionAttack(t *testing.T) { + tester := newTester() + + // Create a valid chain and an infinite junk chain + hashes := createHashes(announceLimit+2*maxQueueDist, knownHash) + blocks := createBlocksFromHashes(hashes) + valid := tester.makeFetcher(blocks) + + attack := createHashes(announceLimit+2*maxQueueDist, unknownHash) + attacker := tester.makeFetcher(nil) + + // Feed the tester a huge hashset from the attacker, and a limited from the valid peer + for i := 0; i < len(attack); i++ { + if i < maxQueueDist { + tester.fetcher.Notify("valid", hashes[len(hashes)-1-i], time.Now().Add(arriveTimeout/2), valid) + } + tester.fetcher.Notify("attacker", attack[i], time.Now().Add(arriveTimeout/2), attacker) + } + if len(tester.fetcher.announced) != announceLimit+maxQueueDist { + t.Fatalf("queued announce count mismatch: have %d, want %d", len(tester.fetcher.announced), announceLimit+maxQueueDist) + } + // Wait for synchronisation to complete and check success for the valid peer + time.Sleep(2 * arriveTimeout) + if imported := len(tester.blocks); imported != maxQueueDist { + t.Fatalf("partial synchronised block mismatch: have %v, want %v", imported, maxQueueDist) + } + // Feed the remaining valid hashes to ensure DOS protection state remains clean + for i := len(hashes) - maxQueueDist; i >= 0; { + for j := 0; j < maxQueueDist && i >= 0; j++ { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(time.Millisecond), valid) + i-- + } + time.Sleep(256 * time.Millisecond) + } + time.Sleep(256 * time.Millisecond) + if imported := len(tester.blocks); imported != len(hashes) { + t.Fatalf("fully synchronised block mismatch: have %v, want %v", imported, len(hashes)) + } +} From 6d596b1ad106db964d4b6a60d35948b588e32b58 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 22 Jun 2015 13:19:59 +0200 Subject: [PATCH 101/110] fixed eth sign unittest --- rpc/api/eth.go | 4 ++-- rpc/api/eth_args.go | 12 ++++++------ rpc/api/eth_js.go | 17 +++++++++++++++++ rpc/api/utils.go | 2 ++ rpc/shared/utils.go | 1 - 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/rpc/api/eth.go b/rpc/api/eth.go index 0bb8d449b..0dff138c6 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -46,7 +46,7 @@ var ( "eth_getData": (*ethApi).GetData, "eth_getCode": (*ethApi).GetData, "eth_sign": (*ethApi).Sign, - "eth_sendRawTransaction": (*ethApi).PushTx, + "eth_sendRawTransaction": (*ethApi).SendRawTransaction, "eth_sendTransaction": (*ethApi).SendTransaction, "eth_transact": (*ethApi).SendTransaction, "eth_estimateGas": (*ethApi).EstimateGas, @@ -250,7 +250,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { return v, nil } -func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) { +func (self *ethApi) SendRawTransaction(req *shared.Request) (interface{}, error) { args := new(NewDataArgs) if err := self.codec.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) diff --git a/rpc/api/eth_args.go b/rpc/api/eth_args.go index 02f438f0c..bf8ffead6 100644 --- a/rpc/api/eth_args.go +++ b/rpc/api/eth_args.go @@ -466,21 +466,21 @@ func (args *CallArgs) UnmarshalJSON(b []byte) (err error) { } args.Value = num - if ext.Gas == nil { - num = big.NewInt(0) - } else { + if ext.Gas != nil { if num, err = numString(ext.Gas); err != nil { return err } + } else { + num = nil } args.Gas = num - if ext.GasPrice == nil { - num = big.NewInt(0) - } else { + if ext.GasPrice != nil { if num, err = numString(ext.GasPrice); err != nil { return err } + } else { + num = nil } args.GasPrice = num diff --git a/rpc/api/eth_js.go b/rpc/api/eth_js.go index f7630bdd5..e1268eb76 100644 --- a/rpc/api/eth_js.go +++ b/rpc/api/eth_js.go @@ -1,3 +1,20 @@ package api // JS api provided by web3.js +// eth_sign not standard + +const Eth_JS = ` +web3._extend({ + property: 'eth', + methods: + [ + new web3._extend.Method({ + name: 'sign', + call: 'eth_sign', + params: 2, + inputFormatter: [web3._extend.formatters.formatInputString,web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputString + }) + ] +}); +` diff --git a/rpc/api/utils.go b/rpc/api/utils.go index 9995e1f7c..6e4835de6 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -178,6 +178,8 @@ func Javascript(name string) string { return Debug_JS case shared.DbApiName: return Db_JS + case shared.EthApiName: + return Eth_JS case shared.MinerApiName: return Miner_JS case shared.NetApiName: diff --git a/rpc/shared/utils.go b/rpc/shared/utils.go index 7953d6c22..e5d6ad417 100644 --- a/rpc/shared/utils.go +++ b/rpc/shared/utils.go @@ -25,4 +25,3 @@ var ( ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName, }, ",") ) - From 4ee7f6fc88d504f2eac96de4e6e04d72032a933a Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 22 Jun 2015 13:54:13 +0200 Subject: [PATCH 102/110] added missing change for sign test --- cmd/geth/js.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/js.go b/cmd/geth/js.go index c0c77c02a..01840ebd9 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -314,7 +314,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error { // load only supported API's in javascript runtime shortcuts := "var eth = web3.eth; " for _, apiName := range apiNames { - if apiName == shared.Web3ApiName || apiName == shared.EthApiName { + if apiName == shared.Web3ApiName { continue // manually mapped } From 1989d1491a21ec1dd8adb20906e07badc5a2f9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 22 Jun 2015 16:49:47 +0300 Subject: [PATCH 103/110] eth/fetcher: handle and (crude) test block memory DOS --- eth/fetcher/fetcher.go | 61 ++++++++++++++++++++++++--------- eth/fetcher/fetcher_test.go | 67 +++++++++++++++++++++++++++++++++---- 2 files changed, 105 insertions(+), 23 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 8d707da5c..ceca79df0 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -20,7 +20,8 @@ const ( fetchTimeout = 5 * time.Second // Maximum alloted time to return an explicitly requested block maxUncleDist = 7 // Maximum allowed backward distance from the chain head maxQueueDist = 32 // Maximum allowed distance from the chain head to queue - announceLimit = 256 // Maximum number of unique blocks a peer may have announced + hashLimit = 256 // Maximum number of unique blocks a peer may have announced + blockLimit = 64 // Maximum number of unique blocks a per may have delivered ) var ( @@ -80,8 +81,9 @@ type Fetcher struct { fetching map[common.Hash]*announce // Announced blocks, currently fetching // Block cache - queue *prque.Prque // Queue containing the import operations (block number sorted) - queued map[common.Hash]struct{} // Presence set of already queued blocks (to dedup imports) + queue *prque.Prque // Queue containing the import operations (block number sorted) + queues map[string]int // Per peer block counts to prevent memory exhaustion + queued map[common.Hash]*inject // Set of already queued blocks (to dedup imports) // Callbacks getBlock blockRetrievalFn // Retrieves a block from the local chain @@ -104,7 +106,8 @@ func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlo announced: make(map[common.Hash][]*announce), fetching: make(map[common.Hash]*announce), queue: prque.New(), - queued: make(map[common.Hash]struct{}), + queues: make(map[string]int), + queued: make(map[common.Hash]*inject), getBlock: getBlock, validateBlock: validateBlock, broadcastBlock: broadcastBlock, @@ -192,22 +195,24 @@ func (f *Fetcher) loop() { // Clean up any expired block fetches for hash, announce := range f.fetching { if time.Since(announce.time) > fetchTimeout { - f.forgetBlock(hash) + f.forgetHash(hash) } } // Import any queued blocks that could potentially fit height := f.chainHeight() for !f.queue.Empty() { op := f.queue.PopItem().(*inject) - number := op.block.NumberU64() // If too high up the chain or phase, continue later + number := op.block.NumberU64() if number > height+1 { f.queue.Push(op, -float32(op.block.NumberU64())) break } // Otherwise if fresh and still unknown, try and import - if number+maxUncleDist < height || f.getBlock(op.block.Hash()) != nil { + hash := op.block.Hash() + if number+maxUncleDist < height || f.getBlock(hash) != nil { + f.forgetBlock(hash) continue } f.insert(op.origin, op.block) @@ -221,8 +226,8 @@ func (f *Fetcher) loop() { case notification := <-f.notify: // A block was announced, make sure the peer isn't DOSing us count := f.announces[notification.origin] + 1 - if count > announceLimit { - glog.V(logger.Debug).Infof("Peer %s: exceeded outstanding announces (%d)", notification.origin, announceLimit) + if count > hashLimit { + glog.V(logger.Debug).Infof("Peer %s: exceeded outstanding announces (%d)", notification.origin, hashLimit) break } // All is well, schedule the announce if block's not yet downloading @@ -241,8 +246,8 @@ func (f *Fetcher) loop() { case hash := <-f.done: // A pending import finished, remove all traces of the notification + f.forgetHash(hash) f.forgetBlock(hash) - delete(f.queued, hash) case <-fetch.C: // At least one block's timer ran out, check for needing retrieval @@ -252,7 +257,7 @@ func (f *Fetcher) loop() { if time.Since(announces[0].time) > arriveTimeout-gatherSlack { // Pick a random peer to retrieve from, reset all others announce := announces[rand.Intn(len(announces))] - f.forgetBlock(hash) + f.forgetHash(hash) // If the block still didn't arrive, queue for fetching if f.getBlock(hash) == nil { @@ -296,7 +301,7 @@ func (f *Fetcher) loop() { if f.getBlock(hash) == nil { explicit = append(explicit, block) } else { - f.forgetBlock(hash) + f.forgetHash(hash) } } else { download = append(download, block) @@ -339,6 +344,12 @@ func (f *Fetcher) reschedule(fetch *time.Timer) { func (f *Fetcher) enqueue(peer string, block *types.Block) { hash := block.Hash() + // Ensure the peer isn't DOSing us + count := f.queues[peer] + 1 + if count > blockLimit { + glog.V(logger.Debug).Infof("Peer %s: discarded block #%d [%x], exceeded allowance (%d)", peer, block.NumberU64(), hash.Bytes()[:4], blockLimit) + return + } // Discard any past or too distant blocks if dist := int64(block.NumberU64()) - int64(f.chainHeight()); dist < -maxUncleDist || dist > maxQueueDist { glog.V(logger.Debug).Infof("Peer %s: discarded block #%d [%x], distance %d", peer, block.NumberU64(), hash.Bytes()[:4], dist) @@ -346,8 +357,13 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { } // Schedule the block for future importing if _, ok := f.queued[hash]; !ok { - f.queued[hash] = struct{}{} - f.queue.Push(&inject{origin: peer, block: block}, -float32(block.NumberU64())) + op := &inject{ + origin: peer, + block: block, + } + f.queues[peer] = count + f.queued[hash] = op + f.queue.Push(op, -float32(block.NumberU64())) if glog.V(logger.Debug) { glog.Infof("Peer %s: queued block #%d [%x], total %v", peer, block.NumberU64(), hash.Bytes()[:4], f.queue.Size()) @@ -389,8 +405,9 @@ func (f *Fetcher) insert(peer string, block *types.Block) { }() } -// forgetBlock removes all traces of a block from the fetcher's internal state. -func (f *Fetcher) forgetBlock(hash common.Hash) { +// forgetHash removes all traces of a block announcement from the fetcher's +// internal state. +func (f *Fetcher) forgetHash(hash common.Hash) { // Remove all pending announces and decrement DOS counters for _, announce := range f.announced[hash] { f.announces[announce.origin]-- @@ -409,3 +426,15 @@ func (f *Fetcher) forgetBlock(hash common.Hash) { delete(f.fetching, hash) } } + +// forgetBlock removes all traces of a queued block frmo the fetcher's internal +// state. +func (f *Fetcher) forgetBlock(hash common.Hash) { + if insert := f.queued[hash]; insert != nil { + f.queues[insert.origin]-- + if f.queues[insert.origin] == 0 { + delete(f.queues, insert.origin) + } + delete(f.queued, hash) + } +} diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index d594d830c..b9f0f36a5 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -399,15 +399,15 @@ func TestDistantDiscarding(t *testing.T) { // Tests that a peer is unable to use unbounded memory with sending infinite // block announcements to a node, but that even in the face of such an attack, // the fetcher remains operational. -func TestAnnounceMemoryExhaustionAttack(t *testing.T) { +func TestHashMemoryExhaustionAttack(t *testing.T) { tester := newTester() // Create a valid chain and an infinite junk chain - hashes := createHashes(announceLimit+2*maxQueueDist, knownHash) + hashes := createHashes(hashLimit+2*maxQueueDist, knownHash) blocks := createBlocksFromHashes(hashes) valid := tester.makeFetcher(blocks) - attack := createHashes(announceLimit+2*maxQueueDist, unknownHash) + attack := createHashes(hashLimit+2*maxQueueDist, unknownHash) attacker := tester.makeFetcher(nil) // Feed the tester a huge hashset from the attacker, and a limited from the valid peer @@ -417,8 +417,8 @@ func TestAnnounceMemoryExhaustionAttack(t *testing.T) { } tester.fetcher.Notify("attacker", attack[i], time.Now().Add(arriveTimeout/2), attacker) } - if len(tester.fetcher.announced) != announceLimit+maxQueueDist { - t.Fatalf("queued announce count mismatch: have %d, want %d", len(tester.fetcher.announced), announceLimit+maxQueueDist) + if len(tester.fetcher.announced) != hashLimit+maxQueueDist { + t.Fatalf("queued announce count mismatch: have %d, want %d", len(tester.fetcher.announced), hashLimit+maxQueueDist) } // Wait for synchronisation to complete and check success for the valid peer time.Sleep(2 * arriveTimeout) @@ -431,10 +431,63 @@ func TestAnnounceMemoryExhaustionAttack(t *testing.T) { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(time.Millisecond), valid) i-- } - time.Sleep(256 * time.Millisecond) + time.Sleep(500 * time.Millisecond) } - time.Sleep(256 * time.Millisecond) + time.Sleep(500 * time.Millisecond) if imported := len(tester.blocks); imported != len(hashes) { t.Fatalf("fully synchronised block mismatch: have %v, want %v", imported, len(hashes)) } } + +// Tests that blocks sent to the fetcher (either through propagation or via hash +// announces and retrievals) don't pile up indefinitely, exhausting available +// system memory. +func TestBlockMemoryExhaustionAttack(t *testing.T) { + tester := newTester() + + // Create a valid chain and a batch of dangling (but in range) blocks + hashes := createHashes(blockLimit, knownHash) + blocks := createBlocksFromHashes(hashes) + + attack := make(map[common.Hash]*types.Block) + for i := 0; i < 16; i++ { + hashes := createHashes(maxQueueDist-1, unknownHash) + blocks := createBlocksFromHashes(hashes) + for _, hash := range hashes[:maxQueueDist-2] { + attack[hash] = blocks[hash] + } + } + // Try to feed all the attacker blocks make sure only a limited batch is accepted + for _, block := range attack { + tester.fetcher.Enqueue("attacker", block) + } + time.Sleep(100 * time.Millisecond) + if queued := tester.fetcher.queue.Size(); queued != blockLimit { + t.Fatalf("queued block count mismatch: have %d, want %d", queued, blockLimit) + } + // Queue up a batch of valid blocks, and check that a new peer is allowed to do so + for i := 0; i < maxQueueDist-1; i++ { + tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-3-i]]) + } + time.Sleep(100 * time.Millisecond) + if queued := tester.fetcher.queue.Size(); queued != blockLimit+maxQueueDist-1 { + t.Fatalf("queued block count mismatch: have %d, want %d", queued, blockLimit+maxQueueDist-1) + } + // Insert the missing piece (and sanity check the import) + tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2]]) + time.Sleep(500 * time.Millisecond) + if imported := len(tester.blocks); imported != maxQueueDist+1 { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, maxQueueDist+1) + } + // Insert the remaining blocks in chunks to ensure clean DOS protection + for i := maxQueueDist; i < len(hashes)-1; i++ { + tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2-i]]) + if i%maxQueueDist == 0 { + time.Sleep(500 * time.Millisecond) + } + } + time.Sleep(500 * time.Millisecond) + if imported := len(tester.blocks); imported != len(hashes) { + t.Fatalf("synchronised block mismatch: have %v, want %v", imported, len(hashes)) + } +} From b53f701c2791e7becba74c1efd4800fe68a06707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 22 Jun 2015 18:08:28 +0300 Subject: [PATCH 104/110] eth/fetcher: remove test sleeps (15s -> 2.8s) --- eth/fetcher/fetcher.go | 17 ++- eth/fetcher/fetcher_test.go | 209 ++++++++++++++++++++++++++---------- 2 files changed, 167 insertions(+), 59 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index ceca79df0..7b5804ab2 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -92,6 +92,10 @@ type Fetcher struct { chainHeight chainHeightFn // Retrieves the current chain's height insertChain chainInsertFn // Injects a batch of blocks into the chain dropPeer peerDropFn // Drops a peer for misbehaving + + // Testing hooks + fetchingHook func([]common.Hash) // Method to call upon starting a block fetch + importedHook func(*types.Block) // Method to call upon successful block import } // New creates a block fetcher to retrieve blocks based on hash announcements. @@ -277,7 +281,13 @@ func (f *Fetcher) loop() { glog.V(logger.Detail).Infof("Peer %s: fetching %s", peer, list) } - go f.fetching[hashes[0]].fetch(hashes) + hashes := hashes // closure! + go func() { + if f.fetchingHook != nil { + f.fetchingHook(hashes) + } + f.fetching[hashes[0]].fetch(hashes) + }() } // Schedule the next fetch if blocks are still pending f.reschedule(fetch) @@ -402,6 +412,11 @@ func (f *Fetcher) insert(peer string, block *types.Block) { } // If import succeeded, broadcast the block go f.broadcastBlock(block, false) + + // Invoke the testing hook if needed + if f.importedHook != nil { + f.importedHook(block) + } }() } diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index b9f0f36a5..06ca2ef86 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -163,7 +163,7 @@ func (f *fetcherTester) makeFetcher(blocks map[common.Hash]*types.Block) blockRe // them, successfully importing into the local chain. func TestSequentialAnnouncements(t *testing.T) { // Create a chain of blocks to import - targetBlocks := 24 + targetBlocks := 4 * hashLimit hashes := createHashes(targetBlocks, knownHash) blocks := createBlocksFromHashes(hashes) @@ -171,12 +171,22 @@ func TestSequentialAnnouncements(t *testing.T) { fetcher := tester.makeFetcher(blocks) // Iteratively announce blocks until all are imported - for i := len(hashes) - 1; i >= 0; i-- { + imported := make(chan *types.Block) + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + + for i := len(hashes) - 2; i >= 0; i-- { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) - time.Sleep(50 * time.Millisecond) + + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", len(hashes)-i) + } } - if imported := len(tester.blocks); imported != targetBlocks+1 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } } @@ -184,7 +194,7 @@ func TestSequentialAnnouncements(t *testing.T) { // peer), they will only get downloaded at most once. func TestConcurrentAnnouncements(t *testing.T) { // Create a chain of blocks to import - targetBlocks := 24 + targetBlocks := 4 * hashLimit hashes := createHashes(targetBlocks, knownHash) blocks := createBlocksFromHashes(hashes) @@ -198,15 +208,24 @@ func TestConcurrentAnnouncements(t *testing.T) { return fetcher(hashes) } // Iteratively announce blocks until all are imported - for i := len(hashes) - 1; i >= 0; i-- { + imported := make(chan *types.Block) + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + + for i := len(hashes) - 2; i >= 0; i-- { tester.fetcher.Notify("first", hashes[i], time.Now().Add(-arriveTimeout), wrapper) tester.fetcher.Notify("second", hashes[i], time.Now().Add(-arriveTimeout+time.Millisecond), wrapper) tester.fetcher.Notify("second", hashes[i], time.Now().Add(-arriveTimeout-time.Millisecond), wrapper) - time.Sleep(50 * time.Millisecond) + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", len(hashes)-i) + } } - if imported := len(tester.blocks); imported != targetBlocks+1 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } // Make sure no blocks were retrieved twice if int(counter) != targetBlocks { @@ -218,7 +237,7 @@ func TestConcurrentAnnouncements(t *testing.T) { // results in a valid import. func TestOverlappingAnnouncements(t *testing.T) { // Create a chain of blocks to import - targetBlocks := 24 + targetBlocks := 4 * hashLimit hashes := createHashes(targetBlocks, knownHash) blocks := createBlocksFromHashes(hashes) @@ -226,15 +245,31 @@ func TestOverlappingAnnouncements(t *testing.T) { fetcher := tester.makeFetcher(blocks) // Iteratively announce blocks, but overlap them continuously - delay, overlap := 50*time.Millisecond, time.Duration(5) - for i := len(hashes) - 1; i >= 0; i-- { - tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout+overlap*delay), fetcher) - time.Sleep(delay) - } - time.Sleep(overlap * delay) + fetching := make(chan []common.Hash) + imported := make(chan *types.Block, len(hashes)-1) + tester.fetcher.fetchingHook = func(hashes []common.Hash) { fetching <- hashes } + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } - if imported := len(tester.blocks); imported != targetBlocks+1 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + for i := len(hashes) - 2; i >= 0; i-- { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) + select { + case <-fetching: + case <-time.After(time.Second): + t.Fatalf("hash %d: announce timeout", len(hashes)-i) + } + } + // Wait for all the imports to complete and check count + for i := 0; i < len(hashes)-1; i++ { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", i) + } + } + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } } @@ -280,27 +315,37 @@ func TestPendingDeduplication(t *testing.T) { // imported when all the gaps are filled in. func TestRandomArrivalImport(t *testing.T) { // Create a chain of blocks to import, and choose one to delay - targetBlocks := 24 - hashes := createHashes(targetBlocks, knownHash) + hashes := createHashes(maxQueueDist, knownHash) blocks := createBlocksFromHashes(hashes) - skip := targetBlocks / 2 + skip := maxQueueDist / 2 tester := newTester() fetcher := tester.makeFetcher(blocks) // Iteratively announce blocks, skipping one entry + imported := make(chan *types.Block, len(hashes)-1) + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + for i := len(hashes) - 1; i >= 0; i-- { if i != skip { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) - time.Sleep(50 * time.Millisecond) + time.Sleep(time.Millisecond) } } // Finally announce the skipped entry and check full import tester.fetcher.Notify("valid", hashes[skip], time.Now().Add(-arriveTimeout), fetcher) - time.Sleep(50 * time.Millisecond) - if imported := len(tester.blocks); imported != targetBlocks+1 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + for i := 0; i < len(hashes)-1; i++ { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", i) + } + } + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } } @@ -308,27 +353,37 @@ func TestRandomArrivalImport(t *testing.T) { // are correctly schedule, filling and import queue gaps. func TestQueueGapFill(t *testing.T) { // Create a chain of blocks to import, and choose one to not announce at all - targetBlocks := 24 - hashes := createHashes(targetBlocks, knownHash) + hashes := createHashes(maxQueueDist, knownHash) blocks := createBlocksFromHashes(hashes) - skip := targetBlocks / 2 + skip := maxQueueDist / 2 tester := newTester() fetcher := tester.makeFetcher(blocks) // Iteratively announce blocks, skipping one entry + imported := make(chan *types.Block, len(hashes)-1) + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + for i := len(hashes) - 1; i >= 0; i-- { if i != skip { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) - time.Sleep(50 * time.Millisecond) + time.Sleep(time.Millisecond) } } // Fill the missing block directly as if propagated tester.fetcher.Enqueue("valid", blocks[hashes[skip]]) - time.Sleep(50 * time.Millisecond) - if imported := len(tester.blocks); imported != targetBlocks+1 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, targetBlocks+1) + for i := 0; i < len(hashes)-1; i++ { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", i) + } + } + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } } @@ -348,9 +403,15 @@ func TestImportDeduplication(t *testing.T) { atomic.AddUint32(&counter, uint32(len(blocks))) return tester.insertChain(blocks) } + // Instrument the fetching and imported events + fetching := make(chan []common.Hash) + imported := make(chan *types.Block, len(hashes)-1) + tester.fetcher.fetchingHook = func(hashes []common.Hash) { fetching <- hashes } + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + // Announce the duplicating block, wait for retrieval, and also propagate directly tester.fetcher.Notify("valid", hashes[0], time.Now().Add(-arriveTimeout), fetcher) - time.Sleep(50 * time.Millisecond) + <-fetching tester.fetcher.Enqueue("valid", blocks[hashes[0]]) tester.fetcher.Enqueue("valid", blocks[hashes[0]]) @@ -358,8 +419,13 @@ func TestImportDeduplication(t *testing.T) { // Fill the missing block directly as if propagated, and check import uniqueness tester.fetcher.Enqueue("valid", blocks[hashes[1]]) - time.Sleep(50 * time.Millisecond) - + for done := false; !done; { + select { + case <-imported: + case <-time.After(50 * time.Millisecond): + done = true + } + } if imported := len(tester.blocks); imported != 3 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, 3) } @@ -400,8 +466,12 @@ func TestDistantDiscarding(t *testing.T) { // block announcements to a node, but that even in the face of such an attack, // the fetcher remains operational. func TestHashMemoryExhaustionAttack(t *testing.T) { + // Create a tester with instrumented import hooks tester := newTester() + imported := make(chan *types.Block) + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + // Create a valid chain and an infinite junk chain hashes := createHashes(hashLimit+2*maxQueueDist, knownHash) blocks := createBlocksFromHashes(hashes) @@ -413,29 +483,39 @@ func TestHashMemoryExhaustionAttack(t *testing.T) { // Feed the tester a huge hashset from the attacker, and a limited from the valid peer for i := 0; i < len(attack); i++ { if i < maxQueueDist { - tester.fetcher.Notify("valid", hashes[len(hashes)-1-i], time.Now().Add(arriveTimeout/2), valid) + tester.fetcher.Notify("valid", hashes[len(hashes)-2-i], time.Now(), valid) } - tester.fetcher.Notify("attacker", attack[i], time.Now().Add(arriveTimeout/2), attacker) + tester.fetcher.Notify("attacker", attack[i], time.Now(), attacker) } if len(tester.fetcher.announced) != hashLimit+maxQueueDist { t.Fatalf("queued announce count mismatch: have %d, want %d", len(tester.fetcher.announced), hashLimit+maxQueueDist) } - // Wait for synchronisation to complete and check success for the valid peer - time.Sleep(2 * arriveTimeout) - if imported := len(tester.blocks); imported != maxQueueDist { - t.Fatalf("partial synchronised block mismatch: have %v, want %v", imported, maxQueueDist) + // Wait for fetches to complete + for i := 0; i < maxQueueDist; i++ { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", i) + } + } + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } // Feed the remaining valid hashes to ensure DOS protection state remains clean - for i := len(hashes) - maxQueueDist; i >= 0; { - for j := 0; j < maxQueueDist && i >= 0; j++ { - tester.fetcher.Notify("valid", hashes[i], time.Now().Add(time.Millisecond), valid) - i-- + for i := len(hashes) - maxQueueDist - 2; i >= 0; i-- { + tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), valid) + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", len(hashes)-i) } - time.Sleep(500 * time.Millisecond) } - time.Sleep(500 * time.Millisecond) - if imported := len(tester.blocks); imported != len(hashes) { - t.Fatalf("fully synchronised block mismatch: have %v, want %v", imported, len(hashes)) + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } } @@ -443,14 +523,18 @@ func TestHashMemoryExhaustionAttack(t *testing.T) { // announces and retrievals) don't pile up indefinitely, exhausting available // system memory. func TestBlockMemoryExhaustionAttack(t *testing.T) { + // Create a tester with instrumented import hooks tester := newTester() + imported := make(chan *types.Block) + tester.fetcher.importedHook = func(block *types.Block) { imported <- block } + // Create a valid chain and a batch of dangling (but in range) blocks - hashes := createHashes(blockLimit, knownHash) + hashes := createHashes(blockLimit+2*maxQueueDist, knownHash) blocks := createBlocksFromHashes(hashes) attack := make(map[common.Hash]*types.Block) - for i := 0; i < 16; i++ { + for len(attack) < blockLimit+2*maxQueueDist { hashes := createHashes(maxQueueDist-1, unknownHash) blocks := createBlocksFromHashes(hashes) for _, hash := range hashes[:maxQueueDist-2] { @@ -475,18 +559,27 @@ func TestBlockMemoryExhaustionAttack(t *testing.T) { } // Insert the missing piece (and sanity check the import) tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2]]) - time.Sleep(500 * time.Millisecond) - if imported := len(tester.blocks); imported != maxQueueDist+1 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, maxQueueDist+1) + for i := 0; i < maxQueueDist; i++ { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", i) + } + } + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): } // Insert the remaining blocks in chunks to ensure clean DOS protection for i := maxQueueDist; i < len(hashes)-1; i++ { tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2-i]]) - if i%maxQueueDist == 0 { - time.Sleep(500 * time.Millisecond) + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", len(hashes)-i) } } - time.Sleep(500 * time.Millisecond) if imported := len(tester.blocks); imported != len(hashes) { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, len(hashes)) } From 99ca4b619b22c000dfe633b036ed0b9b0fe83523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 22 Jun 2015 18:28:38 +0300 Subject: [PATCH 105/110] eth/fetcher: clean up test assertions --- eth/fetcher/fetcher_test.go | 160 +++++++++++------------------------- 1 file changed, 49 insertions(+), 111 deletions(-) diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 06ca2ef86..80247d9d2 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -159,6 +159,37 @@ func (f *fetcherTester) makeFetcher(blocks map[common.Hash]*types.Block) blockRe } } +// verifyImportEvent verifies that one single event arrive on an import channel. +func verifyImportEvent(t *testing.T, imported chan *types.Block) { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("import timeout") + } +} + +// verifyImportCount verifies that exactly count number of events arrive on an +// import hook channel. +func verifyImportCount(t *testing.T, imported chan *types.Block, count int) { + for i := 0; i < count; i++ { + select { + case <-imported: + case <-time.After(time.Second): + t.Fatalf("block %d: import timeout", i) + } + } + verifyImportDone(t, imported) +} + +// verifyImportDone verifies that no more events are arriving on an import channel. +func verifyImportDone(t *testing.T, imported chan *types.Block) { + select { + case <-imported: + t.Fatalf("extra block imported") + case <-time.After(50 * time.Millisecond): + } +} + // Tests that a fetcher accepts block announcements and initiates retrievals for // them, successfully importing into the local chain. func TestSequentialAnnouncements(t *testing.T) { @@ -176,18 +207,9 @@ func TestSequentialAnnouncements(t *testing.T) { for i := len(hashes) - 2; i >= 0; i-- { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), fetcher) - - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", len(hashes)-i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): + verifyImportEvent(t, imported) } + verifyImportDone(t, imported) } // Tests that if blocks are announced by multiple peers (or even the same buggy @@ -216,17 +238,10 @@ func TestConcurrentAnnouncements(t *testing.T) { tester.fetcher.Notify("second", hashes[i], time.Now().Add(-arriveTimeout+time.Millisecond), wrapper) tester.fetcher.Notify("second", hashes[i], time.Now().Add(-arriveTimeout-time.Millisecond), wrapper) - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", len(hashes)-i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): + verifyImportEvent(t, imported) } + verifyImportDone(t, imported) + // Make sure no blocks were retrieved twice if int(counter) != targetBlocks { t.Fatalf("retrieval count mismatch: have %v, want %v", counter, targetBlocks) @@ -259,18 +274,7 @@ func TestOverlappingAnnouncements(t *testing.T) { } } // Wait for all the imports to complete and check count - for i := 0; i < len(hashes)-1; i++ { - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): - } + verifyImportCount(t, imported, len(hashes)-1) } // Tests that announces already being retrieved will not be duplicated. @@ -334,19 +338,7 @@ func TestRandomArrivalImport(t *testing.T) { } // Finally announce the skipped entry and check full import tester.fetcher.Notify("valid", hashes[skip], time.Now().Add(-arriveTimeout), fetcher) - - for i := 0; i < len(hashes)-1; i++ { - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): - } + verifyImportCount(t, imported, len(hashes)-1) } // Tests that direct block enqueues (due to block propagation vs. hash announce) @@ -372,19 +364,7 @@ func TestQueueGapFill(t *testing.T) { } // Fill the missing block directly as if propagated tester.fetcher.Enqueue("valid", blocks[hashes[skip]]) - - for i := 0; i < len(hashes)-1; i++ { - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): - } + verifyImportCount(t, imported, len(hashes)-1) } // Tests that blocks arriving from various sources (multiple propagations, hash @@ -419,16 +399,8 @@ func TestImportDeduplication(t *testing.T) { // Fill the missing block directly as if propagated, and check import uniqueness tester.fetcher.Enqueue("valid", blocks[hashes[1]]) - for done := false; !done; { - select { - case <-imported: - case <-time.After(50 * time.Millisecond): - done = true - } - } - if imported := len(tester.blocks); imported != 3 { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, 3) - } + verifyImportCount(t, imported, 2) + if counter != 2 { t.Fatalf("import invocation count mismatch: have %v, want %v", counter, 2) } @@ -491,32 +463,14 @@ func TestHashMemoryExhaustionAttack(t *testing.T) { t.Fatalf("queued announce count mismatch: have %d, want %d", len(tester.fetcher.announced), hashLimit+maxQueueDist) } // Wait for fetches to complete - for i := 0; i < maxQueueDist; i++ { - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): - } + verifyImportCount(t, imported, maxQueueDist) + // Feed the remaining valid hashes to ensure DOS protection state remains clean for i := len(hashes) - maxQueueDist - 2; i >= 0; i-- { tester.fetcher.Notify("valid", hashes[i], time.Now().Add(-arriveTimeout), valid) - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", len(hashes)-i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): + verifyImportEvent(t, imported) } + verifyImportDone(t, imported) } // Tests that blocks sent to the fetcher (either through propagation or via hash @@ -559,28 +513,12 @@ func TestBlockMemoryExhaustionAttack(t *testing.T) { } // Insert the missing piece (and sanity check the import) tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2]]) - for i := 0; i < maxQueueDist; i++ { - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", i) - } - } - select { - case <-imported: - t.Fatalf("extra block imported") - case <-time.After(50 * time.Millisecond): - } + verifyImportCount(t, imported, maxQueueDist) + // Insert the remaining blocks in chunks to ensure clean DOS protection for i := maxQueueDist; i < len(hashes)-1; i++ { tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2-i]]) - select { - case <-imported: - case <-time.After(time.Second): - t.Fatalf("block %d: import timeout", len(hashes)-i) - } - } - if imported := len(tester.blocks); imported != len(hashes) { - t.Fatalf("synchronised block mismatch: have %v, want %v", imported, len(hashes)) + verifyImportEvent(t, imported) } + verifyImportDone(t, imported) } From 3ce17d2862e89e20b8e9b10cc02ee0b1333f6625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 22 Jun 2015 20:13:18 +0300 Subject: [PATCH 106/110] eth/fetcher: fix a closure data race --- eth/fetcher/fetcher.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 7b5804ab2..90a202235 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -281,12 +281,13 @@ func (f *Fetcher) loop() { glog.V(logger.Detail).Infof("Peer %s: fetching %s", peer, list) } - hashes := hashes // closure! + // Create a closure of the fetch and schedule in on a new thread + fetcher, hashes := f.fetching[hashes[0]].fetch, hashes go func() { if f.fetchingHook != nil { f.fetchingHook(hashes) } - f.fetching[hashes[0]].fetch(hashes) + fetcher(hashes) }() } // Schedule the next fetch if blocks are still pending From 57c911c39804ccfcf597df0acc6a03eb096d7652 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 23 Jun 2015 08:26:17 +0200 Subject: [PATCH 107/110] bugfix in startRPC error handling --- rpc/api/admin.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpc/api/admin.go b/rpc/api/admin.go index 7e79fd4d0..b27482cfe 100644 --- a/rpc/api/admin.go +++ b/rpc/api/admin.go @@ -217,7 +217,6 @@ func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { } func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { - var err error args := new(StartRPCArgs) if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) @@ -229,14 +228,15 @@ func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { CorsDomain: args.CorsDomain, } - if apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum); err == nil { - err = comms.StartHttp(cfg, self.codec, Merge(apis...)) + apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum) + if err != nil { + return false, err } + err = comms.StartHttp(cfg, self.codec, Merge(apis...)) if err == nil { return true, nil } - return false, err } From 55424a11af6bd11c6c9f4b433a4d4690b7267ad4 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 23 Jun 2015 09:11:57 +0200 Subject: [PATCH 108/110] improved action description --- cmd/geth/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index e5c3614fc..1e5481eca 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -208,7 +208,7 @@ See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console { Action: attach, Name: "attach", - Usage: `Geth Console: interactive JavaScript environment`, + Usage: `Geth Console: interactive JavaScript environment (connect to node)`, Description: ` The Geth console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. From 2b3957f3737b56622e38425a52caea2a836f8b63 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 23 Jun 2015 09:38:30 +0200 Subject: [PATCH 109/110] fixed relative path issue with javascript files --- cmd/geth/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 1e5481eca..02ec63300 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -333,7 +333,7 @@ func attach(ctx *cli.Context) { } repl := newLightweightJSRE( - ctx.String(utils.JSpathFlag.Name), + ctx.GlobalString(utils.JSpathFlag.Name), client, true, nil) @@ -366,7 +366,7 @@ func console(ctx *cli.Context) { startEth(ctx, ethereum) repl := newJSRE( ethereum, - ctx.String(utils.JSpathFlag.Name), + ctx.GlobalString(utils.JSpathFlag.Name), ctx.GlobalString(utils.RPCCORSDomainFlag.Name), client, true, @@ -395,7 +395,7 @@ func execJSFiles(ctx *cli.Context) { startEth(ctx, ethereum) repl := newJSRE( ethereum, - ctx.String(utils.JSpathFlag.Name), + ctx.GlobalString(utils.JSpathFlag.Name), ctx.GlobalString(utils.RPCCORSDomainFlag.Name), client, false, From 67e6f74e9af00ff011a6a02f18644804eb18cdaa Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Tue, 23 Jun 2015 19:11:20 +0200 Subject: [PATCH 110/110] cmd/geth: bump --- cmd/geth/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 02ec63300..5a0f523a6 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -46,7 +46,7 @@ import ( const ( ClientIdentifier = "Geth" - Version = "0.9.31" + Version = "0.9.32" ) var (

    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 diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Light.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Light.otf deleted file mode 100644 index 4a8eafd78157a39cc544358cbf424e2303157c1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124476 zcmdqK33wF6)-YV%vnA8XWSLC1$xMcQ57~hLLY4`Mgd`+k39?O+$pT3xOeP7NfFc*r zi=d*YYyp&g4Qp5xL~%z&#VaZ(?uxq|Y?SYus_D!G@p|9;|L^lX{~zt{>guX9$B!Lx7RNUnqm%}R|AwC@V{ zT`Ox`Gv}n7evWWCmk9})T4S48rz}QLTo#RmUF5P+X` z0iIh3hfV!nIWz2pFePBfFGQjE0&2*ss}?xr>&l|13W+_VXXQ9T@`gfh=Ew$WgZ|; zaF-RNE3vuDO0PC5GKeg4*Q<%1oOG8pWGZ>XUG^c7T%5b?OZ>Qz?y^84xN+{Xf6#ke zox7|fUG>@Sav%xN*SO0;M5Uk0%0R52{vLOkBU=43cbO-GewDkdfbvFnSxJ2LyI|a$ z(ig^hzy6TB%#q$9!`)?`=t8Es%L=154& z1$UVzp($Uu%L*v};Vvsl@ZgYiN8K!ERYj%C5+55E+ZWIAmeevwiQQ5-tKMa=skda; zmO7ku4yVm!FN?9HR##gJutUA2z+P{6HbP~gqrq7U9c;DrmVBqfl7r6+>=g~wHfLN+ zY*OrCRJp;d8McB({b(b2ke6m1Yj@UHIchDeZGIsZVq*taI$WiW+D5#K84x?T#x~vV zaFxeYSCz!aB*i2RijBPuL^mx}^%k4O<+PRAYi!Qx7DxHN8I+}}*5azPTgKE@!4NHl zE*L3vuPy8Ea9SMj#AzvYG}OABRrdOrzvfN8t)beI5o5`Mrj;&NT}uD{O-)TPHe_Z@ zsiUU9YgV28f5>l3&)Y)k)z{Kg<*IC#fF;vW>$2p6SF-eA4CrxtNm>54+2gPE*A`U* z_bEk%j&fI%&1ttlMRirFy|y0s+fZ8u97To~X6IP)>g=_waSm(H*Wyu!xR`c$?(PVw z)KOOja7ygej;6jSC#Mq5?2t)$w{*kiL~rjEAQTqzbe7wb!%RdufVnEI;f z7>Bc>e_mz|BIx(u|M_d_Ao8ubmdw1|B1=wox;3}Z>OBTaKTCYFCDUHwY_K_JfrZ5m z_5k;09XO*_^Iga4D5lbxaSa4cEJM z2{@FQ1L^|GQ%{G`u9!F$sB$3a2GG>Lz^sNcP_@368b?`GIVv5}1~_3X&Z?3IbQef+ z^(>1GG~7{Jfme_M+ylF79WG0~qZ(9o7FO2O+p8PFg;-E#6j@&&x3n5?V8_~7AP8qw zBV#)b8#q*It3`53z-X$G5PMCDy{rsN9jS18D~gS}1_W0xo1dG(Wk7|^MKL+uzT1MS z3|NnwS{yb~dn+McG*cFMo&$}QjwVnbCnXk#4D>qf)pnc5*pV3KNYMwPj=7o6;5zLy z8mgRjs(+wBZXtsppw0#Yl|6>Xi&)AWKs6$>)zty_p)KW~qqKoSp&AK8X{blmqFFHE z0&uvga(WGr=>;U1*}2(8*?GBz{@Tu&sPnS(>I`I*gE}D+gj8>*R#IM74J5P=l!@5l z@$Xq6c)PP_eXrY*k7`s3EOG+v7@$zI>MivRrIpAL7$<5t(+xn#!Yf7C7gV7NG|KJC zm@wR zybmg}t&AF%%h4A^UTt@QI`p-G7SuPCfID(EV1=b$KiO^IBkF4$5JRAvDlYS@US!Lj z_7*09Y-U+XD{ZyFnhH=jXN?Vgp%bgoValr5ksYYImRft0#a`Q3<#f~{pV@Fz8(ftR z=br~zUsVC_4SWG2vSSJCy8?V=4VGQ@(#qPZQjkrP6Y?3zVB{pG4wM)K(p2dH8DKiY z9GF|JJ5WUl$hQ`Z$}TJfo3M1Zr03;k$o7$Mch*$Z)07QV74joHj1UN@1%KF=`EU#) z;GHY%G-4nd-Pj!^E--0ig$<~v1HZu7+W|f81ipxQ;91~Vpe1-=I|WF6pxY-yt+yj& zAqD(wbw`)oP}}ao0TjfZzd#FWfpJbY^>R>SM-vhY3@d}6<*2Ps!HglUmnGK@8JOEt zIuH+T$tf#N6(~Rz^n~!%021-&5PE(~yA?r)TXh@!svPCq5d>h_tIMfm;(Pu3zPBBn z46i+wcr%VhHq3W#A3>;!VT^W%5W5XxF%=(b5(t!qQpg%0W59YgrvL{HNgZ`kF7#^N zUcVk1vf$?Sb7dAcN6{0yz(e-4K}3b5#Xi$zaXY`th8kOKKS(#qXqJcbc=XIbH?R{O z4}=4!qt01{2~G_V2?pY6USoGbM;D|SRrcz#dYT+yKSTf^O2DH*g2o&>5aEgE4j|Uu z$4xUtw<_@6jaBw07BLYyXsnaUCjr#M@h6e~wN#)ZrT))uo5c@^H1!ty%sSv-m5bW7 z3(_O7C@(W~+aEd`=7F6M2^w@RK3w#u+0t<*ZY!*cmd(qqmTO#3Z)4mlseZ*z}%*A=N?Py7m;DIH(a|%F1 zQG$SL94_z;_S!Os6F3K=vz0*t;;MohbTzly5;UDzYOkYaZ7ZE#>u7>ps)Dh+-4lXs zd(m+_nlWf2YrTkevIG-qA*c8^0-{=x#JJO8h;BEAsU-}<H_JEWc5O!V%^+S3pR18{b*PVlP#`#D($PEZyVVaUl%#XQVC zk94~XNGid3V$Rn98iA5%bW}mMUoLxE6pZYCWLMpu)`H4QFYZ;eal$AH8$O0`2Qge%nVfJ82%`LW! z%+Af|Yq5@pnOI?=C9lAeJt{vZ+X{8rx#>A$GO}|=Skjsahun3bB7V?l{u(z9W8P?Ps00?@K`{%YXw_T^f*-rmzdxfnUp4U{n7hmLcGP(j*SZ%AX z1nZw|cRC7T!HTZMRi{=%=2nYA%;qUp6heMm4sEkZI&qLXGK)A#6{#SV#04w1@g$bS z!O^$991o>bQU+~Hh#ks>(4!vO+DQ#uEhL-Nl2Ul;1Xy^s(Pw2OhW4u_)o?9n$ACQw zpl>}KPSOZxY*`3B8{oba?h%6xU}DRBsB^$Ir@cS+t$?=G(8dXr#sIBJa0~_-Ge{b& zDG%-dO@_rF_49(ndgReQV<|QDfW-lrEgj(I13bAVmSU=eRxUc`S{Q-+EQSoAPiug( z=>QMglmmU$0JQ}88Uu9VF$h}4{)aSnZy`N8=t&RCk5u5ze_~T8Id7}_|DN{v6D`4`2>8sX z_wWeERu0^10$w>OuUHGTHuNIsKbZcaPNJotj>;Nd2wp1(?(?XgpzeDhqp$Hm=nKzo z=N-`V{F%Ov*wL=gX3#R~pv>q&FIo*XO;jV8J;^O?@T4A|p`A6tQ3dxl@E+CB#{xaj zDp7mT2V{bEjizN6*o5U4U91PJXoq#sqaJ8Q-&PG*wA%`>kv!<1(>{WJOeKv1nLu7hJ~In7NcI)QQyNn5sN9Pzvy#N6XghBMPs)GY*6-EbpX{trU8^vs&i;L zG8GK~m1PI$-{i4*`l7Dd0X|a8BCs7G<8vp4C3D3Fu;sXiRw~CM3s8qK3^N0?IfR2x zk@6ZkeiqSKTtdoZyJHkG+8d!4;|JPTIi(4?BezA~pl4yvn2%=M#Q4i%XcP5SrPNC0 z@u3gEIF0(qa;SQE&Lo8qR)&v~k||-ng2Ak#ZC!vFy%_dIyY}`6o;ZxQ?(LV5ex@CW z2c?Lf2Pu-J(9vfhJ>GOP{xGT=pdZqO{6ii$K$&?ptf>LWcwg?W^Nb5+i%+l*`lJ%* zDQ6clm#ZmvY?Lyj5oL)GJd`5$WbLkn7N|++D^Zh?ulSse3G-6aWz=ZohlNHEjjOk2kWn1>>H;&np@!+`rN&+5#kpWRD6Jl;I97S+o94@5Z zq_bCkR0xp0b+5CV8|6SLdMBAfGEFEg)It_Z&^w?MvE82~>TSiA+ve|C00%7|arFc! z81w!!?#o^lEgrQ9V<7TfoO{B`*3f+fnEWv(KCDXj1YYUdIcOY z>TAcG%-b?L%GwhLJ+kTiAI%v4N*1zpc-wnDXdcGujvgE3B99&^L`gFXljX^>*^a9Q z=-H8Kv2|)7X(~REJu+rOh(-1R4(dCx z1#$^Wkq!)FQ`MG*nnUH5AaWq!v!f4ql2I?q6{d*h5Yzf3jIS6w1-_1fW=R(`{wmzmYvW22FWqn|44Q$rMbhu;2!7^yJQYTZ* zdfzVhjseI;RMRjUMGA17GKWwn=0z2xcoD(9QsB8V;%I2sD3q93LIAd&*b6ey^ zB}56-lv-$y9LH$wS<6GMXDb;jXJ-1xw9~@_oE=~s!gCe0M_f$4$VqH%zb$n1KS(WN z#4Do>b+U}wj69>1@yR1#RFqK2m<6B~c}9hNMj731e(r!LNE^2H;OWR`95GvmM7U_L z7;zcLJ7!$W$2z_2C&BGKFp~Y9mHs!j!Z3RDuK?)65y`(%d9M)5>+|0856p}(wqgD- z6XeC_n&=BW@fxLvTE}A4?W1AG_$Oz2vPPgKIN?9U#d0i9{+CYmq@$I1&z58xVD`aa zuxtR=>pb~%Ezpkgk>{pz?C6*$FpWh0mbCE#`9yt6n@3;YdDrt7bBA&mW)nX;HH&*quGWurk~%0|g7 z7$Y;vA3XzV0j>q0<)h6ot3zvLD3)kN=d<%u9N(+@8}Y3)v6JZP_}-e`i6SSew*Acm7(6$TgG; z+7R?{Ce&Q5#U=XeG?@{*(0##31t-*Y_Ew zj+*#a7`@@k8s2l7 z${5Y$U)c(wlnLV-2QBdzDtx1(5YG5}RUZ8InGL_gTj8+4TsM_I!RMW+CmRP(i{Kaf zJa}iI2wE^01<($E!7GLugpF?{JTq%O*_{IzNN30`hEu##1f>K6WJWw$HBW^|q z@_(!w9=<7nG(~F${vkY#h1F}vbER+uNBZqRK5cp>Wi6A6agZ)u^P`}gN9Aq$=b|Y8iwv2~t zB?IL*8l=hi&fwiT3LMus$}e%FByd> zWyX!ahs(Uz|NK3l{xr9#p!rw~)aTmC^ zxp%mCxr^L;+`qW@xl7#d+#mctelOp`^L#(}YFt5-@CCRUzQXna3baHZeh@2kB!C2x zAQB8;TZh1x*r6nhgp&voNsPRa@5D#(hxl;*V;F;pm`OBnt`kIsE~G2z25W&m;MbX6 zq&MjUn%NKHQh#_0BM#ouNFa$Mi8t{U-pn6?k)@EKpuOYB{p1n&ru$QJm3&6NAfJ=3 ziNvWmC8y?mxK5mf>&$iKQn*xZIG4s{aOqqPSIyOOb$nO;0sbNWLB2a5#`oatd~d!d z--rK%|As#dI=GHM&L8CW^9T6l{0aUfe};dKKgOTpEBR@F`!_C+SMVHvlz)bQm~Z8u z<#l`jcT(9hw@rp z;5U$g5YGm{ckE+nF4hRLUqK!MEX&C;a-1CH`tVozulaBJYy1!Vcl?k1_xw-%r$p(a z1W|{A5@>+K{Q>WAfH4)ca2`2Do`Y}O-yt6XSAHPBa&cTXXXoZ|3%KRn!`udLFUaz9 z?rV_706v``%@^}Fkm`OI$#EFtEBpuiC-CjQpCUk^R~Qvt6+IO(ia5nHrgT%bX_P77 zRA3r!y34f2)NDFt)|dm#VdhTeZstDb!RBmpp}ExTFfTGMH$P%tWnO2#ZqZmmEs++p zr89iT6KhGZq*#VpGAuJJvn=y1ODzvtR$4Y#p0aGQ?6kC44qA?O(sv5$Wa-qoQ}<3W zor*e5?(|4!zO%Y>K24w&X=+-QNWj$Zil)Z@AeGv<;CuSZoYgL(^(>nFWe?V zZaxdgG2juo*$Br8D1b(Rmv{eh$8HvZc6t5XoJ@YXX}x*J%>g%0)9Nl@w`RG)&EId{ zxcSS?YXIx3n_v7PecF?dPhmfcPkX@8?dls>&tHA<(-bJj$UO+T`m?9}@r92=3HhY` z>6Q0Bp7HVaD{p<`_c81@apf5}PF^{7<)``&$^DCcT`S?o9mEbFWSA4Im zx$^jxf-5;!23$UV`Pk)ygj`+<$GXcaFVDCz|O%Q8r%>#GPpb8{0}(Rz_A^UXZS>ZGQWb+3m)tUSpP-- zU;HJ{2*4k|!(Vi_c!$3Xc8mLa&_DkB_7c?bz$HB7KOXky0MBy`Z2L#*>iraEu)7#V zEVfVpPZS?2K2v<9@ah9~pRq%Rf~`E|+m#d`H#~0tr`UO$`oD`49b$sFf0uo=A`v_# zdfI=2FYOHe_8aiDmEbXt@2-vW^_3Uh*V(yN@|Lc>mwP|0^K^p#Qf(1VI1)2$#a| z=JLSv*P!p`mT)V<9}gy9k|E?P$bhed*580!^){=qHFr-}8<9-Tb}$&-|}^8~+=BgZ~43 zBM)&yt?*H3A##K$LiuXGmUr+Cd=o#LpU2N9g&aqUK&7g=NaEm3q>eKy(iG`rA(uez z;}XdtE{QDW29SS(6)xk3k_Wjv$ad~7vV)sQc5;(Q3s*|^b7kZRS4CR6Y2*!VA$gO# zk6Zv-eUE#9T;?7o!^pQ}IJpL1|2vpnd=Gi@50JzE2-)RNkoEoy+3zoqb^i+4rAY21 zZDca%N2YN8WGbg4HZFjaaDk+h3nFD)FtKxbGMno`=5Rg9DlUsW&SjG)z&AVzd&I2f za>yEP6j{sVk_}t|*~k@=O`}> zOWx)dlYeplB=2*}$R+MUK7{5A21ORl7qm2U5FkhC2H8n0U(cuTgZY{KD##zs@H_cE zkaxVwzfZG5Fxi_2AwRm!A4imsC30K{`|_j1)+bmW7o}_?QOfIFl=3$}C`f#i@`j=< zR4EOW_W$)>sEe^7mVZhZ%iRpTw8((|IR9i=WRg0^jop|0KVG-vYU7D{$`x{x$w>{(b&q z{!7qgk^dd^Rts@G3Zi;%$aMxPhAA=?qZCDoV#QQNg`!r`pqQ(;SFuF#h+>Umqhgoh zfZ~|qwBkj@>x%ajmldBYt|@+2NJ?Jms|-|zDb31m%D&13Wr{LYnWfBAj#W-nRw!$f zP0G8K_bDGxKBQcwT&H|Wxm$Tqd0cr$`I7Ptton(mr@nncZDO`0ZKldl=0nW!n% zOw-KJ%+$=&+^1Qtd0ewjvrV&Cb69gyb5`@R=55U-%_o|#G(TwCG?L~IAI`_uC&Y|C&eezC(mcRkIiSAPmNE5&)q)v`#kKk)@QTNZl8lbCw*S1X@jd2y#`gu^ z^S&2-FZ+Jw`;+ettx~JghHE=%du!vhDcTI}DD7D7WNoF^shy*}Py0{pO6@xB7VTc` z5$$R1E84fUm$aW~ztaAoZ4)@bR|pb}LRX=mkR%KfvV{U+s^Ac23-<}jghz$7!WLn# z&?-DDyezyed?Izr}x-|9<~g|5N^F{a^Nf!~c^1=l(zWU-!SMQ|Wwlfw~Z#QP)Y= zP1jeKpi9xE>auisx?2~V&>yGN4)xD&9Lw8YkMfZj7 zJKe9kn*r(o|A3GHV?gJCUIDQI0|M>{um>AiVFgY+aFe|Vya6+IxusX0Q za9-fjz!ib312+cl3Oo>aEbw&Ti-G3@-wpgQ@XNsO1EnB7$Tuh?s7p{x(9oc)pm9MZ zK{JBp20ak;SkTi!dxK5|y%h9b(AA)yg8m5h4-OCR5gZ?!8hmGPVeo`tTk!PYrr>$O zi-P|d{7CSV!5e~i1|JJP9sFYO`QUehKMejf_?zILg4=>`=!ssb_tE?51N9;LaD9~C zqVKBjsqd?g)hFr)>WAou>ofFO`W$_}zDPe_KT$tbU!`~I7wDJjAJwndZ`JSBAJspn ze@%Z;|FQlX{jVV;L>m$kVh-sU5+5=oBsFAY$e56+AypwwAqzs5g*+D09I`!Rf5`EW zvmtMVTnhOjampVht&V3`4GAyrINUZJ2FXXjox*(y+;}%W%x_qTwyW z2ZpPLZw8OF*@R|2z!JhVphb$hzBAbjaVPCEn(C1Bcw>*NJC_FWUt7C$f1#$k$I65Bg-SJBVCd6A{Rxjh+H4JIdWIz zfyiT#rz2mCJRkXP}l+8Og0WNW*Bpfg~npz6rSL%6QiJvhfY$yT%WUpBTS1erLQMrHl%Q zij3+S)h8-G>W(OD)TpQlQMRb^sOL?B$ztlC3Lo*qrWmOuPS|1w_6>@SOV5ByoHaF; zUE@_ew-Bt>l`lOduIbkE2@@o6c z^imt3PcL)0Y^AV&l`DhZQ%JE4Zmcx}D73k(^ofh%% zWTi8*(ivIl$yP?z2oFIcDC7~|kYUTV_z@nu;t^DAY~p~}gxG{EPftoiJcAscnpI+R zX1ic38GAM(IlCjs^i0}5oza}0n$0M=vje=?xP;^!%Ca08KUAgV04Ul!fypC*0ZCv3 zPmIr{U2;8L5|e22L`Ga9>y3u`q+N zFoVI$V6ZX<=D}7fwX|0TBO`-#&S0Ibtg{t6$AWehP!bC~BqlLHNvv}c>zrgQr0oiC z;Ytz$jg60E<4$I2$B0gi(m zv0w*?s`_I3yx8-EVjJl0&X8s@u4N9KK*3D#*0DJ2Aja*1nKm|3o0pX{FsV$?sW?iI z3R9C*93|Z0DB;3Jnd){6Ol{Lxzckh_jrB_#U}GF8rNoqaC@-ZFDQ%~&OqNibHI~7R z%`Br3UiD~*wr#=57ut;wyojI4AjZLOjUg_ycX^3Z#0Fy%>LqDf$o6BrK?6KZLfTABLT zIN8J*or$bh;-Fd^?xYGExK!F5j9$l|HJ+J~I}Etpl-nU>Fve1Ah_g~_fXg69yT)fQ ziZYl~GMH4XOe$9F47Q)zu?oCuP>tcJ;R~D+z&uNi!BCGuX)q zE*Va2Trx!zAIHEYGjPd_mO%qxODYf->~llK#Vi7Czv0iEKpO*TqK&}?jTtUz%y4lV zGh?uIKm!wTLpvv|j6N$P!pexSG9ohLny76z(E&Dj2G}Iq{w(@@mgfl|jk6APcV|d5 znN%|e&8A>xdn+^8K4St^nArFvs?G69NK|Zma$Nb8^71LJ>=;`%MFdw01FjyFa6?%I zSD7p*GQMG*9I|6#jLioByK&jvxNP3IU~@GP3pDcJa(gYP zqf&w^%1K6Nbz@15lM4xQAxSO_kPCz4LYiF2kP9-|X)>HN8BUrECk^1ZU0aL|2=HVS636ecU6L4p*7{O$sH@erjxW#Up13m!N=Cpk{vh4pe5Kq zj5VT=U2e#DMac9@A!CU`rUitI1%ynm6f%|=WGqq0SfG%>VN#m$ije7*LdFt>ObZAZ z3kaEBDP$}$$XKF~v4H9rOXC&nwu`nB9~XzV5+4^IYjeev!p4add3{42?AKWgB7qiIizcIjyOn=Sq66qUUM!Je{7a>A8lUYw4M3UmY#apl2sN!(O_8iz!nB zEjQA06FoD1oJGsC>DkVFEOvrDVV^_MBYb0A_^y2EwjoWeug6EP=Hrz`kpckii~m^nOsR&FOSBHPo@YczRdn zXu@nQK8enBrOLJ=#G;RxL}}# z088(Zd-l2Y&@k5 zE;Ip&PshXp?l2F5i74X33wSpiB@}7Ihl{6%&IS@<<2^MLH_T!^H8kZ(h)wj=(CjB6 zHrZ2yz7!A)@YK-MC?R&Br-mjP39*AbHI(dx*i=sq9YI2Dny1D+m~>AKDgW_wK> z8wF))Yy!>kfR$_@bn*>%jO2JmXS|2bct&Tuht7D)=!66}vj)Pj+#I0AcC4{@>($7M ztN6rCH!XJTcm&ao&D+iS^>wxDS-Jon5ZKoBekcGD8uPG2k{VvB%Ku*xj8%CM~+SjyH3 zv7r}B-OGkpE3?$IcnGy@^zB?qYv)p0I~8f|TuN`}QhGa=(%ZR|jx2DmE6R}Lu+D3d z5$|L=JWGwNHLf<&)@~M2(&F7HuS!+lh$B0pJoOT-;MUD98-+p5#Hb ztb?9u9#ppLpw~o?@(EUm(NZW`Fx8Vwh)|yFx!c7f@4OZ?SzBDwlzSy0!EAvO3tsZa zWlpTZ>5vcI$LF<-jMZMlVvEU8SuD5pT3E(vueOxR zfgW7#^k%k;Jrn6l9Z#>0h9Koa88@h%|_(*?L-4gr@;I(3X?=X$IIeW90xjLKQC z_=#k|?#8%&0)-lPfwqUqFfIv{(n)x!dkS9476VGz^t+TU1eCg`-lgtEfKs*uPzu@z zlP{1qoI!GMhHwpM;3u46*l>n41J00Wz!_2vI76}lXGk~T3<(FEA?1KGBpq;uv;)rh z^bDy7lndw?(hn#X(KDnVP##OqkcL2cJUv4y0%b@>;0*t40IWt~NoE5SWkz7p%?c>G zf6QR=iXUL5{2O2$V5`B6=3${4o-hX2xi9qAc(ry9_Z{~eyeu8bkAm0vUgy71gey8J`Y00N zwXe~NQpHNeD~fj%*Od{b?Zv5Ds(M}ZzUro0sWz#z)Dz*g zl{)p^>V@ims-INvQNO5uQ+-K&RsE&d>Vb`_$={R?z75gi_cD<>%N)3<9%(u^}efp*ZXeu-R1kT?~mF*tr1=l>90+K z*F=VCi?uFotM(7UU+537el!XX3Xcfug`L6y;d9}JAMY0ouX*(KOY|%8d(^MlZ@b@7 zzvuj3^n26qUB55krHVF))*6nfrMcI8s3yVX_a3TN z^?PEYN_;}CGwk|e!?`ub*S`Qg*5|J+-jKU1Cj4#5h8@PXtyE2f%Z-)L;YD$XN~~4u zq^kPf<2yyRE;GFQTB}&R(JT$njL)A?S7a=jwE29ruy~4UiF)_c(&hrAr0&^I>MO;+ zmmvDR{OsF z$0&RyPB2KxpWSus+s}@P$!77jsnUxY$vC2H=+NvI(P$Q5oTL#>iys-Ja#1Bkh(kYq zef!}9X7LGWa+w$}*)-Fq7tYEvO1%?AtvFH~`Gu$v`@Gd!Q@$&D^ETDq%EE&QMk!tL z6)h$J^Qb`@{7pBp>xHwMw(mBJmD2EXF+}R8am|=IZ-P+@N*68Kcdv*+&+lz;Y(W59 zt0(P9HA+3Zi?v$8kfAMAf89xSaJH#NJEu{*S{$wYCbUhnUwThGB(B*ntr3@rukV+B zR|{YEGwfQo_wY9JqNko(`l#_o^;<1XWAid|CDLv5ffu4}iw!C7juZVw^VNTS_-^qo ziI@e2m=gMo`a|*fldY>-A3F-7dSc?rDNjuLNIDsQRxO&_T&l_HWa;GvQ|6Z}m>RKI zJ^#@B1M?3jiZ6$cRVPX>&zI}(IkW)klc4@CwIEImZ57w6#R+XuAm$!YN#kA4NzS{V z`;23at*&D|#FFp{YO(l6luGzK^sxAc`i18YYeWweoU^(?m|L{a{BVuxWRIlkD8aMh5cszMNtsdhJv+|H?>B#?AmhR(4HBk(`VOI)|vHJv$Xn)8`tg~ zrPW_8Yp5t4AE^_AwO@A=qu)CI^syu6x-F^_yR8Yd)HnTOv6C2m;bYP7#Jzmg^&)cy5zRkujFTDBf$%aGKo1;bL zUTFXf@Y&rvPP`d;Xx64W*POXd=lc2U9(?eDe=ai@xT>dAm<7>x-DX&M_lo)RBJDK| zciwAmuCP5e$tWdkGKmS%f??&n74zmrmQ*#4yU%=|^s72wEA0KyBrZO*;fVg?<9$u~ zi?Jyt{hRrtwfZBmRdDW9U7sd{YbBAye;g&^QN`)*P3;QLdAyt@on#3-7htietP5GIJNN849zP& z@yS1;_wU)ZYPa$EZ6#yJRN2Ny|0rHJJke19sNI-6G*?QJbZ4!X-+boGg$uT42A5XO zshu7z>K=OG_*vtY=6mL^i`G5S*f{5ISHtSNo1+DAYrUlY(MLo7+A|B!H;>l}IojaM zhs8CA^+%FT`k7NeVA8LeB$Eb=MhsVr!!Ca(#)tHm$Zd$tsjOM!AXqs0)v0>w!ER%5Tf&Jp4{o=CyLZdijuekcK z(6XplD@3lpZ>^YQs@B%6o%R^0_o%5_Vb%N=@nDPi*uG#fUJQJ<)zzy1dFy+IsRv$| z_=8d8FTWuwKFxl9$eQTo8hzUvn@*khDDvB3XL_a^tD~wuaRE6QN*0p z`|3~kp4@rJxNharMXRF)<7C&w$xEUI{kbV7{o{}BSLx5qH|e)7z6xv+PC=9v=9y}n z$2?}%O*L&5eYDL+!65Ds!!)ALD-}I^-#Jn8i58Zt-^j`{3F0HWq$2fq*UrEELF5M$ z4x~?*IIXna{FFb|?&D6;9wKF!| zZCo;uE{Ybvwlgrgz&i4Hu4{KC^Ylg4!KsX@sV_$}y+Lm_Gf~mFTji z28la0>hk_A&6_rZn_W?^+Ah9XtNur|YO(sMx|$~{jKi~YdPM8WwB>5ud(y0ZVqr^L zd<)p*uk#PIO*kMJq*)c>EVb?(?HIAI>Di^*#W+*N0<&;t+*FgWYG8}_S&KMfKi6hx zRXn}iU^{Sj@(;!zzrQG&L`&j}5}8%}=L@sa(~F||v2X8TOlQ~P$TId1&w z+^DWyQ?1E~#Vsu$mrozqE7tB5^Y(J0x>Y=SOd%%jHHfuhx1CZqG4B@jmJDqUgXGfO zu~b!kQF=rS*L1K7ok6_A)Wi&LeY6EcwKoD)�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�JPe`huN^p8bjn=3Z&;7s<45)w=$d&C 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 QQlBn@4@%x{NGc-lI1ZGKwEzGB diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Regular.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Regular.otf deleted file mode 100644 index 38941ae72f5c9b0d9f3ba46c812778261177698c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127448 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 diff --git a/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Semibold.otf b/cmd/mist/assets/qml/views/network-health/dapp-styles/fonts/SourceSansPro-Semibold.otf deleted file mode 100644 index fd41bcf1c4cba814a89bd45b4f5cb814c1d4a70f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127336 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 z 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 diff --git a/cmd/mist/assets/qml/views/network-health/index.html b/cmd/mist/assets/qml/views/network-health/index.html deleted file mode 100755 index 96c958a35..000000000 --- a/cmd/mist/assets/qml/views/network-health/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Network - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/cmd/mist/assets/qml/views/network-health/loading.css b/cmd/mist/assets/qml/views/network-health/loading.css deleted file mode 100644 index 1b3f4bd65..000000000 --- a/cmd/mist/assets/qml/views/network-health/loading.css +++ /dev/null @@ -1,92 +0,0 @@ -body { - background-color: #000; - font: 16px solid 'Helvetica Neue', sans-serif; -} - -.inject-loading-container { - position: relative; - padding-top: 20%; - /*left: 50%;*/ - margin: 0 auto; - /*max-width: 600px;*/ - /*margin-left: -300px;*/ - text-align: center; - -} -.inject-loading-container h1 { - text-align: center; - font-weight: 300; - font-size: 2em; -} - -img.loading-circle { - width: 24px; - height: 24px; - - animation: rotate 1s linear infinite; - -moz-animation: rotate 1s linear infinite; - -webkit-animation: rotate 1s linear infinite; - -ms-animation: rotate 1s linear infinite; - - transform-origin:50% 49.5%; - -ms-transform-origin:50% 49.5%; /* IE 9 */ - -moz-transform-origin:50% 49.5%; /* Chrome, Safari, Opera */ - -webkit-transform-origin:50% 49.5%; /* Chrome, Safari, Opera */ -} - -/* Keyframes */ -@-webkit-keyframes rotate { - 0% { - -webkit-transform: rotate(0deg); - } - 50% { - opacity: 0.2; - } - 100% { - -webkit-transform: rotate(360deg); - } -} -@-moz-keyframes rotate { - 0% { - -moz-transform: rotate(0deg); - } - 50% { - opacity: 0.2; - } - 100% { - -moz-transform: rotate(360deg); - } -} -@-o-keyframes rotate { - 0% { - -o-transform: rotate(0deg); - } - 50% { - opacity: 0.2; - } - 100% { - -o-transform: rotate(360deg); - } -} -@-ms-keyframes rotate { - 0% { - -ms-transform: rotate(0deg); - } - 50% { - opacity: 0.2; - } - 100% { - -ms-transform-origin: rotate(360deg); - } -} -@keyframes rotate { - 0% { - transform: rotate(0deg); - } - 50% { - opacity: 0.2; - } - 100% { - transform: rotate(360deg); - } -} \ No newline at end of file diff --git a/cmd/mist/assets/qml/views/network.qml b/cmd/mist/assets/qml/views/network.qml deleted file mode 100644 index fe4c7734f..000000000 --- a/cmd/mist/assets/qml/views/network.qml +++ /dev/null @@ -1,159 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Controls.Styles 1.0 -import QtQuick.Layouts 1.0; -import QtWebEngine 1.0 -import QtWebEngine.experimental 1.0 -import QtQuick.Window 2.0; -import Ethereum 1.0 -import Qt.WebSockets 1.0 -//import "qwebchannel.js" as WebChannel - - - -Rectangle { - id: window - anchors.fill: parent - color: "#00000000" - - property var title: "Network" - property var iconSource: "../mining-icon.png" - property var menuItem - property var hideUrl: true - - property alias url: webview.url - property alias windowTitle: webview.title - property alias webView: webview - - property var cleanPath: false - property var open: function(url) { - if(!window.cleanPath) { - var uri = url; - if(!/.*\:\/\/.*/.test(uri)) { - uri = "http://" + uri; - } - - var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ - - if(reg.test(uri)) { - uri.replace(reg, function(match, pre, domain, path) { - uri = pre; - - var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); - var ip = []; - for(var i = 0, l = lookup.length; i < l; i++) { - ip.push(lookup.charCodeAt(i)) - } - - if(ip.length != 0) { - uri += lookup; - } else { - uri += domain; - } - - uri += path; - }); - } - - window.cleanPath = true; - - webview.url = uri; - - //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2$3"); - uriNav.text = uri; - - } else { - // Prevent inf loop. - window.cleanPath = false; - } - } - - Label { - objectName: "miningLabel" - visible: false - font.pixelSize: 10 - anchors.right: lastBlockLabel.left - anchors.rightMargin: 5 - onTextChanged: { - menuItem.secondaryTitle = eth.miner().mining()? eth.miner().hashRate() + " Khash" : "" - } - } - - Item { - objectName: "root" - id: root - anchors.fill: parent - state: "inspectorShown" - - Timer { - interval: 1000; running: true; repeat: true - onTriggered: { - webview.runJavaScript("Miner.mining", function(miningSliderValue) { - - // Check if it's mining and set it accordingly - if (miningSliderValue > 0 && !eth.miner().mining()) { - // If the - eth.miner().start(); - } else if (miningSliderValue == 0 && eth.miner().mining()) { - eth.miner().stop(); - } else if (eth.miner().mining()) { - - webview.runJavaScript('var miningData = MiningData.findOne(); MiningData.update(miningData._id, {$inc: {totalTimeSpent: 1}}); Miner.hashrate = ' + eth.miner().hashRate() ); - - //var miningData = MiningData.findOne(); MiningData.update(miningData._id, {$inc: {totalTimeSpent: 1}}); - - } else if (miningSliderValue == "undefined") { - - webview.runJavaScript('Miner.mining = 0' ); - - } - }); - - } - } - - WebEngineView { - objectName: "webView" - id: webview - anchors.fill: parent - - url: "network-health/index.html" - //url: "http://localhost:3000/" - - experimental.settings.javascriptCanAccessClipboard: true - - - onJavaScriptConsoleMessage: { - console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); - } - - onLoadingChanged: { - if (loadRequest.status == WebEngineView.LoadSucceededStatus) { - webview.runJavaScript(eth.readFile("mist.js")); - } - } - } - - WebEngineView { - id: inspector - visible: false - z:10 - anchors { - left: root.left - right: root.right - top: root.top - bottom: root.bottom - } - - } - - states: [ - State { - name: "inspectorShown" - PropertyChanges { - target: inspector - } - } - ] - } -} diff --git a/cmd/mist/assets/qml/views/pending_tx.qml b/cmd/mist/assets/qml/views/pending_tx.qml deleted file mode 100644 index 3dcedeff2..000000000 --- a/cmd/mist/assets/qml/views/pending_tx.qml +++ /dev/null @@ -1,53 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - property var title: "Pending Transactions" - property var menuItem - - objectName: "pendingTxView" - anchors.fill: parent - visible: false - id: pendingTxView - - property var pendingTxModel: ListModel { - id: pendingTxModel - } - - TableView { - id: pendingTxTableView - anchors.fill: parent - TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "from" ; title: "sender" ; width: 230 } - TableViewColumn{ role: "to" ; title: "Reciever" ; width: 230 } - TableViewColumn{ role: "contract" ; title: "Contract" ; width: 100 } - - model: pendingTxModel - } - - function addTx(tx, inout) { - var isContract - if (tx.contract == true){ - isContract = "Yes" - }else{ - isContract = "No" - } - - - pendingTxModel.insert(0, {hash: tx.hash, to: tx.address, from: tx.sender, value: tx.value, contract: isContract}) - } - - function removeTx(tx) { - for (var i = 0; i < pendingTxModel.count; i++) { - if (tx.hash === pendingTxModel.get(i).hash) { - pendingTxModel.remove(i); - break; - } - } - } -} diff --git a/cmd/mist/assets/qml/views/transaction.qml b/cmd/mist/assets/qml/views/transaction.qml deleted file mode 100644 index df798a9c0..000000000 --- a/cmd/mist/assets/qml/views/transaction.qml +++ /dev/null @@ -1,216 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - property var title: "New Transaction" - property var menuItem - - objectName: "newTxView" - visible: false - anchors.fill: parent - color: "#00000000" - - Column { - id: mainContractColumn - anchors.fill: parent - - - states: [ - State{ - name: "ERROR" - - PropertyChanges { target: txResult; visible:true} - PropertyChanges { target: codeView; visible:true} - }, - State { - name: "DONE" - - PropertyChanges { target: txValue; visible:false} - PropertyChanges { target: txGas; visible:false} - PropertyChanges { target: txGasPrice; visible:false} - PropertyChanges { target: codeView; visible:false} - PropertyChanges { target: txButton; visible:false} - PropertyChanges { target: txDataLabel; visible:false} - PropertyChanges { target: atLabel; visible:false} - PropertyChanges { target: txFuelRecipient; visible:false} - PropertyChanges { target: valueDenom; visible:false} - PropertyChanges { target: gasDenom; visible:false} - - PropertyChanges { target: txResult; visible:true} - PropertyChanges { target: txOutput; visible:true} - PropertyChanges { target: newTxButton; visible:true} - }, - State { - name: "SETUP" - - PropertyChanges { target: txValue; visible:true; text: ""} - PropertyChanges { target: txGas; visible:true;} - PropertyChanges { target: txGasPrice; visible:true;} - PropertyChanges { target: codeView; visible:true; text: ""} - PropertyChanges { target: txButton; visible:true} - PropertyChanges { target: txDataLabel; visible:true} - PropertyChanges { target: valueDenom; visible:true} - PropertyChanges { target: gasDenom; visible:true} - - PropertyChanges { target: txResult; visible:false} - PropertyChanges { target: txOutput; visible:false} - PropertyChanges { target: newTxButton; visible:false} - } - ] - width: 400 - spacing: 5 - anchors.left: parent.left - anchors.top: parent.top - anchors.leftMargin: 5 - anchors.topMargin: 5 - - ListModel { - id: denomModel - ListElement { text: "Wei" ; zeros: "" } - ListElement { text: "Ada" ; zeros: "000" } - ListElement { text: "Babbage" ; zeros: "000000" } - ListElement { text: "Shannon" ; zeros: "000000000" } - ListElement { text: "Szabo" ; zeros: "000000000000" } - ListElement { text: "Finney" ; zeros: "000000000000000" } - ListElement { text: "Ether" ; zeros: "000000000000000000" } - ListElement { text: "Einstein" ;zeros: "000000000000000000000" } - ListElement { text: "Douglas" ; zeros: "000000000000000000000000000000000000000000" } - } - - - TextField { - id: txFuelRecipient - placeholderText: "Address / Name or empty for contract" - //validator: RegExpValidator { regExp: /[a-f0-9]{40}/ } - width: 400 - } - - RowLayout { - TextField { - id: txValue - width: 222 - placeholderText: "Amount" - validator: RegExpValidator { regExp: /\d*/ } - onTextChanged: { - contractFormReady() - } - } - - ComboBox { - id: valueDenom - currentIndex: 5 - model: denomModel - } - } - - RowLayout { - TextField { - id: txGas - width: 50 - validator: RegExpValidator { regExp: /\d*/ } - placeholderText: "Gas" - text: "5000" - } - Label { - id: atLabel - text: "@" - } - - TextField { - id: txGasPrice - width: 200 - placeholderText: "Gas price" - text: "10" - validator: RegExpValidator { regExp: /\d*/ } - } - - ComboBox { - id: gasDenom - currentIndex: 4 - model: denomModel - } - } - - Label { - id: txDataLabel - text: "Data" - } - - TextArea { - id: codeView - height: 300 - anchors.topMargin: 5 - width: 400 - onTextChanged: { - contractFormReady() - } - } - - - Button { - id: txButton - /* enabled: false */ - states: [ - State { - name: "READY" - PropertyChanges { target: txButton; /*enabled: true*/} - }, - State { - name: "NOTREADY" - PropertyChanges { target: txButton; /*enabled:false*/} - } - ] - text: "Send" - onClicked: { - var value = txValue.text + denomModel.get(valueDenom.currentIndex).zeros; - var gasPrice = txGasPrice.text + denomModel.get(gasDenom.currentIndex).zeros; - var res = gui.transact(txFuelRecipient.text, value, txGas.text, gasPrice, codeView.text) - if(res[1]) { - txResult.text = "Your contract could not be sent over the network:\n" - txResult.text += res[1].error() - txResult.text += "" - mainContractColumn.state = "ERROR" - } else { - txResult.text = "Your transaction has been submitted:\n" - txOutput.text = res.toString() - mainContractColumn.state = "DONE" - - console.log(res) - } - } - } - Text { - id: txResult - visible: false - } - TextField { - id: txOutput - visible: false - width: 530 - } - Button { - id: newTxButton - visible: false - text: "Create a new transaction" - onClicked: { - this.visible = false - txResult.text = "" - txOutput.text = "" - mainContractColumn.state = "SETUP" - } - } - } - - function contractFormReady(){ - if(codeView.text.length > 0 && txValue.text.length > 0 && txGas.text.length > 0 && txGasPrice.length > 0) { - txButton.state = "READY" - }else{ - txButton.state = "NOTREADY" - } - } -} diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml deleted file mode 100644 index 2369390c3..000000000 --- a/cmd/mist/assets/qml/views/wallet.qml +++ /dev/null @@ -1,190 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - id: root - property var title: "Wallet" - property var menuItem - - objectName: "walletView" - anchors.fill: parent - - Label { - objectName: "balanceLabel" - visible: false - onTextChanged: { - balance.text = text - menuItem.secondaryTitle = text - } - } - - function onReady() { - setBalance() - } - - function setBalance() { - balance.text = "Balance: " + eth.numberToHuman(eth.balanceAt(eth.coinbase())) - if(menuItem) - menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.coinbase())) - } - - ListModel { - id: denomModel - ListElement { text: "Wei" ; zeros: "" } - ListElement { text: "Ada" ; zeros: "000" } - ListElement { text: "Babbage" ; zeros: "000000" } - ListElement { text: "Shannon" ; zeros: "000000000" } - ListElement { text: "Szabo" ; zeros: "000000000000" } - ListElement { text: "Finney" ; zeros: "000000000000000" } - ListElement { text: "Ether" ; zeros: "000000000000000000" } - ListElement { text: "Einstein" ;zeros: "000000000000000000000" } - ListElement { text: "Douglas" ; zeros: "000000000000000000000000000000000000000000" } - } - - ColumnLayout { - spacing: 10 - y: 40 - anchors.fill: parent - - Text { - id: balance - font.pixelSize: 24 - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top - topMargin: 20 - } - } - - Rectangle { - id: newTxPane - color: "#ececec" - border.color: "#cccccc" - border.width: 1 - anchors { - top: balance.bottom - topMargin: 10 - left: parent.left - leftMargin: 5 - right: parent.right - rightMargin: 5 - } - height: 100 - - RowLayout { - id: amountFields - spacing: 10 - anchors { - top: parent.top - topMargin: 20 - left: parent.left - leftMargin: 20 - } - - Text { - text: "Ξ " - } - - // There's something off with the row layout where textfields won't listen to the width setting - Rectangle { - width: 50 - height: 20 - TextField { - id: txValue - width: parent.width - placeholderText: "0.00" - } - } - - ComboBox { - id: valueDenom - currentIndex: 5 - model: denomModel - } - - } - - RowLayout { - id: toFields - spacing: 10 - anchors { - top: amountFields.bottom - topMargin: 5 - left: parent.left - leftMargin: 20 - } - - Text { - text: "To" - } - - Rectangle { - width: 200 - height: 20 - TextField { - id: txTo - width: parent.width - placeholderText: "Address or name" - } - } - - Button { - text: "Send" - onClicked: { - var value = txValue.text + denomModel.get(valueDenom.currentIndex).zeros; - var gasPrice = "10000000000000" - var res = eth.transact({from: eth.coinbase(), to: txTo.text, value: value, gas: "500", gasPrice: gasPrice}) - } - } - } - } - - Rectangle { - anchors { - left: parent.left - right: parent.right - top: newTxPane.bottom - topMargin: 10 - bottom: parent.bottom - } - TableView { - id: txTableView - anchors.fill : parent - TableViewColumn{ role: "num" ; title: "#" ; width: 30 } - TableViewColumn{ role: "from" ; title: "From" ; width: 340 } - TableViewColumn{ role: "to" ; title: "To" ; width: 340 } - TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 } - - model: ListModel { - id: txModel - Component.onCompleted: { - } - - function addTxs(messages) { - /* - setBalance() - - for(var i = 0; i < messages.length; i++) { - var message = messages.get(i); - var to = eth.lookupName(message.to); - var from; - if(message.from.length == 0) { - from = "- MINED -"; - } else { - from = eth.lookupName(message.from); - } - txModel.insert(0, {num: txModel.count, from: from, to: to, value: eth.numberToHuman(message.value)}) - } - */ - } - } - } - } - - } -} diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml deleted file mode 100644 index dc097b806..000000000 --- a/cmd/mist/assets/qml/views/whisper.qml +++ /dev/null @@ -1,74 +0,0 @@ - -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import QtQuick.Dialogs 1.0; -import QtQuick.Window 2.1; -import QtQuick.Controls.Styles 1.1 -import Ethereum 1.0 - -Rectangle { - id: root - property var title: "Whisper Traffic" - property var menuItem - - objectName: "whisperView" - anchors.fill: parent - - property var identity: "" - Component.onCompleted: { - identity = shh.newIdentity() - - var t = shh.watch({}, root) - } - - function onShhMessage(message, i) { - whisperModel.insert(0, {from: message.from, payload: eth.toAscii(message.payload)}) - } - - RowLayout { - id: input - anchors { - left: parent.left - leftMargin: 20 - top: parent.top - topMargin: 20 - } - - TextField { - id: to - placeholderText: "To" - } - TextField { - id: data - placeholderText: "Data" - } - TextField { - id: topics - placeholderText: "topic1, topic2, topic3, ..." - } - Button { - text: "Send" - onClicked: { - shh.post([eth.toHex(data.text)], "", identity, topics.text.split(","), 500, 50) - } - } - } - - TableView { - id: txTableView - anchors { - top: input.bottom - topMargin: 10 - bottom: parent.bottom - left: parent.left - right: parent.right - } - TableViewColumn{ id: fromRole; role: "from" ; title: "From"; width: 300 } - TableViewColumn{ role: "payload" ; title: "Payload" ; width: parent.width - fromRole.width - 2 } - - model: ListModel { - id: whisperModel - } - } -} diff --git a/cmd/mist/assets/tx.png b/cmd/mist/assets/tx.png deleted file mode 100644 index 62204c3152f55b9fa0265bb322721bf352518025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4070 zcmZ`*2{=@38y-yArLttJX|kl48Czu=%h;wAvSehNVKB@fGYrX^C5&XtQpmn9MG+xO zmiSGwB_Y|8E%I5Df2jZa{9S$Ly3Uz%?&rSW=eeKrKIfV+{VUq+Ec`400Dv8-qj8n? zdwlm~I!L=J!b&m#02VbI0-=vYAVB(VE_OIP768y;Pq|MvG92UyrPiLWeRBj15?SHD z$qag{sKX632t)eo(}x6!dT1Qb;yNsDVr%r0PCFEAqshg3I}kI#yv(WJ(qN#WIXO&m zVqPqk`!WpM|JVNkWHo3=#M0ejAc@Q z>E?+dAMG=5F=A_tkja3_wbMO4>koASFs>x4&S}wfe3-N*7vDnIGChDPu37$t8%M;3 zyhAF$Gsk`+92kbgA)w*#n{Sx_Dzi z1>vCT%a`yB2t+YUw*YzRtYe^jo zTPBJ*yea{wklZp@&B>hHoJ$&=oopNlRNL(}&Ykg>^0@!BH%UB9d&#>L{Mp#xa~yL} zm_tplQh@0_h%HNyU*DMDv2$XKe7-48Tn_G50H0ua{VF75n~O34af(6MS>-0Z&+K(h zDVDan7Y@bIrNk)dn?I&EPq3PYJCEtAfeoit*`jRSL^34!GDm~(4fIFuF_Ip!$Ob@Q z^b*$Wg8nkD3?m>wkiQNm!+i#b4n0m4_(TowSs#*S%;F;`#A;7n7j~b`WLtuULnHnamJ`_ zyb;YicII|LIznH08AlZZ4bUs0c6X|=3KjtE=FVQB^M3;B!oE@i3z(!y;rtfi% zsaTPU2lKhZ47rV!726PHMbn-q(7%yzZ$kM~ zQPvMaMnymFv?!O}ML|vV!7K6?pR0PQdLgo}vgbMXnieEhr#GUHp;ry^7wTLAAj!AhXOQU2CkO zQ8^f?nVb=ixr0f@gkf%fl6z$!@**Z6rt*khzUoZbTaoOO{OUc~UT>=^E>|eL$G(RN zX`j#9>WQ6swQ}Nf?Futi1bcn*^rYY<|77{=s|Ool*6T7?`LZdolp0FZH`%G@)N$(2 zxl)|v&I|GQjWfa#Q=vE9G5BEn*yZ^VD3ap{{bQg11Dsq!^V$Jwt0b*4~jkPS*ta^c|l4JXY1U zL>Xrk^A>yDgUlUGL3N3Dv3F&%vhjZ9?Ug*{)_r5FO3*DDVhf>IdAg?e8V|*fo6T-^ zULJ^?_Gl(F55H3$+^*U>d+5@kXzhsBxZK!jek!ZworKbB(bq~VW7aT>j*Gc)1$Y=d z5`MJKqpr{gx{lta-}cxX{xdTS^PK$TBuQOqcy9A%yp0^Huh9&Y(-Z-+01j?aB!8DD_N znBOm-d++viGQWdba?h#(b>qx&ffGWboI7Dh8}lc1OIEC&lP7@#u{EJvG1Dz)rz4jv z*0JBCfeArRg1R*lnk~X?kR?cNSM17MwVWgZoR&hn`;{TQpRU{Z%&` zMF0_W2ETS_bwpwXMxDb)dJP^Kl+{@~lrK)Ts6SUX7^{`+y3T=rh3Cf458IU&I}Rm) zExZ51bbJc`q$lzrW_A?ib8Ta|b2VtbHhVRDi~P}piTq)Bruv&{5(Z^C_@?BeMe$_k za>jCH&9%8Y6ZG{P)`xIWwow(*c~5FDmO5(p<$lTf62KpoJXQO}yK+9|ee2Lb{V2h& zhc1%g6(jsOm*5M(wl#gHVl~1m^oOycChBa)m+E?ZKPx|td7Y(bs&=q;c57pld!J(O z!1=uMapxK%V_F`M-)ME&{`eQd`)J{ezD(xxb>M}Q@=Kpu*H0{_vMCLEh5HoDh;65> zK6_&pZkFEvp+D?d);XNFuJ`DSe@}`~myo2&gPmI|l+~o<^4Ip4sL@^A4JA z+ue-$hb&b(Z(i7T*tVG)&k$qLJCjcTYM%^21{Q01%8bG9{T_)>W`^AwbZ!E*LDtli*5Y z0{}{%3bb1SmV^d*67bGM1y5!09z%h4zY9abpgju7Nf~T=EN?u+b3X_IPOH0xil0+|O653PJ znRx2wBL7=Q1531V!?}`hF3zCcb`C$iAd8){V^S_w|@)&uSid{>(69+ zP5kLiX}5BPt5~87-hHw3xDZ_3utXwF2ABIK*^m9sH~l9K z{Jiup!G7>}fu0+V<`lhK*WWem$A0Id{*+)pxKFU#dIf!)Cl+t2ful8a&xH(33Hryt z??QwN-o?$(6>WpvEo@J+5Bi!etj*oSl~jnuLW*!=z*-VbYS)7mTE&6kyT{(ifDVzj5|eup2?RVbLTP zHzOApJbcduVfPUv1EIP8J^o9o1l^sYeN**wWcN_o%)(h{%KyzjoW*(7V;KOT6GCdJ z8R@VO-?w0CgmDH5>?lWmy!}}oNX`7%#|2bd%y4jedP9_SDR`y0<^aP`1+pyxc@7bq zmHFw#nqt|tJ7SIErA;{I0-~t|fA8T?uxk&d}@(>~Wg2Sm{ za6Wy}YL&s#L3SAp6AuUR1mWYiiIONGBmEDREglU;vdfgUbu+L;jPAqP(*yZtVSN!7 zuAvVALn~V%h&YS%#N$uSOoy}U6Eca}1wrc*ehk(1!(38XaE2J diff --git a/cmd/mist/assets/util/test.html b/cmd/mist/assets/util/test.html deleted file mode 100644 index d458e6670..000000000 --- a/cmd/mist/assets/util/test.html +++ /dev/null @@ -1,43 +0,0 @@ - - -Utils - - - -