├── .coveralls.yml
├── .gitignore
├── .jshintrc
├── .travis.yml
├── LICENSE
├── README.md
├── bower.json
├── docs
└── index.md
├── gulpfile.js
├── index.js
├── lib
├── index.js
├── insight.js
└── models
│ ├── addressinfo.js
│ └── index.js
├── package.json
└── test
├── index.html
├── insight.js
├── mocha.opts
└── models
├── addressinfo.js
└── sampleAddressFromInsight.json
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | repo_token: hweI3rqbeyC86f0Tku7G1jQyQQyn0ML2b
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw[a-z]
2 | coverage
3 | node_modules
4 | bitcore-explorers.js
5 | bitcore-explorers.min.js
6 |
7 | lib/errors/index.js
8 | npm-debug.log
9 |
10 | bower_components
11 | report
12 | .DS_Store
13 | tests.js
14 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.).
3 | "browser": true, // Standard browser globals e.g. `window`, `document`.
4 | "camelcase": false, // Permit only camelcase for `var` and `object indexes`.
5 | "curly": true, // Require {} for every new block or scope.
6 | "devel": false, // Allow development statements e.g. `console.log();`.
7 | "eqeqeq": true, // Require triple equals i.e. `===`.
8 | "esnext": true, // Allow ES.next specific features such as `const` and `let`.
9 | "freeze": true, // Forbid overwriting prototypes of native objects such as Array, Date and so on.
10 | "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
11 | "indent": 2, // Specify indentation spacing
12 | "latedef": true, // Prohibit variable use before definition.
13 | "newcap": false, // Require capitalization of all constructor functions e.g. `new F()`.
14 | "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`.
15 | "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
16 | "noempty": true, // Prohibit use of empty blocks.
17 | "nonew": true, // Prohibits the use of constructor functions for side-effects
18 | "quotmark": "single", // Define quotes to string values.
19 | "regexp": true, // Prohibit `.` and `[^...]` in regular expressions.
20 | "smarttabs": false, // Supress warnings about mixed tabs and spaces
21 | "strict": true, // Require `use strict` pragma in every file.
22 | "trailing": true, // Prohibit trailing whitespaces.
23 | "undef": true, // Require all non-global variables be declared before they are used.
24 | "unused": true, // Warn unused variables.
25 |
26 | "maxparams": 4, // Maximum number of parameters for a function
27 | "maxstatements": 15, // Maximum number of statements in a function
28 | "maxcomplexity": 6, // Cyclomatic complexity (http://en.wikipedia.org/wiki/Cyclomatic_complexity)
29 | "maxdepth": 4, // Maximum depth of nested control structures
30 | "maxlen": 120, // Maximum number of cols in a line
31 | "multistr": true, // Allow use of multiline EOL escaping
32 |
33 | "predef": [ // Extra globals.
34 | "after",
35 | "afterEach",
36 | "before",
37 | "beforeEach",
38 | "define",
39 | "describe",
40 | "exports",
41 | "it",
42 | "module",
43 | "require"
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | before_install:
5 | - export DISPLAY=:99.0
6 | - sh -e /etc/init.d/xvfb start
7 | install:
8 | - npm install
9 | after_script:
10 | - gulp coveralls
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 BitPay
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Blockchain APIs for bitcore
3 |
4 | [](https://www.npmjs.org/package/bitcore-explorers)
5 | [](https://travis-ci.org/bitpay/bitcore-explorers)
6 | [](https://coveralls.io/r/bitpay/bitcore-explorers)
7 |
8 | A module for [bitcore](https://github.com/bitpay/bitcore) that implements HTTP requests to different Web APIs to query the state of the blockchain.
9 |
10 | ## Getting started
11 |
12 | Be careful! When using this module, the information retrieved from remote servers may be compromised and not reflect the actual state of the blockchain.
13 |
14 | ```sh
15 | npm install bitcore-explorers
16 | bower install bitcore-explorers
17 | ```
18 |
19 | At the moment, only Insight is supported, and only getting the UTXOs for an address and broadcasting a transaction.
20 |
21 | ```javascript
22 | var explorers = require('bitcore-explorers');
23 | var insight = new explorers.Insight();
24 |
25 | insight.getUtxos('1Bitcoin...', function(err, utxos) {
26 | if (err) {
27 | // Handle errors...
28 | } else {
29 | // Maybe use the UTXOs to create a transaction
30 | }
31 | });
32 | ```
33 |
34 | ## Contributing
35 |
36 | See [CONTRIBUTING.md](https://github.com/bitpay/bitcore/blob/master/CONTRIBUTING.md) on the main bitcore repo for information about how to contribute.
37 |
38 | ## License
39 |
40 | Code released under [the MIT license](https://github.com/bitpay/bitcore/blob/master/LICENSE).
41 |
42 | Copyright 2013-2015 BitPay, Inc. Bitcore is a trademark maintained by BitPay, Inc.
43 |
44 | [bitcore]: http://github.com/bitpay/bitcore-explorers
45 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bitcore-explorers",
3 | "main": "/bitcore-explorers.min.js",
4 | "version": "1.0.1",
5 | "homepage": "https://github.com/bitpay/bitcore-explorers",
6 | "authors": [
7 | "BitPay"
8 | ],
9 | "description": "Module to query blockchain apis for Bitcore.",
10 | "moduleType": [
11 | "globals"
12 | ],
13 | "keywords": [
14 | "bitcoin",
15 | "bitcore",
16 | "btc",
17 | "satoshi",
18 | "insight"
19 | ],
20 | "license": "MIT",
21 | "ignore": [
22 | "**/.*",
23 | "index.js",
24 | "gulpfile.js",
25 | "README.md",
26 | "node_modules",
27 | "bower_components",
28 | "test"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Explorers
2 | The `bitcore-explorers` module provides a convenient interface to retrieve unspent transaction outputs and broadcast transactions to the Bitcoin network via blockchain explorers.
3 |
4 | ## Installation
5 | Explorers is implemented as a separate module.
6 |
7 | For node projects:
8 |
9 | ```
10 | npm install bitcore-explorers --save
11 | ```
12 |
13 | For client-side projects:
14 |
15 | ```
16 | bower install bitcore-explorers --save
17 | ```
18 |
19 | ## Insight
20 | ### Description
21 | `Insight` is a simple agent to perform queries to an Insight blockchain explorer. The default servers are `https://insight.bitpay.com` and `https://test-insight.bitpay.com`, hosted by BitPay Inc. You can (and we strongly suggest you do) run your own insight server. For more information, head to [https://github.com/bitpay/insight-api](https://github.com/bitpay/insight-api)
22 |
23 | There are currently two methods implemented: `getUnspentUtxos` and `broadcast`. The API will grow as features are requested.
24 |
25 | #### Retrieving Unspent UTXOs for an Address (or set of)
26 |
27 | ```javascript
28 | var Insight = require('bitcore-explorers').Insight;
29 | var insight = new Insight();
30 |
31 | insight.getUnspentUtxos('1Bitcoin...', function(err, utxos) {
32 | if (err) {
33 | // Handle errors...
34 | } else {
35 | // Maybe use the UTXOs to create a transaction
36 | }
37 | });
38 | ```
39 |
40 | #### Broadcasting a Transaction
41 |
42 | ```javascript
43 | var insight = new Insight();
44 | insight.broadcast(tx, function(err, returnedTxId) {
45 | if (err) {
46 | // Handle errors...
47 | } else {
48 | // Mark the transaction as broadcasted
49 | }
50 | });
51 | ```
52 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var build = require('bitcore-build');
4 |
5 | build('explorers');
6 |
7 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./lib');
2 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | models: require('./models'),
3 | Insight: require('./insight'),
4 | bitcore: require('bitcore-lib'),
5 | };
6 |
--------------------------------------------------------------------------------
/lib/insight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var request = require('request');
4 |
5 | var bitcore = require('bitcore-lib');
6 | var _ = bitcore.deps._;
7 |
8 | var $ = bitcore.util.preconditions;
9 | var Address = bitcore.Address;
10 | var JSUtil = bitcore.util.js;
11 | var Networks = bitcore.Networks;
12 | var Transaction = bitcore.Transaction;
13 | var UnspentOutput = Transaction.UnspentOutput;
14 | var AddressInfo = require('./models/addressinfo');
15 |
16 |
17 | /**
18 | * Allows the retrieval of information regarding the state of the blockchain
19 | * (and broadcasting of transactions) from/to a trusted Insight server.
20 | * @param {string=} url the url of the Insight server
21 | * @param {Network=} network whether to use livenet or testnet
22 | * @constructor
23 | */
24 | function Insight(url, network) {
25 | if (!url && !network) {
26 | return new Insight(Networks.defaultNetwork);
27 | }
28 | if (Networks.get(url)) {
29 | network = Networks.get(url);
30 | if (network === Networks.livenet) {
31 | url = 'https://insight.bitpay.com';
32 | } else {
33 | url = 'https://test-insight.bitpay.com';
34 | }
35 | }
36 | JSUtil.defineImmutable(this, {
37 | url: url,
38 | network: Networks.get(network) || Networks.defaultNetwork
39 | });
40 | this.request = request;
41 | return this;
42 | }
43 |
44 | /**
45 | * @callback Insight.GetTransactionCallback
46 | * @param {Error} err
47 | * @param {Object} transaction
48 | */
49 |
50 | /**
51 | * Get transaction by txid
52 | * @param {string} txid
53 | * @param {GetTransactionCallback} callback
54 | */
55 | Insight.prototype.getTransaction = function(txid, callback) {
56 | $.checkArgument(_.isFunction(callback));
57 | $.checkArgument(_.isString(txid));
58 | $.checkArgument(txid.length === 64);
59 |
60 | this.requestGet('/api/tx/' + txid, function(err, res, body) {
61 | if (err || res.statusCode !== 200) {
62 | return callback(err || res);
63 | }
64 | var tx = JSON.parse(body);
65 |
66 | return callback(null, tx);
67 | });
68 | };
69 |
70 | /**
71 | * @callback Insight.GetUtxosCallback
72 | * @param {Error} err
73 | * @param {Array.UnspentOutput} utxos
74 | */
75 |
76 | /**
77 | * Retrieve a list of unspent outputs associated with an address or set of addresses
78 | * @param {Address|string|Array.Address|Array.string} addresses
79 | * @param {GetUtxosCallback} callback
80 | */
81 | Insight.prototype.getUtxos = function(addresses, callback) {
82 | $.checkArgument(_.isFunction(callback));
83 | if (!_.isArray(addresses)) {
84 | addresses = [addresses];
85 | }
86 | addresses = _.map(addresses, function(address) {
87 | return new Address(address);
88 | });
89 |
90 | this.requestPost('/api/addrs/utxo', {
91 | addrs: _.map(addresses, function(address) {
92 | return address.toString();
93 | }).join(',')
94 | }, function(err, res, unspent) {
95 | if (err || res.statusCode !== 200) {
96 | return callback(err || res);
97 | }
98 | try {
99 | unspent = _.map(unspent, UnspentOutput);
100 | } catch (ex) {
101 | if (ex instanceof bitcore.errors.InvalidArgument) {
102 | return callback(ex);
103 | }
104 | }
105 |
106 | return callback(null, unspent);
107 | });
108 | };
109 |
110 | /**
111 | * @callback Insight.BroadcastCallback
112 | * @param {Error} err
113 | * @param {string} txid
114 | */
115 |
116 | /**
117 | * Broadcast a transaction to the bitcoin network
118 | * @param {transaction|string} transaction
119 | * @param {BroadcastCallback} callback
120 | */
121 | Insight.prototype.broadcast = function(transaction, callback) {
122 | $.checkArgument(JSUtil.isHexa(transaction) || transaction instanceof Transaction);
123 | $.checkArgument(_.isFunction(callback));
124 | if (transaction instanceof Transaction) {
125 | transaction = transaction.serialize();
126 | }
127 |
128 | this.requestPost('/api/tx/send', {
129 | rawtx: transaction
130 | }, function(err, res, body) {
131 | if (err || res.statusCode !== 200) {
132 | return callback(err || body);
133 | }
134 | return callback(null, body ? body.txid : null);
135 | });
136 | };
137 |
138 | /**
139 | * @callback Insight.AddressCallback
140 | * @param {Error} err
141 | * @param {AddressInfo} info
142 | */
143 |
144 | /**
145 | * Retrieve information about an address
146 | * @param {Address|string} address
147 | * @param {AddressCallback} callback
148 | */
149 | Insight.prototype.address = function(address, callback) {
150 | $.checkArgument(_.isFunction(callback));
151 | address = new Address(address);
152 |
153 | this.requestGet('/api/addr/' + address.toString(), function(err, res, body) {
154 | if (err || res.statusCode !== 200) {
155 | return callback(err || body);
156 | }
157 | var info;
158 | try {
159 | info = AddressInfo.fromInsight(body);
160 | } catch (e) {
161 | if (e instanceof SyntaxError) {
162 | return callback(e);
163 | }
164 | throw e;
165 | }
166 | return callback(null, info);
167 | });
168 | };
169 |
170 | /**
171 | * Internal function to make a post request to the server
172 | * @param {string} path
173 | * @param {?} data
174 | * @param {function} callback
175 | * @private
176 | */
177 | Insight.prototype.requestPost = function(path, data, callback) {
178 | $.checkArgument(_.isString(path));
179 | $.checkArgument(_.isFunction(callback));
180 | this.request({
181 | method: 'POST',
182 | url: this.url + path,
183 | json: data
184 | }, callback);
185 | };
186 |
187 | /**
188 | * Internal function to make a get request with no params to the server
189 | * @param {string} path
190 | * @param {function} callback
191 | * @private
192 | */
193 | Insight.prototype.requestGet = function(path, callback) {
194 | $.checkArgument(_.isString(path));
195 | $.checkArgument(_.isFunction(callback));
196 | this.request({
197 | method: 'GET',
198 | url: this.url + path
199 | }, callback);
200 | };
201 |
202 | module.exports = Insight;
203 |
--------------------------------------------------------------------------------
/lib/models/addressinfo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var bitcore = require('bitcore-lib');
4 |
5 | var _ = bitcore.deps._;
6 | var $ = bitcore.util.preconditions;
7 | var Address = bitcore.Address;
8 | var JSUtil = bitcore.util.js;
9 |
10 | function AddressInfo(param) {
11 | if (!(this instanceof AddressInfo)) {
12 | return new AddressInfo(param);
13 | }
14 | if (param instanceof AddressInfo) {
15 | return param;
16 | }
17 |
18 | $.checkArgument(param.address instanceof Address);
19 | $.checkArgument(_.isNumber(param.balance));
20 | $.checkArgument(_.isNumber(param.totalSent));
21 | $.checkArgument(_.isNumber(param.totalReceived));
22 | $.checkArgument(_.isNumber(param.unconfirmedBalance));
23 | $.checkArgument(_.isArray(param.transactionIds));
24 | $.checkArgument(_.all(_.map(param.transactionIds, JSUtil.isHexa)));
25 |
26 | JSUtil.defineImmutable(this, param);
27 | }
28 |
29 | AddressInfo.fromInsight = function(param) {
30 | if (_.isString(param)) {
31 | param = JSON.parse(param);
32 | }
33 | return new AddressInfo({
34 | address: new Address(param.addrStr),
35 | balance: param.balanceSat,
36 | totalReceived: param.totalReceivedSat,
37 | totalSent: param.totalSentSat,
38 | unconfirmedBalance: param.unconfirmedBalanceSat,
39 | transactionIds: param.transactions
40 | });
41 | };
42 |
43 | module.exports = AddressInfo;
44 |
--------------------------------------------------------------------------------
/lib/models/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | AddressInfo: require('./addressinfo')
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bitcore-explorers",
3 | "version": "1.0.1",
4 | "description": "Module to query blockchain apis for Bitcore.",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test": "gulp test",
11 | "coverage": "gulp coverage"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "https://github.com/bitpay/bitcore-explorers.git"
16 | },
17 | "keywords": [
18 | "bitcoin",
19 | "bitcore",
20 | "insight"
21 | ],
22 | "author": "BitPay",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/bitpay/bitcore-explorers/issues"
26 | },
27 | "browser": {
28 | "request": "browser-request"
29 | },
30 | "homepage": "https://github.com/bitpay/bitcore-explorers",
31 | "devDependencies": {
32 | "bitcore-build": "git://github.com/bitpay/bitcore-build.git",
33 | "brfs": "^1.2.0",
34 | "browserify": "^8.1.1",
35 | "chai": "^2.0.0",
36 | "gulp": "^3.8.10",
37 | "sinon": "^1.12.2"
38 | },
39 | "dependencies": {
40 | "bitcore-lib": "^0.13.14",
41 | "browser-request": "^0.3.3",
42 | "request": "^2.51.0"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocha
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/insight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var sinon = require('sinon');
4 | var should = require('chai').should();
5 | var expect = require('chai').expect;
6 | var bitcore = require('bitcore-lib');
7 | var explorers = require('../');
8 |
9 | var Insight = explorers.Insight;
10 | var Address = bitcore.Address;
11 | var Transaction = bitcore.Transaction;
12 | var AddressInfo = explorers.models.AddressInfo;
13 | var Networks = bitcore.Networks;
14 |
15 | describe('Insight', function() {
16 |
17 | describe('instantiation', function() {
18 | it('can be created without any parameters', function() {
19 | var insight = new Insight();
20 | should.exist(insight.url);
21 | should.exist(insight.network);
22 | if (insight.network === Networks.livenet) {
23 | insight.url.should.equal('https://insight.bitpay.com');
24 | } else if (insight.network === Networks.testnet) {
25 | insight.url.should.equal('https://test-insight.bitpay.com');
26 | }
27 | });
28 | it('can be created providing just a network', function() {
29 | var insight = new Insight(Networks.testnet);
30 | insight.url.should.equal('https://test-insight.bitpay.com');
31 | insight.network.should.equal(Networks.testnet);
32 | });
33 | it('can be created with a custom url', function() {
34 | var url = 'https://localhost:1234';
35 | var insight = new Insight(url);
36 | insight.url.should.equal(url);
37 | });
38 | it('can be created with a custom url and network', function() {
39 | var url = 'https://localhost:1234';
40 | var insight = new Insight(url, Networks.testnet);
41 | insight.url.should.equal(url);
42 | insight.network.should.equal(Networks.testnet);
43 | });
44 | it('defaults to defaultNetwork on a custom url', function() {
45 | var insight = new Insight('https://localhost:1234');
46 | insight.network.should.equal(Networks.defaultNetwork);
47 | });
48 | });
49 |
50 | describe('getting unspent utxos', function() {
51 | var insight = new Insight();
52 | var address = '371mZyMp4t6uVtcEr4DAAbTZyby9Lvia72';
53 | beforeEach(function() {
54 | insight.requestPost = sinon.stub();
55 | insight.requestPost.onFirstCall().callsArgWith(2, null, {
56 | statusCode: 200
57 | });
58 | });
59 | it('can receive an address', function(callback) {
60 | insight.getUtxos(new Address(address), callback);
61 | });
62 | it('can receive a address as a string', function(callback) {
63 | insight.getUtxos(address, callback);
64 | });
65 | it('can receive an array of addresses', function(callback) {
66 | insight.getUtxos([address, new Address(address)], callback);
67 | });
68 | it('errors if server is not available', function(callback) {
69 | insight.requestPost.onFirstCall().callsArgWith(2, 'Unable to connect');
70 | insight.getUtxos(address, function(error) {
71 | expect(error).to.equal('Unable to connect');
72 | callback();
73 | });
74 | });
75 | it('errors if server returns errorcode', function(callback) {
76 | insight.requestPost.onFirstCall().callsArgWith(2, null, {
77 | statusCode: 400
78 | });
79 | insight.getUtxos(address, function(error) {
80 | expect(error).to.deep.equal({
81 | statusCode: 400
82 | });
83 | callback();
84 | });
85 | });
86 | it('errors if server returns invalid data', function(callback) {
87 | var invalidUtxo = {
88 | address: '2MvQs7cJe49fbukkTLwhSYnV3hSXe6Bu8tb',
89 | txid: '7d1eea0c7bed061a6ce1b49d57ef385621766e765bc3ed48bde04d816a4c3ea8',
90 | vout: 1,
91 | ts: 1428103500,
92 | amount: 0.000198,
93 | confirmations: 6,
94 | confirmationsFromCache: true
95 | };
96 | insight.requestPost.onFirstCall().callsArgWith(2, null, {
97 | statusCode: 200
98 | }, [invalidUtxo]);
99 | insight.getUtxos(address, function(error, unspent) {
100 | expect(error).to.exist;
101 | expect(error.name).to.equal('bitcore.ErrorInvalidArgument');
102 | expect(error.toString()).to.contain('scriptPubKey');
103 | callback();
104 | });
105 | });
106 | });
107 |
108 | describe('broadcasting a transaction', function() {
109 | var insight = new Insight();
110 | beforeEach(function() {
111 | insight.requestPost = sinon.stub();
112 | insight.requestPost.onFirstCall().callsArgWith(2, null, {
113 | statusCode: 200
114 | });
115 | });
116 | it('accepts a raw transaction', function(callback) {
117 | insight.broadcast(rawTx, callback);
118 | });
119 | it('accepts a transaction model', function(callback) {
120 | var tx = new Transaction()
121 | .from({
122 | "txid": "e42447187db5a29d6db161661e4bc66d61c3e499690fe5ea47f87b79ca573986",
123 | "vout": 1,
124 | "address": "mgBCJAsvzgT2qNNeXsoECg2uPKrUsZ76up",
125 | "scriptPubKey": "76a914073b7eae2823efa349e3b9155b8a735526463a0f88ac",
126 | "amount": 0.01080000
127 | })
128 | .to("mn9new5vPYWuVN5m3gUBujfKh1uPQvR9mf", 500000)
129 | .change("mw5ctwgEaNRbxkM4JhXH3rp5AyGvTWDZCD")
130 | .sign("cSQUuwwJBAg6tYQhzqqLWW115D1s5KFZDyhCF2ffrnukZxMK6rNZ");
131 | insight.broadcast(tx, callback);
132 | });
133 | it('errors if server is not available', function(callback) {
134 | insight.requestPost.onFirstCall().callsArgWith(2, 'Unable to connect');
135 | insight.broadcast(rawTx, function(error) {
136 | expect(error).to.equal('Unable to connect');
137 | callback();
138 | });
139 | });
140 | it('errors if server returns errorcode', function(callback) {
141 | insight.requestPost.onFirstCall().callsArgWith(2, null, {
142 | statusCode: 400
143 | }, 'error');
144 | insight.broadcast(rawTx, function(error) {
145 | expect(error).to.equal('error');
146 | callback();
147 | });
148 | });
149 | });
150 | describe('requestPost', function() {
151 | var insight = new Insight();
152 | insight.request = sinon.stub();
153 | insight.request.onFirstCall().callsArgWith(1);
154 | it('works', function(cb) {
155 | insight.requestPost('some/path', {}, cb);
156 | });
157 | });
158 |
159 | describe('get information about an address', function() {
160 | var insight = new Insight();
161 | var data = require('./models/sampleAddressFromInsight.json');
162 | beforeEach(function() {
163 | insight.requestGet = sinon.stub();
164 | insight.requestGet.onFirstCall().callsArgWith(1, null, {
165 | statusCode: 200
166 | }, JSON.stringify(data));
167 | });
168 | it('makes the request as expected', function(cb) {
169 | insight.address('mmvP3mTe53qxHdPqXEvdu8WdC7GfQ2vmx5', function(err, addressInfo) {
170 | (addressInfo instanceof AddressInfo).should.equal(true);
171 | cb();
172 | });
173 | });
174 | it('calls with error on parse error', function(cb) {
175 | insight.requestGet.onFirstCall().callsArgWith(1, null, {
176 | statusCode: 200
177 | }, 'malformed json');
178 | insight.address('mmvP3mTe53qxHdPqXEvdu8WdC7GfQ2vmx5', function(err) {
179 | should.exist(err);
180 | err.toString().should.contain('SyntaxError');
181 | cb();
182 | });
183 | });
184 | });
185 | });
186 |
187 | var rawTx = '01000000015884e5db9de218238671572340b207ee85b628074e7e467096c267266baf77a4000000006a473044022013fa3089327b50263029265572ae1b022a91d10ac80eb4f32f291c914533670b02200d8a5ed5f62634a7e1a0dc9188a3cc460a986267ae4d58faf50c79105431327501210223078d2942df62c45621d209fab84ea9a7a23346201b7727b9b45a29c4e76f5effffffff0150690f00000000001976a9147821c0a3768aa9d1a37e16cf76002aef5373f1a888ac00000000';
188 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --recursive
2 | --timeout 5000
3 |
--------------------------------------------------------------------------------
/test/models/addressinfo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var should = require('chai').should();
4 |
5 | var explorers = require('../../');
6 | var AddressInfo = explorers.models.AddressInfo;
7 |
8 | describe('AddressInfo', function() {
9 |
10 | describe('instantiation', function() {
11 |
12 | var data = require('./sampleAddressFromInsight.json');
13 | var addressInfo = AddressInfo.fromInsight(data);
14 |
15 |
16 | it('works with both strings and objects', function() {
17 | AddressInfo.fromInsight(JSON.stringify(data)).should.deep.equal(addressInfo);
18 | });
19 |
20 | it('parses correctly a sample response on Insight for address mmvP3mTe53qxHdPqXEvdu8WdC7GfQ2vmx5', function() {
21 | should.exist(addressInfo);
22 | addressInfo.address.toString().should.equal('mmvP3mTe53qxHdPqXEvdu8WdC7GfQ2vmx5');
23 | addressInfo.balance.should.equal(552461906422);
24 | addressInfo.totalSent.should.equal(663303268631);
25 | addressInfo.totalReceived.should.equal(1215765175053);
26 | addressInfo.unconfirmedBalance.should.equal(100000000000);
27 | addressInfo.transactionIds.length.should.equal(444);
28 | });
29 |
30 | it('returns the same instance if an AddressInfo is provided', function() {
31 | (new AddressInfo(addressInfo)).should.equal(addressInfo);
32 | });
33 |
34 | it('can be instantiated without new', function() {
35 | (AddressInfo(addressInfo)).should.equal(addressInfo);
36 | });
37 |
38 | });
39 |
40 | });
41 |
--------------------------------------------------------------------------------
/test/models/sampleAddressFromInsight.json:
--------------------------------------------------------------------------------
1 | {"addrStr":"mmvP3mTe53qxHdPqXEvdu8WdC7GfQ2vmx5","balance":5524.61906422,"balanceSat":552461906422,"totalReceived":12157.65175053,"totalReceivedSat":1215765175053,"totalSent":6633.03268631,"totalSentSat":663303268631,"unconfirmedBalance":1000.00000000,"unconfirmedBalanceSat":100000000000,"unconfirmedTxApperances":0,"txApperances":444,"transactions":["511db530da494a1b7f39955d4a486416e746b643977e0bc17738de9c50b63996","c6b5368c5a256141894972fbd02377b3894aa0df7c35fab5e0eca90de064fdc1","158e1f9c3f8ec44e88052cadef74e8eb99fbad5697d0b005ba48c933f7d96816","7f6191c0f4e3040901ef0d5d6e76af4f16423061ca1347524c86205e35d904d9","c589be71a5da50783968b7c41cd1f12fcc92785654efb67a0c51285caad069da","2c2e20f976b98a0ca76c57eca3653699b60c1bd9503cc9cc2fb755164a679a26","59bc81733ff0eaf2b106a70a655e22d2cdeff80ada27b937693993bf0c22e9ea","7da38b66fb5e8582c8be85abecfd744a6de89e738dd5f3aaa0270b218ec424eb","393d51119cdfbf0a308c0bbde2d4c63546c0961022bad1503c4bbaed0638c837","4518868741817ae6757fd98de27693b51fad100e89e5206b9bbf798aeebb804c","c58bce14de1e3016504babd8bbe8175207d75074134a2548a71743fa3e56c58d","6e69ec4a97515a8fd424f123a5fc1fdfd3c3adcd741292cbc09c09a2cc433bea","0e15f2498362050e5ceb6157d0fbf820fdcaf936e447207d433ee7701d7b99c2","a3789e113041db907a1217ddb5c3aaf0eff905cc3d913e68d977e1ab4d19acea","80b460922faf0ad1e8b8a55533654c9a9f3039bfff0fff2bcf8536b8adf95939","16e5d7c5edcc56d0c4fde9795c2476c691c631a8f2828426c23c8796de9a5982","781a62a311587441fb41a975a711d40bd9187f0f89d183b50551e8b55cc51c22","7d821653895b8832722351e688a63b23513002dbaa34ae341571a2991fb18841","209f97873265652b83922921148cad92d7e048c6822e4864e984753e04181470","156c417794257f19b2e4e1edd71633fe8251fd6e60ec71f13af1900153a45728","887a9a8b5e67f8a2e1ec5e5f481d9222e7b203bdef45298c55c8ec26b3e373c2","fea3e182aa9aaf5b4222f2f046ed6066f07a6eed81a297f047aab13a62dc6110","c1301463cc1f07ed6289ae3b569fe0a7911167a5b914beddf829a9485a949d4a","3b32a082f0690ebfcae31628987559456bd316da5b62510992c0eadc1c4a7a80","1ef1d895fb1f9258cc854559a8690ee4bcd04038bc68cb8b4cd1e6e4bd7cd586","74a4646c0156b23c9da9e1a3f4f48c51b1ba1d8d033d1ef9f56fdb4634ea89dd","712e095b880341ea734528671483f9b533d49f15e66d79245b47389c1ab2fc2e","84dcb4e893c738b174c80a7723a2f49da8985031a17c613915d4425ad015e470","58f65e176b9ae982aa3700fcfd775cdefa40f64c7eb29f17251c9bc1a0a109a1","c17555c5354418f38db2fabcf5c9da91e0ac47e8a489ed8b37e0bb58d8546ad7","b19425ff60106c9a3a52ed12f993d78bcc5d8bb173c23129e1209aac18a50934","4bccb4f2c004c18ff43a52a0b5b6603fe798d07cb64327586ab64400c3809fe7","9986c0599bb904dcaaffa20b66021de71948d876b90abe07635974acb802d329","6ec9045265beb87f39aad9f6ad59f61e33e1a338bf5dad5b88326f86849ee332","52656148090873f8d60e2c32926439f732fe853d8a6fdf00f4b51802c9eea738","e514c933528529c655223c807c56a2b95e6654b4743289ee786ee8f52f740279","6848a322c576a0241549429e08c85206c13be6ecc676f7b1b19fb104061482e6","454b459520922620b3a8efc3838666e15816127f46a9f67c23569a58a12ab783","1b430f3b78ee3b08c0d39301e7d66c66b503fabdaae852d599707e156da44d41","838a5469b432b795522c35d5d85c0cb8e393bc5c8c91d3487186f1651d175394","09027a1690fc703d76d1ce828e35ba0da0a6cc09dd9fb284f43ecd2af2c5fb59","655a015ff507298d7045e857cdfc82c5b0ed28bd2ea732c76f76dc0886c940d2","4fdd75f81adde3d522fcbb977fc6bb9dedd9665afc77df2b4b1d98aeabf7bfa0","fa2ec6a72ffb8afe3188245b8eedd3a44c5bbe78153226c263bcfde4a71e0904","8efe0ab4111a199955daa36508bbe73b4867458c4f091951e5d52eba26d9a755","bf40b31784a51fa618b55eedbfa6f02bf79240eb49604fb3982c0d53e8db0695","39593b054bbf94bd39638c72a80b75a11425ea3c40cf687940553b1f35b340ac","08ab81e1ed4c0e3aeb6cc86a67852f99ca11963dcdffb301a98c526a8a25f99f","a4112d6a583d61420662baca858478b3d51fcfe15fac557ac06f7baabb83d26b","5ba00244310bd137ab2bd2184a4baf74daf436383d4e67523bea0cabaf94bed2","97ceb1ed50a4bf7281cd2b9c5dbfc8a9267ba709a30f52061b8fd6e8fe573e99","bcc05b694e52466f6baf171cdf4a106be2a175c33fe969d816386d59eb5623be","030d6461bcc321e20e478fa9ef3517fb5cccf2072b9e694e8c8bf53c559c9fc7","a3e94f98c08ed5599d263d64ce5b8a30b1fc65250699f0dc06720812ec9e6b0a","21b4b18968d890bd74ea37fc94c3e4ed74a84992b2bcc3199b201caa827fc2da","67e7d45111e285555b4b1be78d89b81f407b38099bfb7dfdc0797eeb2a57463f","2feac84f773a0814f396d8f4bb7643bb32cc051c659aca9b09c34f5729aeda67","768e16d90f493e9fcab8894694b41f6b552d951fdbdaa27c37ea6c2a9d8e1a75","0329b651c7ba07ac5ef99f7ff310695fe601519a49f18aec2a099b0d627e5a36","d3eae477f6f21eb968ec254ed8d6b85060c1ae3dd07a7e75f00a603217d65a0d","4264872d8e71b4f46c9edb38a1188731c26dc3deb7e9fc4e95811e09d9fbac58","d7b9d4bf9722913ccde3966a9fdc56fffb7a501744ab861ddd4ca1e063f21970","b11b5333a20c99e7a2b660338c54d6a994b6bdcea3396336df77e036846e281c","da2d54ce5fdfa9cd5c7fd9f712fd774655088e244e4f0ffa2f80207eacc089b0","bdcc17ea62e3136283fb6f94f78b7389b19a497ed04252ec5d161f7a0ffe50e8","1e3320baffca554af79b6441bd1cd48b1d4c8fc9eab62e32cb453c85dd09f3f3","3a40bc19c5057030ca577bf6f46c98f10e3b18c6cf23493d811095f5c6105a5e","c18b8739e9469cbade06872e8c186468a843e89d28ff9134073c0af50dfcc948","3b3d833439a60ac64df917d2072480195cf21606b5cd9890c150327feb0c3c82","6d71295f60ad13203e49d2b1caa4af840e2b0a03f3b7355981ae6dd2a6f29b46","e2344a35c7cacec06a90d803b97b4f7c180b99a0e77cdb310971b2e5f054a30f","61d4467664a7c949fa3cc6c4c253c4c2ba7b1d0cea2fdb26915090ac437d13b7","050cc567019e4f1dea1d2acfacec8a821bdaaf4944e34310634bc5d40513be12","3aa9be20e8349ef78eb028c42580f3cfdf2cd5ef79b2ed93dd6e3394e0c2ff3d","4760900171bcc47e836e2bac3a756ac207c04591c806d3b2c451edfc62881eb0","2d102da423cc60326082d0baff82fbead76ddea4b282109bdee0ad698b1a99d5","b9b682cce12b8e019eea68238bd150e93012c2472c1596322f821a0952c9fa2f","9ce8c197ebee2913959a77d8dea48ed2f4bdf2bac00b348648a806ebe2e2fb90","f24fd3f18b3576d5240a171b61c09a5682eda1ab1a678501e0f1654725634cb6","6905eaf50cf3f2bed6e31bb4e7b4f3bfa594a541b45aa333f540d78b2461c1f2","7bda07c1052684d9d63c85c890a8e68cf957c707e1769c30974a3b910d5cb753","e9f06ac3ee860ac3e62c477eba59c87bf2ed4ffc996d78936d18b60091b63d75","5ded326ec03b29b538d1cf35093189011430cd1be5ae85c3a0242e4dc7ee0d37","3df1a50e2e5d8525f04bd21a66bad824364a975449fa24fd5c2537d0f713919b","5f4dfbe7e62b885e18c1fb17e924d10d8aa5ac64fe485d0d900ff751e6f67993","6d48324fba090bcdd757b323f0c35ae40870568e02e57d968d06d6421717cab7","e8d00d8cc744381233dbc95e2d657345084dfb6df785b81285183f4c89b678d4","186c598548232f5ff57b41fd178288935b08ccbcb8f2720e809791415123d4ba","7a748364255c5b64979d9d3da35ea0fbef0114e0d7f96fccd5bea76f6d19f06b","d6e077324201a5616781c02359fdc3fc95f6badfddaec3ec5b457d5a31d660ae","d85f5265618fb694c3ea3ca6f73eba93df8a644bc1c7286cec2fbc2fbf7d895e","19b8383f48e2a4e0f33a704468b4ab2d8d1dde8966f9d2f6a73777a175cc6b01","8044b88c8e80ac9bbf5c8363364ad570949a816598374676e9fbdcc02827bfe2","bb91b988f36c0ca29406d65c4833d42b7a12d0e383ad0f3915a95727e5ace4db","daf3aa58119a6f3eaa9a16e0b9bf45dcad10dc8ff05d22aeeeecc38ee3d77748","77cc88b79f2772db652cc311b9558c1ef03a10dd9168081d9a31f1d18f9a26a9","5bc4d7dc7e9f25ee97bb029733829c69fa8f9c7310c443c7e9c1922ceb037eea","ee899a182bbb75e98ef14d83489e631dd66a8c5059dc8255692dd8ca9efba01f","560ff7a7aa98f0d046abf44a1474d04dd293eec5a9b3f0c12a586c6e0f29a36e","bc27f31caae86750b126d9b09e969362b85b7c15f41421387d682064544bf7e7","18769e9064c78f6c28d1e3e540971b59f667470185f8d9904425e4a3da2f57f4","5e4569458b11b0df6468306333b824e8fb339c4559e42f0125a9b38762494293","27fed98ada935be24a9f37dcc86cba677b50091aebf33a00fc3cebef44b5acbc","b48a2d7f8c9172170afec67688458d1c497c236199c4671083db6e3939f0198a","d61c1ef4bc15f2e9c5f8d931c0c07b5e2a90d2f78957e1f6e75e4d15308e7c1f","7829d1fd94cb1916e59cf53ead6075a3daf7a6589565b4cbaf41a426622a20ae","d5604b3547582e2f912ef00b40267ed7e018de2b2a7f343d63d7188206910e87","d56c22950ad2924f404b5b0baa6e49b0df1aaf09d1947842aed9d0178958eb9d","86d40716fc3ba3dce3d67cdbf8fc771963aae9b395ec7c7b5d6c9ec72a398cbb","4e54343c5f4a8515ff97ea072d331cd89dedc9c3a2c1be647e59cd7bb12823a3","d5176771a7394ad59c815aee606125a14110aab0c2b0582b13abc04e82748248","2b6a70d33b7098107ed7bf524c38e76cc7011f32b55e0cb7b4ba8114cc67bd68","d9ca9710fcc3fe057c30e01fff4e6513839b471104ace6ed4c2f552747ff58c9","0426eed2e46251ff060e1935340e99ef62fbd1063b4f79593a9cdbd5ce209757","23b8d0580ddce122d29699402aabe9783e3ff8ec024d3eed7041273e87dc7a03","0964bedc33c3ccfc3dee84688097c3e6b16acc0610d2059a35c85b8e453e2ab9","78900260fd01c5d1518886ba0d2c1cc0c265b00f8c6a92801ae15893e764ed6f","a0dc03a870e589ea51e3d3a8aed0d34f4f1ae6844acad26dae48fe523b26e764","ddb2297f7da0e7cccee5b0d47c10727cfe0ec8a1dd36d7136e85b135d30c4215","3fe86abce7a9fb7139e9509d88a4bb02775ae25e0c96ed3c846bce0e5e107f30","0ba78ada77352628708f25898f5151a31ad53927f5552e71acc301a53079ec67","be52ff5a745c7b407f937bce8fc68beda307317f59f4c1d188ec523b8ddfad37","bfa7993a7c225b9d067cad7270060c9380d52a9a1995630bdcbf196407cc4f95","68436a1394645f79d95f1355a7d6cb532f844a32875b6d89a20d4d6c12f20f67","d108b7a37a1924121923179995f8f5d636b8656ad417d956f467008da8d41c86","a84b4cfa9705f72d0cb7e88381b2002a7026fd43d70decbf190bf9690317c2fa","fa696de1582b28db9cd536d66aa722ec5173ce7dd7993479479ff66fdea4e90c","9363bca9b0283dd70a95977fff1aeca6bb9f1ccbccf3aa1d6240fbba1faaac01","9dc8fa80834ba2de353509ee3770757b43c199b5ccba8eee6a7041e51b1bb0c7","ded4cbc9c52fd5599b6a93f89a79cde9aeb5a7f8f56732bb67ae9554325b3666","e9f4ff5e9b993632422129a72af51ec4698508639830af96fbeea0aec2482aaf","a04bf5ba5e42d537354fa8d059acdabf16372fb36ec8aeae7d1252a8214db4c7","2cd6a1cb26880276fbc9851396f1bd8081cb2b9107ff6921e8fd65ed2df3df79","a1481de9aba6f61a91da0504ecc3a1f3c18c8ba3f8e98bef034679f741a4aeeb","bdfa4e234acf755ee90ff20b4d918cd361b8867e7310107baf740c6c744c82ff","8bea41f573bccb7b648bc0b1bbfeba8a96da05b1d819ff4a33d39fbcd334ecfd","4efe00ba9919f42f16dc11cd2729161eaa064d96f42f143faabbf14e62554d89","ac2dfc259902fe430a79b84b51d32aa0bc7933e10695963fafde8d2da2711302","d0b7e087040f67ef9bd9f21ccf53d1b5410400351d949cabf127caf28a6e7add","5ee18638245ee139f1f471ec2007f987c08273d0dde2e3f0f4c82fdc4c8d732d","a9f40fbaecd2b28a05405e28b95566d7b3bd8ac38a2853debd72517f2994c6fc","d9e0fca6ca6e8bc1fd4a8021075314cf61919d4faf0f9723a1f17f8eac20c6a1","0070fced3b9089a1a22d966083e205287e782341c78a30d97408549efd383274","f6d6932689abd29fd13f35544c45d738e1b94b71e09de250c35ea16296fc42ca","91224a219196a3f6e6f40ad2137b13fe54109e57aaed7527ea34aa903e6b8313","c684bd97844a44b382bcc655e8c2459fc97de4bf34645bd6dcf6764478338805","a2a2ffa7e89197ecdff0c4dbe7bfe92884d136549f0312e36122fdf19c22aece","23c40a3744ebb4f4fb96ee20bae680af3816fceeb13816a0cc9bb812e801ee02","daf03d666047ca0b5340b4a0027f8562b7c5bac87dca3727093b5393176a541a","1e8ffd8463872586d2035846d51947f71ebed45c6d2733bcb9a1b58c685b9b5c","1c840de063b0f290931e3545cf3501da2ee951d142cf59344d67d57f34c345e4","39df68a9afcaf1a190d77130fb5d7bb71fb1c72de3ba6f72ef0268e3b49ceee5","4123255b7678e37c168b9e929927760bc5d9363b0c78ec61a7b4a78b2a07adab","fd057d32da78086b1d355996d4c8bc4aa94cda91521fbebfab5e639ba6d1c509","7b007aeace2299d27b6bb6c24d0a8040d6a87e4c2601216c34d226462b75f915","7302b83b0413f2c7082dd2d450c8aa366fd0be35a00aa77ab0168281999ae049","c2a1a48653108b32bfb46d7c750840e88ac6465bc33b7500bdbc284988e66c1a","cb3760529c2684c32047a2fddf0e2534c9241e5d72011aac4a8982e0c7b46df3","a41dade9c045cdc9ce8b3a4feb16f5831cad0a8dec5c737b862f8cdfe319ce29","f6e80d4fd1a2377406856c67d0cee5ac7e5120993ff97e617ca9aac33b4c6b1e","f030cd713355c36b3c646175feb789531f051972c437d8c0e567f02440aa92c3","0d2c778ed9976b52792c941cac126bda37d3b1453082022d5e36ac401be3b249","dbfecb57f1effc5e29198e2c3bdba8552f7b9486867961f9c9b0167b0b3ae1d1","f5a1dec0a2687efd54ee1e79bfd5d053f5b5d5de8a220a038e381b3251469cec","871eb3b20a55ad43b85ba06777fa0181b02f036f78dd2b5a02e9aa0ed55aa821","f1fdeb7ced28f697c97b6a3ed7cc1946e1fc5e062ad8c17d05c88b1767b91b2a","51b07c87b5fe1fd8185cf30eb04a48338cc0a4698a3b2b3ce6be8a0f6eb6ecc3","08f9290c7737851c5ad113def89d1469b627b5a9c1ab7f85451e139bfdebf412","7f5f2033f87821f7b4aa00b69559533ec95bb3c4d74761d7495b3658d3e3899f","ea4481e236b0bd6d207330a3efbbc69f9ea17e2601cf1efcad768e58c65653e5","c970c66502d45d8121b8b522b9f750fcb99ca1d912df835b01e44c92b0eaabab","0f150febc1c6b89514be20c3ecd84226f0e380510d12dcec6702cc5c1a700da2","d31e6af79198439caaffecb4b84e00d9db35848e76551b63efbdac1a59785361","151c88abe7820ce85a1bbe4a519ad575cdea6e82243397e2059556d2912838d1","22d19b585943a1450ee11b85c838638ba29807012096d5e6a6573370fd514c95","fdcfc714e48594cc901bf0586ff4546ba976c1bd3c183b97d0be05c95e477dcf","29c22a3169502e76b6e02ca3260e3e2f33820ee750e6fd37203769beb96feded","3a4af7755d3061ecced2f3707c2623534104f08aa73a52ca243d7ddecf5fe86d","0a2b70eae5365c1cf4d53da64d2097b8dc0d5b9a2f4a02fdcde2c55fa416a5c5","12bde9db97154ae08eb8282c8a4359c45665877af292d98a2f4270272479f95e","4308929605272056beac03f9ad2d3c7b2f8d34fc17c6fca440e57db011b1a357","b2674e52cbaddfd2a400d444f99a3f82f0976f22ae2069a363076c81f9ceb1ae","cdc5db0505cd9f51a4a36cf8c93445d80ef5ea2cfc9d8bca103881721427ec79","673c71f9568769f4e62badf7e5a5a963133185442ca20bb799c5c990dbc272dc","18319610b4843b59f121d9b307b31d37ad817922ca1cf66ceb63cbb198a2731e","b1588b9b429df44a0e36b72948213c16c229e40e7f6dede6a68646be7b528791","c67e260ac445b34092aeddbe5d87d0d6304765d1083a4d927bb80115954c267a","310288116eb5255f892d027b5b28d3fe5b25ca6bc7311e94605f6a56463edb08","e935918033ef8972fc6f109cd8c84ef3b6dcd4b1d2aea04b70e4d8dbdd99ea46","cb0d55c37acc57f759255193673e13858b5ab3d8fdfa7ee8b25f9964bdaa11e3","732cb12893240f7f71b8bb8f4171540e53eff9c9c35271d00032dd037051673c","7bc26c1f3b4ab5ca57677593d28d13bff468a658f4d5efc379c1612554cf668e","503444162c119d646fb1eb24fca3f5330bb1ab00dda6147b1c0c7a0155b3a0e6","4a4b5c8d464a77814ed35a37e2a28e821d467a803761427c057f67823309b725","79fc5fab06471384776847afd1dadaadbe74275c9344361a0f8728965ecc6ce0","c0014eee416352a99d7ee6fe0c3832b10a1089a69c51c103d6fb0a16eb4e2754","f8c9207f952045d7377d844bf738563543a2cc2c4b2b7c9d6d605ef4825d90a3","fd3ef3465b20bad29bac5f065534b562587a837182341ce60167533a1aa2774b","aab89c9074cab80908f6ad693db65db7727b7939723a0c0d2d18019d9ebd9452","8821b504fef5fab3f6ab32cafbb4c13fa76675ed99bb05e95f3521b4667b69de","3e5514320aa8131d34d4d141919ce519af7d6563b587c89e9b7dba4241546a8f","dbd4265eec3ac8b1bc945854daafe0bbcfbe16ce00d1ef637c9391a280a8d917","f2c293980ae5b2b8f0252dcb73754bc954db5acd34ac647d58d8b50f98244da7","6edd0240a0cdeced5285ec3eb220da2d3d90090ca1e48ad535cf89bf8ab70be5","4c0f8137881d49aa24104c5ac03fea0578dfdec610bee91ec0d50653adfb8aa6","3f6e175bd976d538bfb159349d51af462c44191ea15b06a6001f1ff3c48976c9","7dfcfa51839b2816982682ffe0b99d541de78275dbd84c2f88684d863d9649a4","1574a24920c6a59e0a187bfd9b4c2b628225a89972a201168ba86191a74eb33c","91800d80bb4c69b238c9bfd94eb5155ab821e6b25cae5c79903d12853bbb4ed5","5c79f2e6761f06f7d30f2e6a5d4309eea994a123045426561a25fc89096b5ac1","340bc6830e30e23e42acf7f5e9758f9f0756200f7e36b0cfe8970c9c94c7689f","05e8ddf8df855e605d5f795b5b26274ad1c11f8eb2ef9072d4e9bebd7afcc108","650f8e44b8b32204a59ab835bec1589f56249e675bf7f1158b92aeefa63b73e4","50c725d734ab1407fc8fb8f4c7d74bfef4375aaa6835b6b32fe5c808e5b06143","b4e0f56c70b16a127b7c1c37180b269cd8ccf58fa48f23bbd18cf151fa4374f5","618464d905687e06d7c02c2a45f81c2114bd8670cb4fbc365a98834637a62d8f","3a4fed5de8de8c31c0d7a4cf053ace752e1ee3b5dd350fffee98426712b51351","e45ecc95854bbe74816eb8e1fa876d0b351086ec2d184f93371f5212bf846d7a","9dc9f3596477bfe6aab853b478c2b9897a1a6d3c7c276ef7a3c6606e5179e355","1e8a3cd1371ae9908236e9ad527054cfa7d9942162d94d451aead27c9cbea0db","888d61ba48d86e20f9804cc169f8061299d28fddae1e7be45fb2dcb347fb96fe","5543a13fcc09b7111e5e76250434a50181f58a1ef71013b6cafa0ff3aff1e33b","4a045d398d13b54def3ac2ad120ebbcc89f79a9f513eca026380b4787c792eec","20092ea970797f057794c961c95326087dfd6762ebffd4f326f513c46c9e697c","757aa100cab6ba8732a2571c4c4ae9c7b2b8140cd2132f733f1578558a7fe9e2","ba78226e1c5a3616a125911a055cc9105b048f306afaed7e444a22ab18ff4ac9","099a829a856562bf7c0ce40503c8173b9c1488dd48f91a8835fbe9f66ee661a2","b9b17aa05934aa7c5123d92285edd189d5192c6a643a59d959447431e8db6eaf","206c6565310a5275a3e173cdff1679b051d84e8bbf5236c16526113a93378c02","ccf41ce1c24d08f3a4dcbd58cda12fadeb81b1b512a7be666f2d996228964edb","28d411de336e49c355e6d112ca118bede298e04092389bfcafe71d68b31c1d5f","38ac349b443e4d3df8edb6378b0137743648d7c6f8f4c8a525989e31f1d29e7a","594ffd03673adc4442881797eeb2ca25a699bf4994bd061e18b61622b0b7e708","45e86c61ec33aab1a4ac59e5de2a81995dcf412bd9342192c14e5cc6e9caf636","622903b4a5234cf65cc6a648685160efbc3d9e2a9534d86a9f3a2c7270a548fb","29b9b39ad99def73d6cdb3cd542e68c0e811149e0d771a85e45e2df953fcf049","b9cd8e96d61ff9575a022525ae205decd6558cb25ca3e738ccaa4d8fea7fd495","e3d84021904bfb67981da6d4cc79b58ba34cd46da2953ecb242a6d4559b0aef7","6e6faeff78f6629b18c4bc3e26eb1a32439e8e78013afe0c27f34c9db4d5937c","b028458b22ac975e62e47754fd6845d479d427cd7aff916ba258bf35fcd7552c","6930d3a40fc029a80a184cbadb2077618357089c9ad393e7c8476d10eaedaddd","7fb6d6da7f10d94dda97d712871ee5e23738b3aedcc695651a1e86b0cd605af2","ad78b1f427776358394cec415b4a8b862da051c4bc191d96843b4b3c4dc5f17d","c85948a8255d5b6f93209ec9b6601b62850494928b60bd38c257aa1114b7f45e","6db8b0e0129182a96020f569e6b7a707fb5874d6e01a9c0696d52e44144b81ed","1eb7ee069069634023c1580d86db87c6a36511a4599ac1894a2c8446d2a22038","cd65807d991b3e4392676cbf645077a6d5915ea4934c0acdf8d8502074839245","e724bc5c0785c70efd901e78336a9936cc07b734c68a4538d3dc8324e661ce4c","0d5707aaa5b4f38973ee9f098be37eca84ea97cc361bf1245b7ce0126cc0cdc4","37cf54c3ee477491f696a80184ee5133a0502446ccfeb03f8a5a02d1a723b7d1","3093e89aaf15192923af7dbe407ff8010649434e7ce57ec16ffed79211c889db","66dd87f91e6d44303a929f5e62d4068f30b520b891c07079f05cb01ce3c97589","05c1aa784ddac307467dc67b53c078a2e5d5d2de791e73bb44bd041de50aa924","1832f582eab4e0c39481e47ade55d6744ce87cbbed27cc8f72c0e9923c46781f","61b4c6ad64b354fa0594cabd61718e0d1f00678c135a179fb35dfa6759fec958","e4b33819950c52305e55684701b93219b1ea5e87e2111c7c32cb6e116e685d12","0427623c15809c2359d4c355cd7484a74800f0fb30ed6b5fb9e929bd7565c0f8","0f0f71b10b5b6717d87c8fd9685f7460fecadaedce00d7180e2130e1aab456db","c319612c0e2b08f653fc51f4348e4faba2080ceff6b3df123b0a554c78f49bf3","818230d2e0f209b4f218811334eebe595073cf751f2a396decdf5149b47cb3b8","ffeb9526fd4771e737e4c3412b14516b18f6a453d5ecbdc66d9de2d912de7e46","ca6fedfe822cefc13f142fbbb450130552f78ae04a7eb41cddc4b54e9c3b1574","a168ed7764ce58d7bf65fa74ae97b34f4914556cd9002e1a098822825b518bd7","a6766fc5dca8b6e0a7201f3a4c3c155fce71923c00b0bd868a6501e604f09e48","843f69324f458d586480c46b70ff2f38c3758b68910c582c484823ed021114b3","6a93136ef13666f5627630ae9122bf67cca41e6576cf6a5c99bec7b44dfb2a49","30665faac3fbbe611c0ac72b10d5212760fb9f3be582c322e9c8d380a2c1aa6a","a4bde17c8df7095230896d98d44f1e1659166d40b5daacbda5aa44f1ac5d2b27","124b068027300d0bf353fe48b49d7cd9722df9919d3cd1b26d1bea7d3fce82d8","fc77a75a5ad3ec1022c7184fc1549304aa266af08a1c7e6d8d4e7140f0e67579","663861a81fac8b5866764e3c4da3d9c447329f72e0d7d15ee00c4e0a1a665e61","538eb0045873382b2e5c0cbe8c201a93951e5d6c17e7e0bdd55a3aa63b87f9a7","4317408436f801c7cbb848796e40923adb3cccacd48383ab9efb51e55f2a317d","c5011dde3168de0b40dbe448e898f80124a8118847a5a71bee9cf6400c5775b6","dd4041c7a6152cfea984474398d52df59f53a4adcf286a027d875aba412ef570","92b38548090292cd423690544077192e77910ef0b64cb5cd03101cfbf6ecbc2a","8ed4f781303123da6a8e2692f43ea35bb19c0939fd364a38500abbd1d4910db9","05396f690bc768cc83bcacb494f14b10314c916b7731fb2b5c8da78409b27d74","94af4d6dc25a309b84e9ddced689e0fd489e377173a31f33052925597bbbabd4","c7b3639032b5e4a998f2df1da82f87e9f659ca455efa421d245f4a60f6669e53","badbb25dcbcb7291e70e31cafeec58ab98271db4a0fba765f2770de1eb0a3c8b","ed8523083d02b8c9ef67fff281053139201a4515942e7ed5feabb4455802e5fd","86b094ed480bb7a2084c3b95710207ad2d0ad5143a9714ecdfefee8953a00a40","dd714c5ffe0a9e631c0f5ed0e5fdc4eab0c856372d81d45e7b195cf8bff4c834","4ef0605e64cc0c0c05d75c1348f5be923da6637fa3bea1cc0cd88baa024374a9","2833b6639ef0a533111ec0db1e768d335343bcad7b0cff10a28bcfeffd96cc1e","25682e17b29ac85d2a58b7d9284fc7729df5f31f4174de05f6264e632cef6602","70b578bb3a7460cf3a639bb763dab0d39ff57c5fc8a395f32b5eda7b7b98f41a","16a1ba6e75f649953fa505261497de889758ae172bbc877f7a4ced70a3e34b56","3d9edf909b25b15a03fe09b9295caa505216e9adf15149ad41baacb1e1d67b1b","08a2c14d10057a84de3a0ec29f6e33f5d6f14c0578fa3e56948803d3b44b880b","01fb058e181928e72ab307c151eaf1c086cef03623c0a1986c6765463646118e","0cde19c63934870456f4795307e5e329dd3ae0bab0a5610cc8694c99d5a12a9d","e83d16b29a3946af54ea005e29cf47e0205da222a680d64433de00ffbd795e0d","9f0f716b3cf8efdc3a8bec7329482d92204fff90f965b6b96362be1c00bfa8e9","bff6130ea0aa6fe0f7c5067651e629fa2405c6d5adb44454d4f45c0162697811","7db7f549ba9db050fce83088cb0b76fa11696af663f4e44e63e33401852bad28","e4656a67cacd7a594feaba72e6bcb5fcd145d1ce4dced46848f6615668d1db2f","6cf25b22a72cd8ede91458a576eab2b6d6195701dd6762f3ccb9c0eb24b88d46","4c5f138958ceee581a019536f6ba36920bb084ec2bb33de846bcc99064147caa","5bb30deae28dc12b91e1bc1cdf2fced33d9782461b2471a024c453f9f6dfb193","d4f577e5dd6fe60d112efef08cbc1b64d9d12b9b792de7060e9d965af7ddcd67","12eaf069901abc39cfcafd6283ab1f27834915162a8ea9531346e4df17befbfa","290e8fa5e3178f266abb1044325a93dede7e26ec99779cf340770cc715c34892","57d65ce5320dc617e65df7a18007ebe4e89fb7658ad6ff7f93e554480563eaf2","42526ebe256cce06d0b902babecf6809a2d7c1cfcf457db1803ea231fb583b8e","521d04e36df20cc790e7db086e84f263bc02eec5f400d913abadd27bf263a8d5","4a78406bedc346257226364602c2603667518bd567b6546adaa05684333f795a","4234f86886f50cc18b776ea46ff8f0117079ece90e8d52db75a942cb4ec93bd2","7dde5b9f6cc8525c66cb884b82b2ac3935acf4bd04348d11cac796276b305bf5","4eaea6e6af5548066a782fa35ef12a47cbe6c280542bdc75efa732e3bec3435c","db89d7c831589c67ddda87ff5f5ffaf017f42e0fd4e4ef25766b4a372e99b963","8b13a84501cb67bfc8c0815b7e1ad32677d53aaa51d48723632cc8a9e1c63637","713c121440b9602168108f593841bb2ba31aa2bf453f28d77bdaef5b3274f0d0","85948746e916f55cabe5425e3520bc6f8e2ed1d671fdeff207cc6f67ee50a9e2","7d130d65247b2aabaef2c23365355cd7766f3d69490e085e835c12b7917a2ef1","6f9b79eddcdd70a3e6e8fa9adc9f6584a45da91a4de000ad99aac5f104f2d314","f4bdfacfca13412fc8353bfbe509abdfa65726cc0e5ae5371e059a004e828870","fc670ec5ffd16164b32543e37d985289ef558de6cda29aae46ce9c64b3eaf251","6d687da47e86129a3badb5fb805a488172e25d6efffa5a0ea677c67acd07bef3","85e0533e2abcd4ac57add3eac5e2fef0bb4431cb3699fccc5f696715d2c95d0e","3f1c0817e70035dc4f90feee99df200643294e2ec0f22bb6f68f6e85886cdca9","4ba0c18f6ca3f574dca69a0f83b5b60c8bbbbc0d8a4b955cff6c09f7d8cc7f7d","f0c788025b04600d723b69d0c10129c49d64b75941850e646a6520d13311cf43","b52d76976fee481b33098e3375eb35f6b6852175d3dd2fa6ef94c101c8dbd820","c4a9a9b16d919c5fed092bf92b2e7e2fdf7f17ac40874bb5bfd627d924881038","77b4dc1cf7bd9e0e0fe23848dd69b49b19fc12cd0f6bf5b263b0d8e2abae7efa","5fb75bc529706832eb861b20f6f91217ded7c910fb5937d88a87efe535a6b978","9069287ccb9cbd33633acbc4eea195357d8427f258b0bebc11a253918ac3ce88","2a14cf150cbca7cdf407b720a922942938ecf920bae54cd89b42ddfda809e65f","7ae62fea963b74f07fca986c966fee71a55176f78129f0edc236f4c612b18203","09a41471ac6ed6afc7695676e4854c4e09c3f0a0e0a0d156a6639966432c5e5c","8bb0e9b4f54acdf4b595c3bfcb503d3399502658f3963e4e6185a9573f02ad3d","98a25f662753685e7ae32f496bf9d1f4acc1666b5dd4e9906c8c0f685da0807b","4f403376c1452dbf36a1978f5fd1d52b686db7e0d2f666d3b2b05a15bd1ba432","379b5abe4aa7ab727ccb370c1fad21f5340564a5fbaf7f97802e493779c52eb8","88d85e4a2192c118a8e66ade1a13366a82043d46b986c556a627d932a6137fdb","c14e5c25858d47f4187cdcf60ba57a525d7de5bd35deeac930d5ea10ad8369a8","98e33762674981a02499d9c8869b13e19d3600da016e51b4d09dd11099a89273","e12f226065adc2265fcd94ccb2f1d55073329f48b4d05ade176411d3f8401221","0834cdb1127b0f4fef46367ecdf926455c2492bfa19b39dc22f3c5a7627a1932","2bd782e8adf784a3fbdc160d2ae054b34730784b37dcd86b11776422d6d6d152","576f62da6cd87b79880b02da082119c2e84c40a97da928deae513f050707e1ec","7a7590fbb320f1bd6837d0fe1f07e242194358794382ba0f543483558d580c6b","d064dffa8157ed363afdb389fdf9cab200bd51936e68bae30fe6399b1eb7d6d7","8540283bde661e496c751fee620a081b3f0206647293b50d8d4322b068174acc","0bfa8bc0692c8a512d43afe7de02e25e092ec3a092b42aa7278677b4c68ffc31","f3d7695df020aff0421e6d790f160e24526b7fe05b99f51aaf23e3b876e0811c","2b8f2905dd667a82eb1cad1237d4b3bad17ee4e206bf9ad7be2cd13b6a7bd051","425022ba0507ec0abc60298830e753605e7b6da7931cc3d34ed9174eeb5bbbbc","9630a1ebffe1d8d4f6c8c30e937bca3b94c32c5cd699712b39ff2731e31474e6","13680234ccdb0579362cd6a1727b7f72d9304014a69a6b64646b6cacf7d8fe71","c4d87d63534197129cea41f1c4cb3eac0921ef2798dfaa1690e0469399694f40","ed9731b4946bed9dd17704a1864de065ff6751a1ab8074059338df833f330518","79677763b5cc8880ad04203c48661e889d02d2fc842c912a131b835e1a54f53a","10d52cb88430a370935a94f5a0a31cbc69007d0f94d61082b83703206e390457","bbff530de9b4265f17ad47c48e0998fcb2bcf6e603b4f5f2ad8185ad98123a40","f71e1ffa179ae5be523934473c2bfb89e8844db47f33f89d05d2ff62ad8be8ee","4821fab81643f924041bb7fb9615a872bb71ba983bb98c41674de5699eac0761","7a69318e53cccff133cd10f3165ae01fbf72a705e2e0998e96b653170a07c44a","fbd13d8a090ed9040eccdd2384813d43937b6e4aeaf14cb11720f4f396992400","88c7b4c940bf45e24ffd3cf99a40594ca0278294f1c518f49f1422c63f41977b","cc27076c9ba8d6104e2846e6b35121f0640d9ec337083aeb9b0e4b27bb306dd6","75cad0ea2b5ffe7b0ce0d6ef0d4a38ca20df66a95ac8d85deadecb4a0d761ba8","39886afec55cd4193e6c6752ed93c2769e2497b44c01f0a40370fa6dbb400b48","f738cd8928f8e838ff34f62d76609c79e8785d55a9d3a0e905615df18872c112","c39c3bcf275150ff3f60ab29f7ec6d0167a21695d722ef161c65a53a5336669b","e735e601b425fe122a45bf3cc3d9762be083275555ed665f51ab7f7096889eb8","c38385613855414eefefd0384e1141ef9084fa24d630b57f3939f89e02a06698","0aa75ef831ce668e9c26467e761f2bca010dbab0f35f0bd2bab7039557c93a6a","58f5505cbfa7c6e7d2d15fe65d558c890574c0d4fa567191d4357ad60f6dbfec","8b1f1baa93d29fb46f0c9ba0690d39b7c2d480679a8635d6d7cef12a87cbee02","17ce3bc58234d43711d80ad2df0c57091fc3a2e124dea9b9e0a797ed3a9393ac","b59dc130ab8178e6aed911a91333ac0abd3574e7d54abd36f4dfa30349cb05af","86df7641385c2986d93a4476ad0b5ed19e8af79c096c866f45089f19843061fe","36a711ab10d25f262b7e946aeed6e14142e1b999d42efa910311952067ef0518","60aca792c9f2feb8398ce907b8d798ab05b0b7c2fdf372cec18c5e0a85acb731","a8d7d4242d5a6e3fdcc74651d17e6ca3dd6134393b40bef8e5fcad78d15e5132","a8cdec1de97884de92d8451bb07223d34007221081584a46e68700465d4cb375","19a9f90d8ec564318828e16c92e9038b71e181fa2f975ef31fd4281f865769b4","b489bc0e51ba3a7e82753996608a02ffc78fba692e4e903d73b7aa36665d04a2","2955a4b042cb2c96423b5d6603a268b87ba27485d36fe36bcdbd3729a49d4b71","1ba9269ba1885f5b77cada8d40790c94c4264dea2a03618db4c1a58e6bb38798","16f2eddfca314c74a0243e643c0ffb9fb53fed185f82400f704d55ba3a484cfe","675a88d8f68d28ea0047eda8dd967bde1a16685520ee38f762c5c2c9e96a8f13","5907abdb3b6c1e108403575ba71d0957c365994280ea7937c75027fd647e9572","6bd49ee46dd82c244d61f82729dd92a70dcd8894f7b42982f6f2c8ec108c4cfe","0c48b81bc1389f6d546a7d6162f935fbb21f353148f5a9c0fb0cd1f3f505b6f9","29d7f7b9b05b13af08323a1e4bdcdb2b22717c73bc3423545c9d68e763594b7e","6950ade214487c96350b5ebece962d1f838e4382790e8ad5c0ab1a7cc601ba41","0a61590c7548bd4f6a0df1575b268057e5e3e295a44eaeeb1dfbd01332c585ed","7a8124547d1f981c724800841245c3be6c7fb70ee00649c4827c2171209d8a37","22482c5aa44d0c535d2a259123568cd865ee31158b83c3a4eac1dbc737edb13e","db5cdd1442b5dba68056c1310323f48ecf9b5870d63671ac2583c3bc46b8ff06","c11877520e0da3607fce62dd6c8f7801e0d367589d74e69f55c6c49cdf3e1f10","670bfc59e56a6245754e472b4bbdecd726bb590e760f164a904650dd13515db6","30e9baea243c0a50c3d8319590613b206d0b5b57da40a8ce7a86bf8539b1a77d","8171af99e86f3ec5ea7443bccefbd73d2e382f46896893d8041a391b48a5dc9c","af4c10e0c95790744b8acc4cd3b44028236768f7d2fba97c7e59c139b62f56d2","440e2112cceda1e7905d414fd43771f0df84aa13790c1d72107133a944f36fb7","a269248e9414ab1919956137807b12540967444cbace0c984a5db05180e3b280","b37654ec77b8d07fb36267da7d00ea803e69d4ae9ef7542ad370f5077132b240","8e4e6c6c2002b971168ed02513f4e8cde18862cfbc2b2671914be9b9a57f5394","096540da2eebd75e2366953afa9b28a8e152c55e5a998489f638d8db897be7f0","4836ea18a4453916cd020f3bd6e4fccfe149fe5bfe667b7ff606dfcdeef780b4","56c33ee4e6d346f08a5dc15d24e20f18a5c9afe1274be6ac68dad87de589ad09","1411f62d1f0a6b0682e12a4fe71c22c0b817f350ce8d62f3a82b3dccdfb28578","2669d2a9078781811260df12ac8c69f8f10940d1b4e7b43016141ebaa5fcd3b4","37a1058daac4a91136f670882cf1646bfed1c28d5b955ef0bb28008f0e2e9d12","b6a4e32b3a9663b1095409037ec1c0fffa4bcafec1053444ae63663d3741b3f3","4cd9b6a5ec78a0b7c856a040c973cd89c7576b82c523db2497445fef448232f3","3d2b2fdd972b36a590e0dff3a8a3cc14d1f5227fd385a311d6477449cfd8593b","36f37668b5ce0c89ac18dcca96dbb291ca60e200b992d3cd3744dfb6c948d6f7","62ac4d55f4ea4555eefe97cedd1496876a77e985f5356e42bcf475fb99a5b880","3e11645b71f527c5c95abbc7590c8d71f5f85f3e7d2af0afb4ce2c1ffce8751a","b78cdad220d7b76c36e08a036ea5014859e4d35f5a136604f6e34b5a8a902945","0eda34fae6c9ac181f06ae2e0567728e0e680387f79e2cbaf3016e6f5cced091","3368a69ebbecd9647a51ac753a18db8119da8320343d4acf06b357c9838c6e13","6bdc9e53acf4a5d689074bbbe2b72708ed18161ce5b55c99db96edcbc0a27fa8","d7165979b231fb146a7d4f71f02cc528ef8e2dbc1936c50758e28d2988b711f9","297ca4943d35c9a82c0cf236993bd1f91e4edd6164e008373d80112c62ce325b","86834ebd73e7a79cc9549e775cf3691660d0578cfc498e8f901eb75bddf92c11","e321f4fddb107a3f853294e0ca14888c150e42470f069c8fb450d6d5ccf07bf8","c318ebdbbd6c4cb2e859fe5acda0f829d977f87306dafdd4f1b89b2de1f1a278","5257a2ac4a332586c836dd40fc97a4cc3376b18409935cf9640a981fd35e8b90","b12f039096a1db0456a8908e313c7fe0102f5232811624f06786fc4bc304bebf","d593fd84799eb024eb57d51eaf9a72a75e95cdd1084ea452946c78ca39acb875","91fe844b16647904bb079c11016c225bfb53d19d3dd23d6d89ba16c3935aecdf","cb271059b186c7e21e721af4edf9668378d46ce45ff75e663409ce781826ff98","a5ad19606ef9e538cc172aeb27219d1e492c84edf8426ef0469ac4a5961a34cb","66945be17108a0b7d55cc6e8f2423a26bac927e683e524a3144dcab419290f79","b5e6cb0cd17526a394343b1a2007e199d6d9ed0e3b37612abd8ed52b36a6fb23","73a6d2b56bba58dabb86fb6be5358c52be178028b7dc592110a44f2a20b3eaea","84792f135b293cf4056ec8fbc2ff9e10aaed8468fe0c8fd5ec8861d886011501","ef4daf92f7aa39500755abc41b6c904af891e77b038e852af6d69087880eb31e","5286e339f1db9706c074fa9562c2d9e77e61e872b4f70d132b2a7a3d742e3583","793b96262b397fadb4b391e57fca295ad5f14961cfa466965b32a58342792e33","6c4faf799121ab49837f82797e4a31b515e469416cb1725abfa098c9a470e2a9","bd474f24754c25a388972fa51a5bf6f65131413bbcee5e9a3fa61827b9d27191","61211d10c17fd44d40262f33a741c1e53d7c504f569fb4323909c57b7c9d6d84","2d8fda602a4fc611fe63fe1a4a1ebbae4b36b4ce6167bbbe43365f208e5a9199","847b3b3c29e3b59cb2b798acbcc091c222ad17c3e984bfab89785039f5d5f088","609732aada2b42ca6c706db2973f42efb5241c587ab8158a9c4d8822e2386c97","2816834ee88fc1c5d2f36f27d8cc4f53b2fb0cc9d72dd5562c8f1dee8aa902ce"]}
2 |
--------------------------------------------------------------------------------