From 6efaec8f8bf27fdc553fe7a7cd0a3d57b240bdc6 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 19 Dec 2016 14:07:50 +0100 Subject: [PATCH 01/29] Blocktime format rounding --- js/src/views/Status/components/Status/status.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/views/Status/components/Status/status.js b/js/src/views/Status/components/Status/status.js index 80a489efb..b8336a6bf 100644 --- a/js/src/views/Status/components/Status/status.js +++ b/js/src/views/Status/components/Status/status.js @@ -52,7 +52,7 @@ export default class Status extends Component { #{ nodeStatus.blockNumber.toFormat() }
- { moment().calendar(nodeStatus.blockTimestamp) } + { moment(nodeStatus.blockTimestamp).calendar() }
From e1adc9606f595e69984942a54c2a1c663df97b8d Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 19 Dec 2016 15:27:17 +0100 Subject: [PATCH 02/29] parity_chainStatus RPC for block gap info --- rpc/src/v1/impls/eth.rs | 4 +--- rpc/src/v1/impls/parity.rs | 15 ++++++++++++++- rpc/src/v1/tests/mocked/eth.rs | 7 +++---- rpc/src/v1/tests/mocked/parity.rs | 15 +++++++++++++++ rpc/src/v1/traits/parity.rs | 6 +++++- rpc/src/v1/types/mod.rs.in | 7 +++++-- rpc/src/v1/types/sync.rs | 24 ++++++++++++++++-------- 7 files changed, 59 insertions(+), 19 deletions(-) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index fbd4fe8ed..491bdde10 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -293,15 +293,13 @@ impl Eth for EthClient where let chain_info = client.chain_info(); let current_block = U256::from(chain_info.best_block_number); let highest_block = U256::from(status.highest_block_number.unwrap_or(status.start_block_number)); - let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1)) - .and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last)))); + let info = SyncInfo { starting_block: status.start_block_number.into(), current_block: current_block.into(), highest_block: highest_block.into(), warp_chunks_amount: warp_chunks_amount.map(|x| U256::from(x as u64)).map(Into::into), warp_chunks_processed: warp_chunks_processed.map(|x| U256::from(x as u64)).map(Into::into), - block_gap: gap.map(|(x, y)| (x.into(), y.into())), }; Ok(SyncStatus::Info(info)) } else { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 326dc9c2b..3c14ea39e 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -40,7 +40,7 @@ use v1::types::{ Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, - OperationsInfo + OperationsInfo, ChainStatus, }; use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings}; use v1::helpers::dispatch::DEFAULT_MAC; @@ -385,4 +385,17 @@ impl Parity for ParityClient where let updater = take_weak!(self.updater); Ok(updater.info().map(Into::into)) } + + fn chain_status(&self) -> Result { + try!(self.active()); + + let chain_info = take_weak!(self.client).chain_info(); + + let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1)) + .and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last)))); + + Ok(ChainStatus { + block_gap: gap.map(|(x, y)| (x.into(), y.into())), + }) + } } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 35790a29f..c0566589e 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -137,16 +137,15 @@ fn rpc_eth_syncing() { // "sync" to 1000 blocks. // causes TestBlockChainClient to return 1000 for its best block number. tester.add_blocks(1000, EachBlockWith::Nothing); - *tester.client.ancient_block.write() = Some((H256::new(), 5)); - *tester.client.first_block.write() = Some((H256::from(U256::from(1234)), 3333)); - let true_res = r#"{"jsonrpc":"2.0","result":{"blockGap":["0x6","0xd05"],"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}"#; + + let true_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}"#; assert_eq!(tester.io.handle_request_sync(request), Some(true_res.to_owned())); *tester.client.ancient_block.write() = None; *tester.client.first_block.write() = None; - let snap_res = r#"{"jsonrpc":"2.0","result":{"blockGap":null,"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":"0x32","warpChunksProcessed":"0x18"},"id":1}"#; + let snap_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":"0x32","warpChunksProcessed":"0x18"},"id":1}"#; tester.snapshot.set_status(RestorationStatus::Ongoing { state_chunks: 40, block_chunks: 10, diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index ca5c9b8db..2ab5ba2ce 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -421,3 +421,18 @@ fn rpc_parity_local_transactions() { assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } +#[test] +fn rpc_parity_chain_status() { + use util::{H256, U256}; + + let deps = Dependencies::new(); + let io = deps.default_client(); + + *deps.client.ancient_block.write() = Some((H256::default(), 5)); + *deps.client.first_block.write() = Some((H256::from(U256::from(1234)), 3333)); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_chainStatus", "params":[], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"blockGap":["0x6","0xd05"]},"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); +} diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index d0e3b16ee..9c8d61bf4 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -26,7 +26,7 @@ use v1::types::{ Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, - OperationsInfo + OperationsInfo, ChainStatus, }; build_rpc_trait! { @@ -174,5 +174,9 @@ build_rpc_trait! { /// Get information concerning the latest releases if available. #[rpc(name = "parity_releasesInfo")] fn releases_info(&self) -> Result, Error>; + + /// Get the current chain status. + #[rpc(name = "parity_chainStatus")] + fn chain_status(&self) -> Result; } } diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 7c7c56c9a..954622a74 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -49,7 +49,10 @@ pub use self::filter::{Filter, FilterChanges}; pub use self::hash::{H64, H160, H256, H512, H520, H2048}; pub use self::index::Index; pub use self::log::Log; -pub use self::sync::{SyncStatus, SyncInfo, Peers, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo, PeerEthereumProtocolInfo, TransactionStats}; +pub use self::sync::{ + SyncStatus, SyncInfo, Peers, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo, PeerEthereumProtocolInfo, + TransactionStats, ChainStatus +}; pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus}; pub use self::transaction_request::TransactionRequest; pub use self::receipt::Receipt; @@ -59,4 +62,4 @@ pub use self::trace_filter::TraceFilter; pub use self::uint::{U128, U256}; pub use self::work::Work; pub use self::histogram::Histogram; -pub use self::consensus_status::*; \ No newline at end of file +pub use self::consensus_status::*; diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index 837b425d7..d0e3c7c99 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -37,9 +37,6 @@ pub struct SyncInfo { /// Warp sync snpashot chunks processed. #[serde(rename="warpChunksProcessed")] pub warp_chunks_processed: Option, - /// Describes the gap in the blockchain, if there is one: (first, last) - #[serde(rename="blockGap")] - pub block_gap: Option<(U256, U256)>, } /// Peers info @@ -162,17 +159,25 @@ impl From for TransactionStats { } } +/// Chain status. +#[derive(Default, Debug, Serialize)] +pub struct ChainStatus { + /// Describes the gap in the blockchain, if there is one: (first, last) + #[serde(rename="blockGap")] + pub block_gap: Option<(U256, U256)>, +} + #[cfg(test)] mod tests { use serde_json; use std::collections::BTreeMap; - use super::{SyncInfo, SyncStatus, Peers, TransactionStats}; + use super::{SyncInfo, SyncStatus, Peers, TransactionStats, ChainStatus}; #[test] fn test_serialize_sync_info() { let t = SyncInfo::default(); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null,"blockGap":null}"#); + assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null}"#); } #[test] @@ -190,16 +195,19 @@ mod tests { let t = SyncStatus::Info(SyncInfo::default()); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null,"blockGap":null}"#); + assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null}"#); } #[test] fn test_serialize_block_gap() { - let mut t = SyncInfo::default(); + let mut t = ChainStatus::default(); + let serialized = serde_json::to_string(&t).unwrap(); + assert_eq!(serialized, r#"{"blockGap":null}"#); + t.block_gap = Some((1.into(), 5.into())); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null,"blockGap":["0x1","0x5"]}"#) + assert_eq!(serialized, r#"{"blockGap":["0x1","0x5"]}"#); } #[test] From d89ee5432e0d5825606436ad91b6fb5c286b5113 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 20 Dec 2016 12:12:39 +0100 Subject: [PATCH 03/29] JS API interface for parity_chainStatus --- js/src/api/format/output.js | 15 +++++++++++++++ js/src/api/format/output.spec.js | 14 +++++++++++++- js/src/api/rpc/parity/parity.js | 8 +++++++- js/src/api/rpc/parity/parity.spec.js | 17 +++++++++++++++++ js/src/jsonrpc/interfaces/parity.js | 16 ++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js index ca1d54ede..e1887582a 100644 --- a/js/src/api/format/output.js +++ b/js/src/api/format/output.js @@ -66,6 +66,20 @@ export function outBlock (block) { return block; } +export function outChainStatus (status) { + if (status) { + Object.keys(status).forEach((key) => { + switch (key) { + case 'blockGap': + status[key] = status[key].map(outNumber); + break; + } + }); + } + + return status; +} + export function outDate (date) { return new Date(outNumber(date).toNumber() * 1000); } @@ -77,6 +91,7 @@ export function outHistogram (histogram) { case 'bucketBounds': case 'counts': histogram[key] = histogram[key].map(outNumber); + break; } }); } diff --git a/js/src/api/format/output.spec.js b/js/src/api/format/output.spec.js index 1958b57d8..ce50c69c1 100644 --- a/js/src/api/format/output.spec.js +++ b/js/src/api/format/output.spec.js @@ -16,7 +16,7 @@ import BigNumber from 'bignumber.js'; -import { outBlock, outAccountInfo, outAddress, outDate, outHistogram, outNumber, outPeers, outReceipt, outSyncing, outTransaction, outTrace } from './output'; +import { outBlock, outAccountInfo, outAddress, outChainStatus, outDate, outHistogram, outNumber, outPeers, outReceipt, outSyncing, outTransaction, outTrace } from './output'; import { isAddress, isBigNumber, isInstanceOf } from '../../../test/types'; describe('api/format/output', () => { @@ -114,6 +114,18 @@ describe('api/format/output', () => { }); }); + describe('outChainStatus', () => { + it('formats blockGap values', () => { + const status = { + blockGap: [0x1234, '0x5678'] + }; + + expect(outChainStatus(status)).to.deep.equal({ + blockGap: [new BigNumber(0x1234), new BigNumber(0x5678)] + }); + }); + }); + describe('outDate', () => { it('converts a second date in unix timestamp', () => { expect(outDate(0x57513668)).to.deep.equal(new Date('2016-06-03T07:48:56.000Z')); diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js index 2605e41e5..816081643 100644 --- a/js/src/api/rpc/parity/parity.js +++ b/js/src/api/rpc/parity/parity.js @@ -15,7 +15,7 @@ // along with Parity. If not, see . import { inAddress, inData, inHex, inNumber16, inOptions } from '../../format/input'; -import { outAccountInfo, outAddress, outHistogram, outNumber, outPeers, outTransaction } from '../../format/output'; +import { outAccountInfo, outAddress, outChainStatus, outHistogram, outNumber, outPeers, outTransaction } from '../../format/output'; export default class Parity { constructor (transport) { @@ -44,6 +44,12 @@ export default class Parity { .execute('parity_addReservedPeer', encode); } + chainStatus () { + return this._transport + .execute('parity_chainStatus') + .then(outChainStatus); + } + changePassword (account, password, newPassword) { return this._transport .execute('parity_changePassword', inAddress(account), password, newPassword); diff --git a/js/src/api/rpc/parity/parity.spec.js b/js/src/api/rpc/parity/parity.spec.js index b58c8f85c..6b15a8fe1 100644 --- a/js/src/api/rpc/parity/parity.spec.js +++ b/js/src/api/rpc/parity/parity.spec.js @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import BigNumber from 'bignumber.js'; import { TEST_HTTP_URL, mockHttp } from '../../../../test/mockRpc'; import { isBigNumber } from '../../../../test/types'; @@ -45,6 +46,22 @@ describe('api/rpc/parity', () => { }); }); + describe('chainStatus', () => { + it('retrieves the chain status', () => { + mockHttp([{ method: 'parity_chainStatus', reply: { + result: { + 'blockGap': [0x123, 0x456] + } + } }]); + + return instance.chainStatus().then((result) => { + expect(result).to.deep.equal({ + 'blockGap': [new BigNumber(0x123), new BigNumber(0x456)] + }); + }); + }); + }); + describe('gasFloorTarget', () => { it('returns the gasfloor, formatted', () => { mockHttp([{ method: 'parity_gasFloorTarget', reply: { result: '0x123456' } }]); diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js index 3f36a93b3..db194a913 100644 --- a/js/src/jsonrpc/interfaces/parity.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -86,6 +86,22 @@ export default { } }, + chainStatus: { + desc: 'Returns the information on warp sync blocks', + params: [], + returns: { + type: Object, + desc: 'The status object', + details: { + blockGap: { + type: Array, + desc: 'Describes the gap in the blockchain, if there is one: (first, last)', + optional: true + } + } + } + }, + checkRequest: { desc: 'Returns the transactionhash of the requestId (received from parity_postTransaction) if the request was confirmed', params: [ From 269338d9bf7595d36485367e77adb63ce8db04b2 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Tue, 20 Dec 2016 13:04:47 +0000 Subject: [PATCH 04/29] [ci skip] js-precompiled 20161220-130157 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a4083fd6d..70dd070f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1367,7 +1367,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#c8eb24c13e6fa57bf3b85b16209d281d89b31cbf" +source = "git+https://github.com/ethcore/js-precompiled.git#91f48517805ffbeb99d0b73a0fc4143c92918ae3" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index c7ab53a2e..8f6ea7e2e 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.131", + "version": "0.2.132", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From f5a4581fa56e5730f21843263b84159e98616f4c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 20 Dec 2016 14:05:07 +0100 Subject: [PATCH 05/29] Move release-registering to intermediate stage. --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0c9a256e3..d350615ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,7 +20,6 @@ linux-stable: - stable - triggers script: - - curl --data "secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF - cargo build -j $(nproc) --release --features final $CARGOFLAGS - strip target/release/parity - export SHA3=$(target/release/parity tools hash target/release/parity) @@ -507,6 +506,7 @@ js-release: - master - beta - stable + - triggers image: ethcore/rust:stable before_script: - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) @@ -515,5 +515,6 @@ js-release: script: - echo $JS_FILES_MODIFIED - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi + - curl --data "secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF tags: - javascript From 9a5bb9470be038d6d6a7470e9e38621aa5d20e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 20 Dec 2016 16:34:53 +0100 Subject: [PATCH 06/29] Ignore dapps_policy.json (#3919) * Ignore dapps_policy.json * Produce warning for non-ignored files --- Cargo.lock | 1 + ethstore/Cargo.toml | 1 + ethstore/src/dir/disk.rs | 14 +++++++++----- ethstore/src/lib.rs | 3 +++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70dd070f4..46c6aaa3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -665,6 +665,7 @@ dependencies = [ "itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index f47d9171f..cbb3741e9 100644 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Parity Technologies "] build = "build.rs" [dependencies] +log = "0.3" libc = "0.2.11" rand = "0.3.14" ethkey = { path = "../ethkey" } diff --git a/ethstore/src/dir/disk.rs b/ethstore/src/dir/disk.rs index d049def48..f0674d835 100644 --- a/ethstore/src/dir/disk.rs +++ b/ethstore/src/dir/disk.rs @@ -22,7 +22,7 @@ use {json, SafeAccount, Error}; use json::Uuid; use super::KeyDirectory; -const IGNORED_FILES: &'static [&'static str] = &["thumbs.db", "address_book.json"]; +const IGNORED_FILES: &'static [&'static str] = &["thumbs.db", "address_book.json", "dapps_policy.json"]; #[cfg(not(windows))] fn restrict_permissions_to_owner(file_path: &Path) -> Result<(), i32> { @@ -78,7 +78,7 @@ impl DiskDirectory { .map(|entry| entry.path()) .collect::>(); - paths + Ok(paths .iter() .map(|p| ( fs::File::open(p) @@ -86,13 +86,17 @@ impl DiskDirectory { .and_then(|r| json::KeyFile::load(r).map_err(|e| Error::Custom(format!("{:?}", e)))), p )) - .map(|(file, path)| match file { - Ok(file) => Ok((path.clone(), SafeAccount::from_file( + .filter_map(|(file, path)| match file { + Ok(file) => Some((path.clone(), SafeAccount::from_file( file, Some(path.file_name().and_then(|n| n.to_str()).expect("Keys have valid UTF8 names only.").to_owned()) ))), - Err(err) => Err(Error::InvalidKeyFile(format!("{:?}: {}", path, err))), + Err(err) => { + warn!("Invalid key file: {:?} ({})", path, err); + None + }, }) .collect() + ) } } diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index e38b04ee4..b960bfd9a 100644 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -32,6 +32,9 @@ extern crate parking_lot; extern crate ethkey as _ethkey; extern crate ethcrypto as crypto; +#[macro_use] +extern crate log; + #[macro_use] extern crate lazy_static; From 5bccd13111b8184e1f98526fa6a65f5f85d22850 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Tue, 20 Dec 2016 16:44:23 +0000 Subject: [PATCH 07/29] [ci skip] js-precompiled 20161220-164120 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46c6aaa3c..36adce0b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#91f48517805ffbeb99d0b73a0fc4143c92918ae3" +source = "git+https://github.com/ethcore/js-precompiled.git#af35fe9fa45377016ef90c55aae976fb44b35b55" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 8f6ea7e2e..df59d43d9 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.132", + "version": "0.2.133", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From af5c6af539b6efa90fd300ecf59827c382b8cbd9 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 20 Dec 2016 17:54:09 +0100 Subject: [PATCH 08/29] Split intermediate stage into two. --- .gitlab-ci.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d350615ee..7b05c1e01 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - test - js-build + - push-release - build variables: GIT_DEPTH: "3" @@ -506,7 +507,6 @@ js-release: - master - beta - stable - - triggers image: ethcore/rust:stable before_script: - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) @@ -515,6 +515,17 @@ js-release: script: - echo $JS_FILES_MODIFIED - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi - - curl --data "secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF tags: - javascript +push-release: + stage: push-release + only: + - beta + - tags + - stable + - triggers + image: ethcore/rust:stable + script: + - curl --data "secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF + tags: + - curl From af501e64678c384593f9df1b9ddb00bc0caedd29 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 21 Dec 2016 18:09:35 +0400 Subject: [PATCH 09/29] Custom attribute for binary serialization (#3922) * derive(Binary) -> binary * ethcore types refact * fixup ethcore * make binary optional * fix common types * fix updater * remove condition --- ethcore/light/src/types/les_request.rs | 26 +++--- ethcore/light/src/types/mod.rs | 3 +- ethcore/src/types/account_diff.rs | 9 +- ethcore/src/types/block_import_error.rs | 3 +- ethcore/src/types/block_status.rs | 5 +- ethcore/src/types/blockchain_info.rs | 5 +- ethcore/src/types/call_analytics.rs | 3 +- ethcore/src/types/executed.rs | 12 ++- ethcore/src/types/filter.rs | 3 +- ethcore/src/types/ids.rs | 11 ++- ethcore/src/types/log_entry.rs | 6 +- ethcore/src/types/mod.rs | 7 +- ethcore/src/types/mode.rs | 3 +- ethcore/src/types/pruning_info.rs | 5 +- ethcore/src/types/receipt.rs | 9 +- ethcore/src/types/restoration_status.rs | 3 +- ethcore/src/types/security_level.rs | 7 +- ethcore/src/types/snapshot_manifest.rs | 3 +- ethcore/src/types/state_diff.rs | 3 +- ethcore/src/types/trace_filter.rs | 2 +- ethcore/src/types/trace_types/error.rs | 3 +- ethcore/src/types/trace_types/filter.rs | 6 +- ethcore/src/types/trace_types/flat.rs | 3 +- ethcore/src/types/trace_types/localized.rs | 3 +- ethcore/src/types/trace_types/trace.rs | 36 +++++--- ethcore/src/types/transaction.rs | 35 ++++---- ethcore/src/types/transaction_import.rs | 3 +- ethcore/src/types/tree_route.rs | 3 +- ethcore/src/types/verification_queue_info.rs | 5 +- ipc-common-types/src/types/release_track.rs | 45 +++++----- ipc-common-types/src/types/version_info.rs | 5 +- ipc/codegen/src/codegen.rs | 8 +- ipc/codegen/src/lib.rs | 92 +++++++++++++++----- ipc/tests/binary.rs.in | 15 ++-- ipc/tests/nested.rs.in | 2 +- ipc/tests/service.rs.in | 2 +- stratum/src/traits.rs | 5 +- sync/src/api.rs | 8 +- updater/src/types/all.rs | 21 +++-- 39 files changed, 268 insertions(+), 160 deletions(-) diff --git a/ethcore/light/src/types/les_request.rs b/ethcore/light/src/types/les_request.rs index 864f2d4f8..dde8ac2f8 100644 --- a/ethcore/light/src/types/les_request.rs +++ b/ethcore/light/src/types/les_request.rs @@ -20,7 +20,7 @@ use util::H256; /// Either a hash or a number. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub enum HashOrNumber { /// Block hash variant. Hash(H256), @@ -42,7 +42,7 @@ impl From for HashOrNumber { /// A request for block headers. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct Headers { /// Starting block number or hash. pub start: HashOrNumber, @@ -56,7 +56,7 @@ pub struct Headers { /// A request for specific block bodies. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct Bodies { /// Hashes which bodies are being requested for. pub block_hashes: Vec @@ -67,7 +67,7 @@ pub struct Bodies { /// This request is answered with a list of transaction receipts for each block /// requested. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct Receipts { /// Block hashes to return receipts for. pub block_hashes: Vec, @@ -75,7 +75,7 @@ pub struct Receipts { /// A request for a state proof #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct StateProof { /// Block hash to query state from. pub block: H256, @@ -90,7 +90,7 @@ pub struct StateProof { /// A request for state proofs. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct StateProofs { /// All the proof requests. pub requests: Vec, @@ -98,7 +98,7 @@ pub struct StateProofs { /// A request for contract code. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct ContractCode { /// Block hash pub block_hash: H256, @@ -108,7 +108,7 @@ pub struct ContractCode { /// A request for contract code. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct ContractCodes { /// Block hash and account key (== sha3(address)) pairs to fetch code for. pub code_requests: Vec, @@ -116,7 +116,7 @@ pub struct ContractCodes { /// A request for a header proof from the Canonical Hash Trie. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct HeaderProof { /// Number of the CHT. pub cht_number: u64, @@ -128,7 +128,7 @@ pub struct HeaderProof { /// A request for header proofs from the CHT. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct HeaderProofs { /// All the proof requests. pub requests: Vec, @@ -136,7 +136,7 @@ pub struct HeaderProofs { /// Kinds of requests. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub enum Kind { /// Requesting headers. Headers, @@ -154,7 +154,7 @@ pub enum Kind { /// Encompasses all possible types of requests in a single structure. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub enum Request { /// Requesting headers. Headers(Headers), @@ -194,4 +194,4 @@ impl Request { Request::HeaderProofs(ref req) => req.requests.len(), } } -} \ No newline at end of file +} diff --git a/ethcore/light/src/types/mod.rs b/ethcore/light/src/types/mod.rs index 86d269766..60765dfc5 100644 --- a/ethcore/light/src/types/mod.rs +++ b/ethcore/light/src/types/mod.rs @@ -17,9 +17,8 @@ //! Types used in the public (IPC) api which require custom code generation. #![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues - #[cfg(feature = "ipc")] include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); #[cfg(not(feature = "ipc"))] -include!("mod.rs.in"); \ No newline at end of file +include!("mod.rs.in"); diff --git a/ethcore/src/types/account_diff.rs b/ethcore/src/types/account_diff.rs index c8d5c9eec..96180aefd 100644 --- a/ethcore/src/types/account_diff.rs +++ b/ethcore/src/types/account_diff.rs @@ -22,7 +22,8 @@ use std::collections::BTreeMap; use util::{U256, H256, Uint, Bytes}; use ipc::binary::BinaryConvertable; -#[derive(Debug, PartialEq, Eq, Clone, Binary)] +#[derive(Debug, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "ipc", binary)] /// Diff type for specifying a change (or not). pub enum Diff where T: Eq + BinaryConvertable { /// Both sides are the same. @@ -49,7 +50,8 @@ impl Diff where T: Eq + BinaryConvertable { pub fn is_same(&self) -> bool { match *self { Diff::Same => true, _ => false }} } -#[derive(Debug, PartialEq, Eq, Clone, Binary)] +#[derive(Debug, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "ipc", binary)] /// Account diff. pub struct AccountDiff { /// Change in balance, allowed to be `Diff::Same`. @@ -62,7 +64,8 @@ pub struct AccountDiff { pub storage: BTreeMap>, } -#[derive(Debug, PartialEq, Eq, Clone, Binary)] +#[derive(Debug, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "ipc", binary)] /// Change in existance type. // TODO: include other types of change. pub enum Existance { diff --git a/ethcore/src/types/block_import_error.rs b/ethcore/src/types/block_import_error.rs index e229db6d2..ae29dd5a5 100644 --- a/ethcore/src/types/block_import_error.rs +++ b/ethcore/src/types/block_import_error.rs @@ -20,7 +20,8 @@ use error::{ImportError, BlockError, Error}; use std::convert::From; /// Error dedicated to import block function -#[derive(Binary, Debug)] +#[derive(Debug)] +#[cfg_attr(feature = "ipc", binary)] pub enum BlockImportError { /// Import error Import(ImportError), diff --git a/ethcore/src/types/block_status.rs b/ethcore/src/types/block_status.rs index d1c6c7d5b..33ca3f352 100644 --- a/ethcore/src/types/block_status.rs +++ b/ethcore/src/types/block_status.rs @@ -18,7 +18,8 @@ use verification::queue::Status as QueueStatus; /// General block status -#[derive(Debug, Eq, PartialEq, Binary)] +#[derive(Debug, Eq, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub enum BlockStatus { /// Part of the blockchain. InChain, @@ -38,4 +39,4 @@ impl From for BlockStatus { QueueStatus::Unknown => BlockStatus::Unknown, } } -} \ No newline at end of file +} diff --git a/ethcore/src/types/blockchain_info.rs b/ethcore/src/types/blockchain_info.rs index 33657ff0e..50887c0b7 100644 --- a/ethcore/src/types/blockchain_info.rs +++ b/ethcore/src/types/blockchain_info.rs @@ -21,7 +21,8 @@ use header::BlockNumber; use types::security_level::SecurityLevel; /// Information about the blockchain gathered together. -#[derive(Clone, Debug, Binary)] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "ipc", binary)] pub struct BlockChainInfo { /// Blockchain difficulty. pub total_difficulty: U256, @@ -53,4 +54,4 @@ impl BlockChainInfo { SecurityLevel::PartialProofOfWork(self.best_block_number - self.first_block_number.expect("Guard condition means this is not none")) } } -} \ No newline at end of file +} diff --git a/ethcore/src/types/call_analytics.rs b/ethcore/src/types/call_analytics.rs index 9da2d11ae..5274adfac 100644 --- a/ethcore/src/types/call_analytics.rs +++ b/ethcore/src/types/call_analytics.rs @@ -17,7 +17,8 @@ //! Call analytics related types /// Options concerning what analytics we run on the call. -#[derive(Eq, PartialEq, Default, Clone, Copy, Debug, Binary)] +#[derive(Eq, PartialEq, Default, Clone, Copy, Debug)] +#[cfg_attr(feature = "ipc", binary)] pub struct CallAnalytics { /// Make a transaction trace. pub transaction_tracing: bool, diff --git a/ethcore/src/types/executed.rs b/ethcore/src/types/executed.rs index 3ce8d2634..1f0ef33c7 100644 --- a/ethcore/src/types/executed.rs +++ b/ethcore/src/types/executed.rs @@ -24,7 +24,8 @@ use types::state_diff::StateDiff; use std::fmt; /// The type of the call-like instruction. -#[derive(Debug, PartialEq, Clone, Binary)] +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub enum CallType { /// Not a CALL. None, @@ -61,7 +62,8 @@ impl Decodable for CallType { } /// Transaction execution receipt. -#[derive(Debug, PartialEq, Clone, Binary)] +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct Executed { /// Gas paid up front for execution of transaction. pub gas: U256, @@ -101,7 +103,8 @@ pub struct Executed { } /// Result of executing the transaction. -#[derive(PartialEq, Debug, Clone, Binary)] +#[derive(PartialEq, Debug, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub enum ExecutionError { /// Returned when there gas paid for transaction execution is /// lower than base gas required. @@ -168,7 +171,8 @@ impl fmt::Display for ExecutionError { } /// Result of executing the transaction. -#[derive(PartialEq, Debug, Clone, Binary)] +#[derive(PartialEq, Debug, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub enum CallError { /// Couldn't find the transaction in the chain. TransactionNotFound, diff --git a/ethcore/src/types/filter.rs b/ethcore/src/types/filter.rs index 8aecef43b..f940423e3 100644 --- a/ethcore/src/types/filter.rs +++ b/ethcore/src/types/filter.rs @@ -22,7 +22,8 @@ use client::BlockId; use log_entry::LogEntry; /// Blockchain Filter. -#[derive(Binary, Debug, PartialEq)] +#[derive(Debug, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct Filter { /// Blockchain will be searched from this block. pub from_block: BlockId, diff --git a/ethcore/src/types/ids.rs b/ethcore/src/types/ids.rs index 2828c4798..42b51c54e 100644 --- a/ethcore/src/types/ids.rs +++ b/ethcore/src/types/ids.rs @@ -20,7 +20,8 @@ use util::hash::H256; use header::BlockNumber; /// Uniquely identifies block. -#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Binary)] +#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub enum BlockId { /// Block's sha3. /// Querying by hash is always faster. @@ -36,7 +37,8 @@ pub enum BlockId { } /// Uniquely identifies transaction. -#[derive(Debug, PartialEq, Clone, Hash, Eq, Binary)] +#[derive(Debug, PartialEq, Clone, Hash, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub enum TransactionId { /// Transaction's sha3. Hash(H256), @@ -46,7 +48,7 @@ pub enum TransactionId { } /// Uniquely identifies Trace. -#[derive(Binary)] +#[cfg_attr(feature = "ipc", binary)] pub struct TraceId { /// Transaction pub transaction: TransactionId, @@ -55,7 +57,8 @@ pub struct TraceId { } /// Uniquely identifies Uncle. -#[derive(Debug, PartialEq, Eq, Copy, Clone, Binary)] +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct UncleId { /// Block id. pub block: BlockId, diff --git a/ethcore/src/types/log_entry.rs b/ethcore/src/types/log_entry.rs index 19531a9e9..7407952ba 100644 --- a/ethcore/src/types/log_entry.rs +++ b/ethcore/src/types/log_entry.rs @@ -26,7 +26,8 @@ use header::BlockNumber; use ethjson; /// A record of execution for a `LOG` operation. -#[derive(Default, Debug, Clone, PartialEq, Eq, Binary)] +#[derive(Default, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub struct LogEntry { /// The address of the contract executing at the point of the `LOG` operation. pub address: Address, @@ -81,7 +82,8 @@ impl From for LogEntry { } /// Log localized in a blockchain. -#[derive(Default, Debug, PartialEq, Clone, Binary)] +#[derive(Default, Debug, PartialEq, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedLogEntry { /// Plain log entry. pub entry: LogEntry, diff --git a/ethcore/src/types/mod.rs b/ethcore/src/types/mod.rs index 959ff694a..6d2072ce2 100644 --- a/ethcore/src/types/mod.rs +++ b/ethcore/src/types/mod.rs @@ -16,5 +16,10 @@ //! Types used in the public api -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues +#![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues + +#[cfg(feature = "ipc")] include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); + +#[cfg(not(feature = "ipc"))] +include!("mod.rs.in"); diff --git a/ethcore/src/types/mode.rs b/ethcore/src/types/mode.rs index a1df3c76f..95bcd0d2b 100644 --- a/ethcore/src/types/mode.rs +++ b/ethcore/src/types/mode.rs @@ -20,7 +20,8 @@ pub use std::time::Duration; use client::Mode as ClientMode; /// IPC-capable shadow-type for `client::config::Mode` -#[derive(Clone, Binary, Debug)] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "ipc", binary)] pub enum Mode { /// Same as `ClientMode::Off`. Off, diff --git a/ethcore/src/types/pruning_info.rs b/ethcore/src/types/pruning_info.rs index fd5689d2d..80c3e0ce2 100644 --- a/ethcore/src/types/pruning_info.rs +++ b/ethcore/src/types/pruning_info.rs @@ -21,10 +21,11 @@ //! of which portions of the ancient chain and current state trie are stored as well. /// Client pruning info. See module-level docs for more details. -#[derive(Debug, Clone, Binary)] +#[derive(Debug, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct PruningInfo { /// The first block which everything can be served after. pub earliest_chain: u64, /// The first block where state requests may be served. pub earliest_state: u64, -} \ No newline at end of file +} diff --git a/ethcore/src/types/receipt.rs b/ethcore/src/types/receipt.rs index c15f039bc..524526ff6 100644 --- a/ethcore/src/types/receipt.rs +++ b/ethcore/src/types/receipt.rs @@ -25,7 +25,8 @@ use header::BlockNumber; use log_entry::{LogEntry, LocalizedLogEntry}; /// Information describing execution of a transaction. -#[derive(Default, Debug, Clone, Binary)] +#[derive(Default, Debug, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct Receipt { /// The state root after executing the transaction. pub state_root: H256, @@ -79,7 +80,8 @@ impl HeapSizeOf for Receipt { } /// Receipt with additional info. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct RichReceipt { /// Transaction hash. pub transaction_hash: H256, @@ -100,7 +102,8 @@ pub struct RichReceipt { } /// Receipt with additional info. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedReceipt { /// Transaction hash. pub transaction_hash: H256, diff --git a/ethcore/src/types/restoration_status.rs b/ethcore/src/types/restoration_status.rs index 507659d5b..065946ea2 100644 --- a/ethcore/src/types/restoration_status.rs +++ b/ethcore/src/types/restoration_status.rs @@ -17,7 +17,8 @@ //! Restoration status type definition /// Statuses for restorations. -#[derive(PartialEq, Eq, Clone, Copy, Debug, Binary)] +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[cfg_attr(feature = "ipc", binary)] pub enum RestorationStatus { /// No restoration. Inactive, diff --git a/ethcore/src/types/security_level.rs b/ethcore/src/types/security_level.rs index 0415b9bb1..48d252b28 100644 --- a/ethcore/src/types/security_level.rs +++ b/ethcore/src/types/security_level.rs @@ -19,7 +19,8 @@ use header::BlockNumber; /// Indication of how secure the chain is. -#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Binary)] +#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub enum SecurityLevel { /// All blocks from genesis to chain head are known to have valid state transitions and PoW. FullState, @@ -35,6 +36,6 @@ impl SecurityLevel { match *self { SecurityLevel::FullState | SecurityLevel::FullProofOfWork => true, _ => false, - } + } } -} \ No newline at end of file +} diff --git a/ethcore/src/types/snapshot_manifest.rs b/ethcore/src/types/snapshot_manifest.rs index dac164b0b..1c1e801cb 100644 --- a/ethcore/src/types/snapshot_manifest.rs +++ b/ethcore/src/types/snapshot_manifest.rs @@ -21,7 +21,8 @@ use rlp::*; use util::Bytes; /// Manifest data. -#[derive(Debug, Clone, PartialEq, Eq, Binary)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub struct ManifestData { /// List of state chunk hashes. pub state_hashes: Vec, diff --git a/ethcore/src/types/state_diff.rs b/ethcore/src/types/state_diff.rs index 6b8242db6..cb3db1ba9 100644 --- a/ethcore/src/types/state_diff.rs +++ b/ethcore/src/types/state_diff.rs @@ -22,7 +22,8 @@ use std::collections::BTreeMap; use util::Address; use account_diff::*; -#[derive(Debug, PartialEq, Eq, Clone, Binary)] +#[derive(Debug, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "ipc", binary)] /// Expression for the delta between two system states. Encoded the /// delta of every altered account. pub struct StateDiff { diff --git a/ethcore/src/types/trace_filter.rs b/ethcore/src/types/trace_filter.rs index 5a7ed8429..4085c5bd0 100644 --- a/ethcore/src/types/trace_filter.rs +++ b/ethcore/src/types/trace_filter.rs @@ -21,7 +21,7 @@ use util::{Address}; use types::ids::BlockId; /// Easy to use trace filter. -#[derive(Binary)] +#[cfg_attr(feature = "ipc", binary)] pub struct Filter { /// Range of filtering. pub range: Range, diff --git a/ethcore/src/types/trace_types/error.rs b/ethcore/src/types/trace_types/error.rs index 72b873fc9..2294f673a 100644 --- a/ethcore/src/types/trace_types/error.rs +++ b/ethcore/src/types/trace_types/error.rs @@ -21,7 +21,8 @@ use rlp::{Encodable, RlpStream, Decodable, Decoder, DecoderError, Stream, View}; use evm::Error as EvmError; /// Trace evm errors. -#[derive(Debug, PartialEq, Clone, Binary)] +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub enum Error { /// `OutOfGas` is returned when transaction execution runs out of gas. OutOfGas, diff --git a/ethcore/src/types/trace_types/filter.rs b/ethcore/src/types/trace_types/filter.rs index b12112acd..282aeab9b 100644 --- a/ethcore/src/types/trace_types/filter.rs +++ b/ethcore/src/types/trace_types/filter.rs @@ -28,7 +28,8 @@ use types::trace_types::trace::{Action, Res}; /// Addresses filter. /// /// Used to create bloom possibilities and match filters. -#[derive(Debug, Binary)] +#[derive(Debug)] +#[cfg_attr(feature = "ipc", binary)] pub struct AddressesFilter { list: Vec
} @@ -74,7 +75,8 @@ impl AddressesFilter { } } -#[derive(Debug, Binary)] +#[derive(Debug)] +#[cfg_attr(feature = "ipc", binary)] /// Traces filter. pub struct Filter { /// Block range. diff --git a/ethcore/src/types/trace_types/flat.rs b/ethcore/src/types/trace_types/flat.rs index 8a949c210..b79cabb49 100644 --- a/ethcore/src/types/trace_types/flat.rs +++ b/ethcore/src/types/trace_types/flat.rs @@ -25,7 +25,8 @@ use super::trace::{Action, Res}; /// Trace localized in vector of traces produced by a single transaction. /// /// Parent and children indexes refer to positions in this vector. -#[derive(Debug, PartialEq, Clone, Binary)] +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct FlatTrace { /// Type of action performed by a transaction. pub action: Action, diff --git a/ethcore/src/types/trace_types/localized.rs b/ethcore/src/types/trace_types/localized.rs index f65c47415..1b8cbd1b8 100644 --- a/ethcore/src/types/trace_types/localized.rs +++ b/ethcore/src/types/trace_types/localized.rs @@ -21,7 +21,8 @@ use super::trace::{Action, Res}; use header::BlockNumber; /// Localized trace. -#[derive(Debug, PartialEq, Clone, Binary)] +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedTrace { /// Type of action performed by a transaction. pub action: Action, diff --git a/ethcore/src/types/trace_types/trace.rs b/ethcore/src/types/trace_types/trace.rs index 7f5149905..55494c533 100644 --- a/ethcore/src/types/trace_types/trace.rs +++ b/ethcore/src/types/trace_types/trace.rs @@ -27,7 +27,8 @@ use types::executed::CallType; use super::error::Error; /// `Call` result. -#[derive(Debug, Clone, PartialEq, Default, Binary)] +#[derive(Debug, Clone, PartialEq, Default)] +#[cfg_attr(feature = "ipc", binary)] pub struct CallResult { /// Gas used by call. pub gas_used: U256, @@ -56,7 +57,8 @@ impl Decodable for CallResult { } /// `Create` result. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct CreateResult { /// Gas used by create. pub gas_used: U256, @@ -96,7 +98,8 @@ impl CreateResult { } /// Description of a _call_ action, either a `CALL` operation or a message transction. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct Call { /// The sending account. pub from: Address, @@ -163,7 +166,8 @@ impl Call { } /// Description of a _create_ action, either a `CREATE` operation or a create transction. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct Create { /// The address of the creator. pub from: Address, @@ -219,7 +223,8 @@ impl Create { } /// Suicide action. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub struct Suicide { /// Suicided address. pub address: Address, @@ -261,7 +266,8 @@ impl Decodable for Suicide { /// Description of an action that we trace; will be either a call or a create. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub enum Action { /// It's a call action. Call(Call), @@ -316,7 +322,8 @@ impl Action { } /// The result of the performed action. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] pub enum Res { /// Successful call action result. Call(CallResult), @@ -386,7 +393,8 @@ impl Res { } } -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] /// A diff of some chunk of memory. pub struct MemoryDiff { /// Offset into memory the change begins. @@ -413,7 +421,8 @@ impl Decodable for MemoryDiff { } } -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] /// A diff of some storage value. pub struct StorageDiff { /// Which key in storage is changed. @@ -440,7 +449,8 @@ impl Decodable for StorageDiff { } } -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "ipc", binary)] /// A record of an executed VM operation. pub struct VMExecutedOperation { /// The total gas used. @@ -475,7 +485,8 @@ impl Decodable for VMExecutedOperation { } } -#[derive(Debug, Clone, PartialEq, Binary, Default)] +#[derive(Debug, Clone, PartialEq, Default)] +#[cfg_attr(feature = "ipc", binary)] /// A record of the execution of a single VM operation. pub struct VMOperation { /// The program counter. @@ -512,7 +523,8 @@ impl Decodable for VMOperation { } } -#[derive(Debug, Clone, PartialEq, Binary, Default)] +#[derive(Debug, Clone, PartialEq, Default)] +#[cfg_attr(feature = "ipc", binary)] /// A record of a full VM trace for a CALL/CREATE. pub struct VMTrace { /// The step (i.e. index into operations) at which this trace corresponds. diff --git a/ethcore/src/types/transaction.rs b/ethcore/src/types/transaction.rs index 2cd001bdb..32fe9acab 100644 --- a/ethcore/src/types/transaction.rs +++ b/ethcore/src/types/transaction.rs @@ -27,7 +27,8 @@ use evm::Schedule; use header::BlockNumber; use ethjson; -#[derive(Debug, Clone, PartialEq, Eq, Binary)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] /// Transaction action type. pub enum Action { /// Create creates new contract. @@ -54,7 +55,8 @@ impl Decodable for Action { /// A set of information describing an externally-originating message call /// or contract creation operation. -#[derive(Default, Debug, Clone, PartialEq, Eq, Binary)] +#[derive(Default, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub struct Transaction { /// Nonce. pub nonce: U256, @@ -205,7 +207,8 @@ impl Transaction { } /// Signed transaction information. -#[derive(Debug, Clone, Eq, Binary)] +#[derive(Debug, Clone, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub struct SignedTransaction { /// Plain Transaction. unsigned: Transaction, @@ -370,7 +373,8 @@ impl SignedTransaction { } /// Signed Transaction that is a part of canon blockchain. -#[derive(Debug, PartialEq, Eq, Binary)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedTransaction { /// Signed part. pub signed: SignedTransaction, @@ -391,7 +395,8 @@ impl Deref for LocalizedTransaction { } /// Queued transaction with additional information. -#[derive(Debug, Clone, PartialEq, Eq, Binary)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] pub struct PendingTransaction { /// Signed transaction data. pub transaction: SignedTransaction, @@ -495,14 +500,14 @@ fn should_agree_with_vitalik() { flushln!("networkid: {:?}", signed.network_id()); }; - test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce") - test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112") - test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be") - test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0") - test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554") - test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4") - test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35") - test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332") - test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029") - test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f") + test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce"); + test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112"); + test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be"); + test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0"); + test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554"); + test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4"); + test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35"); + test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332"); + test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029"); + test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f"); } diff --git a/ethcore/src/types/transaction_import.rs b/ethcore/src/types/transaction_import.rs index cfd3d5243..9be235fb0 100644 --- a/ethcore/src/types/transaction_import.rs +++ b/ethcore/src/types/transaction_import.rs @@ -31,7 +31,8 @@ pub enum TransactionImportResult { binary_fixed_size!(TransactionImportResult); /// Api-level error for transaction import -#[derive(Debug, Clone, Binary)] +#[derive(Debug, Clone)] +#[cfg_attr(feature = "ipc", binary)] pub enum TransactionImportError { /// Transaction error Transaction(TransactionError), diff --git a/ethcore/src/types/tree_route.rs b/ethcore/src/types/tree_route.rs index 7a97cac03..ff7362ad2 100644 --- a/ethcore/src/types/tree_route.rs +++ b/ethcore/src/types/tree_route.rs @@ -19,7 +19,8 @@ use util::H256; /// Represents a tree route between `from` block and `to` block: -#[derive(Debug, Binary)] +#[derive(Debug)] +#[cfg_attr(feature = "ipc", binary)] pub struct TreeRoute { /// A vector of hashes of all blocks, ordered from `from` to `to`. pub blocks: Vec, diff --git a/ethcore/src/types/verification_queue_info.rs b/ethcore/src/types/verification_queue_info.rs index 3361155df..aba7785d8 100644 --- a/ethcore/src/types/verification_queue_info.rs +++ b/ethcore/src/types/verification_queue_info.rs @@ -17,7 +17,8 @@ //! Verification queue info types /// Verification queue status -#[derive(Debug, Binary)] +#[derive(Debug)] +#[cfg_attr(feature = "ipc", binary)] pub struct VerificationQueueInfo { /// Number of queued items pending verification pub unverified_queue_size: usize, @@ -50,4 +51,4 @@ impl VerificationQueueInfo { pub fn is_empty(&self) -> bool { self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size == 0 } -} \ No newline at end of file +} diff --git a/ipc-common-types/src/types/release_track.rs b/ipc-common-types/src/types/release_track.rs index 3fcc0bb64..0e68a9a31 100644 --- a/ipc-common-types/src/types/release_track.rs +++ b/ipc-common-types/src/types/release_track.rs @@ -19,7 +19,8 @@ use std::fmt; /// A release's track. -#[derive(PartialEq, Eq, Clone, Copy, Debug, Binary)] +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[binary] pub enum ReleaseTrack { /// Stable track. Stable, @@ -36,9 +37,9 @@ pub enum ReleaseTrack { impl fmt::Display for ReleaseTrack { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", match *self { - ReleaseTrack::Stable => "stable", - ReleaseTrack::Beta => "beta", - ReleaseTrack::Nightly => "nightly", + ReleaseTrack::Stable => "stable", + ReleaseTrack::Beta => "beta", + ReleaseTrack::Nightly => "nightly", ReleaseTrack::Testing => "testing", ReleaseTrack::Unknown => "unknown", }) @@ -48,35 +49,35 @@ impl fmt::Display for ReleaseTrack { impl<'a> From<&'a str> for ReleaseTrack { fn from(s: &'a str) -> Self { match s { - "stable" => ReleaseTrack::Stable, - "beta" => ReleaseTrack::Beta, - "nightly" => ReleaseTrack::Nightly, - "testing" => ReleaseTrack::Testing, - _ => ReleaseTrack::Unknown, - } + "stable" => ReleaseTrack::Stable, + "beta" => ReleaseTrack::Beta, + "nightly" => ReleaseTrack::Nightly, + "testing" => ReleaseTrack::Testing, + _ => ReleaseTrack::Unknown, + } } } impl From for ReleaseTrack { fn from(i: u8) -> Self { match i { - 1 => ReleaseTrack::Stable, - 2 => ReleaseTrack::Beta, - 3 => ReleaseTrack::Nightly, - 4 => ReleaseTrack::Testing, - _ => ReleaseTrack::Unknown, - } + 1 => ReleaseTrack::Stable, + 2 => ReleaseTrack::Beta, + 3 => ReleaseTrack::Nightly, + 4 => ReleaseTrack::Testing, + _ => ReleaseTrack::Unknown, + } } } impl Into for ReleaseTrack { fn into(self) -> u8 { match self { - ReleaseTrack::Stable => 1, - ReleaseTrack::Beta => 2, - ReleaseTrack::Nightly => 3, - ReleaseTrack::Testing => 4, - ReleaseTrack::Unknown => 0, - } + ReleaseTrack::Stable => 1, + ReleaseTrack::Beta => 2, + ReleaseTrack::Nightly => 3, + ReleaseTrack::Testing => 4, + ReleaseTrack::Unknown => 0, + } } } diff --git a/ipc-common-types/src/types/version_info.rs b/ipc-common-types/src/types/version_info.rs index cbffbe198..bd869bf01 100644 --- a/ipc-common-types/src/types/version_info.rs +++ b/ipc-common-types/src/types/version_info.rs @@ -22,8 +22,9 @@ use util::{H160}; use util::misc::raw_package_info; use release_track::ReleaseTrack; -/// Version information of a particular release. -#[derive(Debug, Clone, PartialEq, Binary)] +/// Version information of a particular release. +#[derive(Debug, Clone, PartialEq)] +#[binary] pub struct VersionInfo { /// The track on which it was released. pub track: ReleaseTrack, diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index 27eb8fb0b..9cc49d53f 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -111,7 +111,7 @@ fn push_invoke_signature_aster( let arg_ty = &inputs[skip-1].ty; let mut tree = builder.item() - .attr().word("derive(Binary)") + .attr().word("binary") .attr().word("allow(non_camel_case_types)") .struct_(name_str.as_str()) .field(arg_name.as_str()) @@ -140,7 +140,7 @@ fn push_invoke_signature_aster( FunctionRetTy::Ty(ref ty) => { let name_str = format!("{}_output", named_signature.ident.name.as_str()); let tree = builder.item() - .attr().word("derive(Binary)") + .attr().word("binary") .attr().word("allow(non_camel_case_types)") .struct_(name_str.as_str()) .field(format!("payload")).ty().build(ty.clone()); @@ -326,7 +326,7 @@ pub fn has_ptr(ty: &P) -> bool { /// fn commit(&self, f: u32) -> u32 /// /// the expanded implementation will generate method for the client like that -/// #[derive(Serialize)] +/// #[binary] /// struct Request<'a> { /// f: &'a u32, /// } @@ -358,7 +358,7 @@ fn implement_client_method_body( .build(static_ty.clone()); let mut tree = builder.item() - .attr().word("derive(Binary)") + .attr().word("binary") .struct_("Request") .generics() .lifetime_name("'a") diff --git a/ipc/codegen/src/lib.rs b/ipc/codegen/src/lib.rs index caa0228fc..b4825d7f9 100644 --- a/ipc/codegen/src/lib.rs +++ b/ipc/codegen/src/lib.rs @@ -42,6 +42,10 @@ extern crate rustc_plugin; #[cfg(not(feature = "with-syntex"))] use syntax::feature_gate::AttributeType; +#[cfg(feature = "with-syntex")] +use syntax::{ast, fold}; + + #[cfg(feature = "with-syntex")] include!(concat!(env!("OUT_DIR"), "/lib.rs")); @@ -56,29 +60,44 @@ pub fn expand(src: &std::path::Path, dst: &std::path::Path) { } #[cfg(feature = "with-syntex")] -pub fn register_cleaner(reg: &mut syntex::Registry) { - use syntax::{ast, fold}; +struct StripAttributeFolder<'a> { + attr_title: &'a str, +} - #[cfg(feature = "with-syntex")] - fn strip_attributes(krate: ast::Crate) -> ast::Crate { - struct StripAttributeFolder; - impl fold::Folder for StripAttributeFolder { - fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { - match attr.node.value.node { - ast::MetaItemKind::List(ref n, _) if n == &"ipc" => { return None; } - ast::MetaItemKind::Word(ref n) if n == &"ipc" => { return None; } - _ => {} - } - - Some(attr) - } - - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) - } +#[cfg(feature = "with-syntex")] +impl<'a> fold::Folder for StripAttributeFolder<'a> { + fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { + match attr.node.value.node { + ast::MetaItemKind::List(ref n, _) if n == self.attr_title => { return None; } + ast::MetaItemKind::Word(ref n) if n == self.attr_title => { return None; } + _ => {} } - fold::Folder::fold_crate(&mut StripAttributeFolder, krate) + Some(attr) + } + + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } +} + +#[cfg(feature = "with-syntex")] +pub fn register_cleaner_ipc(reg: &mut syntex::Registry) { + #[cfg(feature = "with-syntex")] + fn strip_attributes(krate: ast::Crate) -> ast::Crate { + let mut folder = StripAttributeFolder { attr_title: "ipc" }; + fold::Folder::fold_crate(&mut folder, krate) + } + + reg.add_post_expansion_pass(strip_attributes); +} + +#[cfg(feature = "with-syntex")] +pub fn register_cleaner_binary(reg: &mut syntex::Registry) { + #[cfg(feature = "with-syntex")] + fn strip_attributes(krate: ast::Crate) -> ast::Crate { + let mut folder = StripAttributeFolder { attr_title: "binary" }; + fold::Folder::fold_crate(&mut folder, krate) } reg.add_post_expansion_pass(strip_attributes); @@ -90,9 +109,10 @@ pub fn register(reg: &mut syntex::Registry) { reg.add_attr("feature(custom_attribute)"); reg.add_decorator("ipc", codegen::expand_ipc_implementation); - reg.add_decorator("derive_Binary", serialization::expand_serialization_implementation); + reg.add_decorator("binary", serialization::expand_serialization_implementation); - register_cleaner(reg); + register_cleaner_ipc(reg); + register_cleaner_binary(reg); } #[cfg(not(feature = "with-syntex"))] @@ -102,11 +122,12 @@ pub fn register(reg: &mut rustc_plugin::Registry) { syntax::ext::base::MultiDecorator( Box::new(codegen::expand_ipc_implementation))); reg.register_syntax_extension( - syntax::parse::token::intern("derive_Binary"), + syntax::parse::token::intern("binary"), syntax::ext::base::MultiDecorator( Box::new(serialization::expand_serialization_implementation))); reg.register_attribute("ipc".to_owned(), AttributeType::Normal); + reg.register_attribute("binary".to_owned(), AttributeType::Normal); } #[derive(Debug)] @@ -124,13 +145,31 @@ pub fn derive_ipc_cond(src_path: &str, has_feature: bool) -> Result<(), Error> { } pub fn cleanup_ipc(src_path: &str) -> Result<(), Error> { + cleanup(src_path, AttributeKind::Ipc) +} + +pub fn cleanup_binary(src_path: &str) -> Result<(), Error> { + cleanup(src_path, AttributeKind::Binary) +} + +enum AttributeKind { + Ipc, + Binary, +} + +fn cleanup(src_path: &str, attr: AttributeKind) -> Result<(), Error> { use std::env; use std::path::{Path, PathBuf}; let out_dir = env::var_os("OUT_DIR").unwrap(); let file_name = try!(PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())); let mut registry = syntex::Registry::new(); - register_cleaner(&mut registry); + + match attr { + AttributeKind::Ipc => { register_cleaner_ipc(&mut registry); } + AttributeKind::Binary => { register_cleaner_binary(&mut registry); } + } + if let Err(_) = registry.expand("", &Path::new(src_path), &Path::new(&out_dir).join(&file_name)) { // will be reported by compiler @@ -190,3 +229,8 @@ pub fn derive_binary(src_path: &str) -> Result<(), Error> { Ok(()) } + +pub fn derive_binary_cond(src_path: &str, has_feature: bool) -> Result<(), Error> { + if has_feature { derive_binary(src_path) } + else { cleanup_binary(src_path) } +} diff --git a/ipc/tests/binary.rs.in b/ipc/tests/binary.rs.in index 34e33609f..513007b22 100644 --- a/ipc/tests/binary.rs.in +++ b/ipc/tests/binary.rs.in @@ -17,37 +17,40 @@ use util::Bytes; -#[derive(Binary)] +#[binary] pub enum Root { Top, Middle(u32, u64), } -#[derive(Binary, PartialEq, Debug)] +#[derive(PartialEq, Debug)] +#[binary] pub struct DoubleRoot { pub x1: u32, pub x2: u64, pub x3: u32, } -#[derive(Binary, PartialEq, Debug)] +#[derive(PartialEq, Debug)] +#[binary] pub struct ReferenceStruct<'a> { pub ref_data: &'a u64, } -#[derive(Binary, PartialEq, Debug)] +#[derive(PartialEq, Debug)] +#[binary] pub enum EnumWithStruct { Left, Right { how_much: u64 }, } -#[derive(Binary)] +#[binary] pub struct TwoVec { v1: Vec, v2: Vec, } -#[derive(Binary)] +#[binary] struct ChunkSet { items: Vec, } diff --git a/ipc/tests/nested.rs.in b/ipc/tests/nested.rs.in index a12371ecf..763cd9e71 100644 --- a/ipc/tests/nested.rs.in +++ b/ipc/tests/nested.rs.in @@ -30,7 +30,7 @@ pub trait DBWriter { impl IpcConfig for DBWriter {} -#[derive(Binary)] +#[binary] pub enum DBError { Write, Read } #[ipc] diff --git a/ipc/tests/service.rs.in b/ipc/tests/service.rs.in index 9bfe93cb3..84cc38427 100644 --- a/ipc/tests/service.rs.in +++ b/ipc/tests/service.rs.in @@ -22,7 +22,7 @@ pub struct Service { pub rollbacks: RwLock, } -#[derive(Binary)] +#[binary] pub struct CustomData { pub a: u64, pub b: u64, diff --git a/stratum/src/traits.rs b/stratum/src/traits.rs index 98a6ba763..8f172bef2 100644 --- a/stratum/src/traits.rs +++ b/stratum/src/traits.rs @@ -19,7 +19,8 @@ use std::error::Error as StdError; use util::H256; use ipc::IpcConfig; -#[derive(Debug, Clone, Binary)] +#[derive(Debug, Clone)] +#[binary] pub enum Error { NoWork, NoWorkers, @@ -53,7 +54,7 @@ pub trait PushWorkHandler: Send + Sync { fn push_work(&self, payloads: Vec) -> Result<(), Error>; } -#[derive(Binary)] +#[binary] pub struct ServiceConfiguration { pub listen_addr: String, pub secret: Option, diff --git a/sync/src/api.rs b/sync/src/api.rs index 45a9c1eb7..d623ba9c3 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -304,7 +304,7 @@ impl ChainNotify for EthSync { Some(lp) => lp, None => return, }; - + let chain_info = self.eth_handler.chain.chain_info(); light_proto.make_announcement(context, Announcement { head_hash: chain_info.best_block_hash, @@ -431,7 +431,7 @@ impl ManageNetwork for EthSync { /// IP fiter #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub enum AllowIP { /// Connect to any address All, @@ -454,7 +454,7 @@ impl AllowIP { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] /// Network service configuration pub struct NetworkConfiguration { /// Directory path to store general network configuration. None means nothing will be saved @@ -558,7 +558,7 @@ impl From for NetworkConfiguration { /// Configuration for IPC service. #[derive(Debug, Clone)] -#[cfg_attr(feature = "ipc", derive(Binary))] +#[cfg_attr(feature = "ipc", binary)] pub struct ServiceConfiguration { /// Sync config. pub sync: SyncConfig, diff --git a/updater/src/types/all.rs b/updater/src/types/all.rs index 5a602afcd..2337dfac5 100644 --- a/updater/src/types/all.rs +++ b/updater/src/types/all.rs @@ -20,43 +20,46 @@ use util::{H256}; pub use ipc_common_types::{VersionInfo, ReleaseTrack}; /// Information regarding a particular release of Parity -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[binary] pub struct ReleaseInfo { /// Information on the version. pub version: VersionInfo, - /// Does this release contain critical security updates? + /// Does this release contain critical security updates? pub is_critical: bool, /// The latest fork that this release can handle. pub fork: u64, - /// Our platform's binary, if known. + /// Our platform's binary, if known. pub binary: Option, } /// Information on our operations environment. -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq)] +#[binary] pub struct OperationsInfo { /// Our blockchain's latest fork. pub fork: u64, - /// Last fork our client supports, if known. + /// Last fork our client supports, if known. pub this_fork: Option, - /// Information on our track's latest release. + /// Information on our track's latest release. pub track: ReleaseInfo, /// Information on our minor version's latest release. pub minor: Option, } /// Information on the current version's consensus capabililty. -#[derive(Debug, Clone, Copy, PartialEq, Binary)] +#[derive(Debug, Clone, Copy, PartialEq)] +#[binary] pub enum CapState { /// Unknown. Unknown, /// Capable of consensus indefinitely. Capable, - /// Capable of consensus up until a definite block. + /// Capable of consensus up until a definite block. CapableUntil(u64), - /// Incapable of consensus since a particular block. + /// Incapable of consensus since a particular block. IncapableSince(u64), } From aba38721b18e30093e696fd3a37ae3dd846c5217 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Wed, 21 Dec 2016 15:12:40 +0100 Subject: [PATCH 10/29] Fix Secure API hangs (#3927) * Use proxy for WS in dev * Update SecureAPI * Update webpack config * Fix dev contract * Update webpack * Linting fixes * Refactor Secure API logic : Promise based, no wastes of req * Fix tests * Add try 'intitial' token --- js/package.json | 3 +- js/src/api/transport/ws/ws.js | 61 +++++-- js/src/index.js | 7 +- js/src/redux/providers/status.js | 55 ------ js/src/redux/providers/statusReducer.js | 1 - js/src/secureApi.js | 163 ++++++++---------- js/src/serviceWorker.js | 2 +- js/src/ui/BlockStatus/blockStatus.js | 10 +- js/src/views/Connection/connection.js | 32 ++-- js/src/views/WriteContract/writeContract.css | 2 + js/src/views/WriteContract/writeContract.js | 11 +- .../views/WriteContract/writeContractStore.js | 4 +- js/webpack/app.js | 40 ++++- js/webpack/dev.server.js | 10 +- js/webpack/vendor.js | 2 + 15 files changed, 218 insertions(+), 185 deletions(-) diff --git a/js/package.json b/js/package.json index df59d43d9..b98fe163b 100644 --- a/js/package.json +++ b/js/package.json @@ -117,6 +117,7 @@ "react-hot-loader": "3.0.0-beta.6", "react-intl-aggregate-webpack-plugin": "0.0.1", "rucksack-css": "0.9.1", + "script-ext-html-webpack-plugin": "1.3.4", "serviceworker-webpack-plugin": "0.1.7", "sinon": "1.17.6", "sinon-as-promised": "4.0.2", @@ -125,7 +126,7 @@ "stylelint": "7.6.0", "stylelint-config-standard": "15.0.0", "url-loader": "0.5.7", - "webpack": "2.1.0-beta.27", + "webpack": "2.2.0-rc.1", "webpack-dev-middleware": "1.8.4", "webpack-error-notification": "0.1.6", "webpack-hot-middleware": "2.13.2", diff --git a/js/src/api/transport/ws/ws.js b/js/src/api/transport/ws/ws.js index 2de500309..43f1403ce 100644 --- a/js/src/api/transport/ws/ws.js +++ b/js/src/api/transport/ws/ws.js @@ -22,7 +22,7 @@ import TransportError from '../error'; /* global WebSocket */ export default class Ws extends JsonRpcBase { - constructor (url, token) { + constructor (url, token, connect = true) { super(); this._url = url; @@ -32,23 +32,34 @@ export default class Ws extends JsonRpcBase { this._connecting = false; this._connected = false; this._lastError = null; - this._autoConnect = true; + this._autoConnect = false; this._retries = 0; this._reconnectTimeoutId = null; - this._connect(); + this._connectPromise = null; + this._connectPromiseFunctions = {}; + + if (connect) { + this.connect(); + } } - updateToken (token) { + updateToken (token, connect = true) { this._token = token; - this._autoConnect = true; + // this._autoConnect = true; - this._connect(); + if (connect) { + this.connect(); + } } - _connect () { + connect () { + if (this._connected) { + return Promise.resolve(); + } + if (this._connecting) { - return; + return this._connectPromise || Promise.resolve(); } if (this._reconnectTimeoutId) { @@ -104,10 +115,17 @@ export default class Ws extends JsonRpcBase { window._parityWS = this; } + + this._connectPromise = new Promise((resolve, reject) => { + this._connectPromiseFunctions = { resolve, reject }; + }); + + return this._connectPromise; } _onOpen = (event) => { - console.log('ws:onOpen', event); + console.log('ws:onOpen'); + this._connected = true; this._connecting = false; this._autoConnect = true; @@ -116,6 +134,11 @@ export default class Ws extends JsonRpcBase { Object.keys(this._messages) .filter((id) => this._messages[id].queued) .forEach(this._send); + + this._connectPromiseFunctions.resolve(); + + this._connectPromise = null; + this._connectPromiseFunctions = {}; } _onClose = (event) => { @@ -135,13 +158,20 @@ export default class Ws extends JsonRpcBase { console.log('ws:onClose', `trying again in ${time}...`); this._reconnectTimeoutId = setTimeout(() => { - this._connect(); + this.connect(); }, timeout); return; } - console.log('ws:onClose', event); + if (this._connectPromise) { + this._connectPromiseFunctions.reject(event); + + this._connectPromise = null; + this._connectPromiseFunctions = {}; + } + + console.log('ws:onClose'); } _onError = (event) => { @@ -149,10 +179,17 @@ export default class Ws extends JsonRpcBase { // ie. don't print if error == closed window.setTimeout(() => { if (this._connected) { - console.error('ws:onError', event); + console.error('ws:onError'); event.timestamp = Date.now(); this._lastError = event; + + if (this._connectPromise) { + this._connectPromiseFunctions.reject(event); + + this._connectPromise = null; + this._connectPromiseFunctions = {}; + } } }, 50); } diff --git a/js/src/index.js b/js/src/index.js index b90f9c61a..77f247b3b 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -52,12 +52,7 @@ if (process.env.NODE_ENV === 'development') { } const AUTH_HASH = '#/auth?'; -const parityUrl = process.env.PARITY_URL || - ( - process.env.NODE_ENV === 'production' - ? window.location.host - : '127.0.0.1:8180' - ); +const parityUrl = process.env.PARITY_URL || window.location.host; let token = null; if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) { diff --git a/js/src/redux/providers/status.js b/js/src/redux/providers/status.js index d7b360b14..ef4c09224 100644 --- a/js/src/redux/providers/status.js +++ b/js/src/redux/providers/status.js @@ -22,13 +22,11 @@ export default class Status { this._api = api; this._store = store; - this._pingable = false; this._apiStatus = {}; this._status = {}; this._longStatus = {}; this._minerSettings = {}; - this._pollPingTimeoutId = null; this._longStatusTimeoutId = null; this._timestamp = Date.now(); @@ -36,7 +34,6 @@ export default class Status { start () { this._subscribeBlockNumber(); - this._pollPing(); this._pollStatus(); this._pollLongStatus(); this._pollLogs(); @@ -65,50 +62,6 @@ export default class Status { }); } - /** - * Pinging should be smart. It should only - * be used when the UI is connecting or the - * Node is deconnected. - * - * @see src/views/Connection/connection.js - */ - _shouldPing = () => { - const { isConnected } = this._apiStatus; - return !isConnected; - } - - _stopPollPing = () => { - if (!this._pollPingTimeoutId) { - return; - } - - clearTimeout(this._pollPingTimeoutId); - this._pollPingTimeoutId = null; - } - - _pollPing = () => { - // Already pinging, don't try again - if (this._pollPingTimeoutId) { - return; - } - - const dispatch = (pingable, timeout = 1000) => { - if (pingable !== this._pingable) { - this._pingable = pingable; - this._store.dispatch(statusCollection({ isPingable: pingable })); - } - - this._pollPingTimeoutId = setTimeout(() => { - this._stopPollPing(); - this._pollPing(); - }, timeout); - }; - - fetch('/', { method: 'HEAD' }) - .then((response) => dispatch(!!response.ok)) - .catch(() => dispatch(false)); - } - _pollTraceMode = () => { return this._api.trace.block() .then(blockTraces => { @@ -137,7 +90,6 @@ export default class Status { if (gotConnected) { this._pollLongStatus(); - this._store.dispatch(statusCollection({ isPingable: true })); } if (!isEqual(apiStatus, this._apiStatus)) { @@ -145,13 +97,6 @@ export default class Status { this._apiStatus = apiStatus; } - // Ping if necessary, otherwise stop pinging - if (this._shouldPing()) { - this._pollPing(); - } else { - this._stopPollPing(); - } - if (!isConnected) { return nextTimeout(250); } diff --git a/js/src/redux/providers/statusReducer.js b/js/src/redux/providers/statusReducer.js index 413ff3319..17186b012 100644 --- a/js/src/redux/providers/statusReducer.js +++ b/js/src/redux/providers/statusReducer.js @@ -43,7 +43,6 @@ const initialState = { syncing: true, isConnected: false, isConnecting: false, - isPingable: false, isTest: undefined, refreshStatus: false, traceMode: undefined diff --git a/js/src/secureApi.js b/js/src/secureApi.js index d91a974d7..445151c69 100644 --- a/js/src/secureApi.js +++ b/js/src/secureApi.js @@ -14,35 +14,45 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import { uniq } from 'lodash'; + import Api from './api'; const sysuiToken = window.localStorage.getItem('sysuiToken'); export default class SecureApi extends Api { constructor (url, nextToken) { - super(new Api.Transport.Ws(url, sysuiToken)); + super(new Api.Transport.Ws(url, sysuiToken, false)); + this._url = url; this._isConnecting = true; - this._connectState = sysuiToken === 'initial' ? 1 : 0; this._needsToken = false; + this._dappsPort = 8080; this._dappsInterface = null; this._signerPort = 8180; - this._followConnectionTimeoutId = null; // Try tokens from localstorage, then from hash - this._tokensToTry = [ sysuiToken, nextToken ].filter((t) => t && t.length); + this._tokens = uniq([sysuiToken, nextToken, 'initial']) + .filter((token) => token) + .map((token) => ({ value: token, tried: false })); - this._followConnection(); + this._tryNextToken(); } - setToken = () => { + saveToken = () => { window.localStorage.setItem('sysuiToken', this._transport.token); - // DEBUG: console.log('SecureApi:setToken', this._transport.token); + // DEBUG: console.log('SecureApi:saveToken', this._transport.token); } + /** + * Returns a Promise that gets resolved with + * a boolean: `true` if the node is up, `false` + * otherwise + */ _checkNodeUp () { - return fetch('/', { method: 'HEAD' }) + const url = this._url.replace(/wss?/, 'http'); + return fetch(url, { method: 'HEAD' }) .then( (r) => r.status === 200, () => false @@ -50,92 +60,70 @@ export default class SecureApi extends Api { .catch(() => false); } - _followConnection = () => { - const nextTick = () => { - if (this._followConnectionTimeoutId) { - clearTimeout(this._followConnectionTimeoutId); - } + _setManual () { + this._needsToken = true; + this._isConnecting = false; + } - this._followConnectionTimeoutId = setTimeout(() => this._followConnection(), 250); - }; + _tryNextToken () { + const nextTokenIndex = this._tokens.findIndex((t) => !t.tried); - const setManual = () => { - this._connectState = 100; - this._needsToken = true; - this._isConnecting = false; - }; - - const lastError = this._transport.lastError; - const isConnected = this._transport.isConnected; - - switch (this._connectState) { - // token = - case 0: - if (isConnected) { - return this.connectSuccess(); - } else if (lastError) { - return this - ._checkNodeUp() - .then((isNodeUp) => { - const { timestamp } = lastError; - - if ((Date.now() - timestamp) > 250) { - return nextTick(); - } - - const nextToken = this._tokensToTry[0] || 'initial'; - const nextState = nextToken !== 'initial' ? 0 : 1; - - // If previous token was wrong (error while node up), delete it - if (isNodeUp) { - this._tokensToTry = this._tokensToTry.slice(1); - } - - if (nextToken !== this._transport.token) { - this.updateToken(nextToken, nextState); - } - - return nextTick(); - }); - } - break; - - // token = 'initial' - case 1: - if (isConnected) { - this.signer - .generateAuthorizationToken() - .then((token) => { - this.updateToken(token, 2); - }) - .catch((error) => { - console.error('SecureApi:generateAuthorizationToken', error); - setManual(); - }); - return; - } else if (lastError) { - return setManual(); - } - break; - - // token = - case 2: - if (isConnected) { - return this.connectSuccess(); - } else if (lastError) { - return setManual(); - } - break; + if (nextTokenIndex < 0) { + return this._setManual(); } - nextTick(); + const nextToken = this._tokens[nextTokenIndex]; + nextToken.tried = true; + + this.updateToken(nextToken.value); + } + + _followConnection = () => { + const token = this.transport.token; + + return this + .transport + .connect() + .then(() => { + if (token === 'initial') { + return this.signer + .generateAuthorizationToken() + .then((token) => { + return this.updateToken(token); + }) + .catch((e) => console.error(e)); + } + + this.connectSuccess(); + return true; + }) + .catch((e) => { + this + ._checkNodeUp() + .then((isNodeUp) => { + // Try again in a few... + if (!isNodeUp) { + this._isConnecting = false; + const timeout = this.transport.retryTimeout; + + window.setTimeout(() => { + this._followConnection(); + }, timeout); + + return; + } + + this._tryNextToken(); + return false; + }); + }); } connectSuccess () { this._isConnecting = false; this._needsToken = false; - this.setToken(); + this.saveToken(); Promise .all([ @@ -152,10 +140,9 @@ export default class SecureApi extends Api { // DEBUG: console.log('SecureApi:connectSuccess', this._transport.token); } - updateToken (token, connectState = 0) { - this._connectState = connectState; - this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, '')); - this._followConnection(); + updateToken (token) { + this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, ''), false); + return this._followConnection(); // DEBUG: console.log('SecureApi:updateToken', this._transport.token, connectState); } diff --git a/js/src/serviceWorker.js b/js/src/serviceWorker.js index c558a57cf..136e6a6b7 100644 --- a/js/src/serviceWorker.js +++ b/js/src/serviceWorker.js @@ -140,5 +140,5 @@ function getCompiler (build) { }); } - return self.solc[longVersion]; + return Promise.resolve(self.solc[longVersion]); } diff --git a/js/src/ui/BlockStatus/blockStatus.js b/js/src/ui/BlockStatus/blockStatus.js index df6f44a8c..f50c7a685 100644 --- a/js/src/ui/BlockStatus/blockStatus.js +++ b/js/src/ui/BlockStatus/blockStatus.js @@ -62,9 +62,17 @@ class BlockStatus extends Component { ); } + let syncStatus = null; + + if (syncing && syncing.currentBlock && syncing.highestBlock) { + syncStatus = ( + { syncing.currentBlock.toFormat() }/{ syncing.highestBlock.toFormat() } syncing + ); + } + return (
- { syncing.currentBlock.toFormat() }/{ syncing.highestBlock.toFormat() } syncing + { syncStatus } { warpStatus }
); diff --git a/js/src/views/Connection/connection.js b/js/src/views/Connection/connection.js index 8cc2378d9..51b0c8018 100644 --- a/js/src/views/Connection/connection.js +++ b/js/src/views/Connection/connection.js @@ -34,27 +34,26 @@ class Connection extends Component { static propTypes = { isConnected: PropTypes.bool, isConnecting: PropTypes.bool, - isPingable: PropTypes.bool, needsToken: PropTypes.bool } state = { + loading: false, token: '', validToken: false } render () { - const { isConnected, isConnecting, isPingable } = this.props; - const isOk = !isConnecting && isConnected && isPingable; + const { isConnected, needsToken } = this.props; - if (isOk) { + if (isConnected) { return null; } - const typeIcon = isPingable + const typeIcon = needsToken ? : ; - const description = isPingable + const description = needsToken ? this.renderSigner() : this.renderPing(); @@ -82,7 +81,7 @@ class Connection extends Component { } renderSigner () { - const { token, validToken } = this.state; + const { loading, token, validToken } = this.state; const { isConnecting, needsToken } = this.props; if (needsToken && !isConnecting) { @@ -93,9 +92,11 @@ class Connection extends Component { + onChange={ this.onChangeToken } + />
); @@ -117,7 +118,7 @@ class Connection extends Component { } onChangeToken = (event, token) => { - const validToken = /[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}/.test(token); + const validToken = /[a-zA-Z0-9]{4}-?[a-zA-Z0-9]{4}-?[a-zA-Z0-9]{4}-?[a-zA-Z0-9]{4}/.test(token); this.setState({ token, validToken }, () => { validToken && this.setToken(); }); @@ -127,15 +128,20 @@ class Connection extends Component { const { api } = this.context; const { token } = this.state; - api.updateToken(token, 0); - this.setState({ token: '', validToken: false }); + this.setState({ loading: true }); + + api + .updateToken(token, 0) + .then((isValid) => { + this.setState({ loading: isValid || false, validToken: isValid }); + }); } } function mapStateToProps (state) { - const { isConnected, isConnecting, isPingable, needsToken } = state.nodeStatus; + const { isConnected, isConnecting, needsToken } = state.nodeStatus; - return { isConnected, isConnecting, isPingable, needsToken }; + return { isConnected, isConnecting, needsToken }; } function mapDispatchToProps (dispatch) { diff --git a/js/src/views/WriteContract/writeContract.css b/js/src/views/WriteContract/writeContract.css index c5cefcf7a..3db18bf39 100644 --- a/js/src/views/WriteContract/writeContract.css +++ b/js/src/views/WriteContract/writeContract.css @@ -105,6 +105,8 @@ display: flex; flex-direction: column; margin-right: 0.5em; + overflow: auto; + .panel { background-color: rgba(0, 0, 0, 0.5); padding: 1em; diff --git a/js/src/views/WriteContract/writeContract.js b/js/src/views/WriteContract/writeContract.js index c95c09c04..8adb80b5a 100644 --- a/js/src/views/WriteContract/writeContract.js +++ b/js/src/views/WriteContract/writeContract.js @@ -21,6 +21,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import CircularProgress from 'material-ui/CircularProgress'; import moment from 'moment'; +import { throttle } from 'lodash'; import ContentClear from 'material-ui/svg-icons/content/clear'; import SaveIcon from 'material-ui/svg-icons/content/save'; @@ -60,6 +61,8 @@ class WriteContract extends Component { if (worker !== undefined) { this.store.setWorker(worker); } + + this.throttledResize = throttle(this.applyResize, 100, { leading: true }); } componentDidMount () { @@ -516,10 +519,16 @@ class WriteContract extends Component { const x = pageX - left; - this.setState({ size: 100 * x / width }); + this.size = 100 * x / width; + this.throttledResize(); + event.stopPropagation(); } + applyResize = () => { + this.setState({ size: this.size }); + } + } function mapStateToProps (state) { diff --git a/js/src/views/WriteContract/writeContractStore.js b/js/src/views/WriteContract/writeContractStore.js index 141569af2..a1f710f8e 100644 --- a/js/src/views/WriteContract/writeContractStore.js +++ b/js/src/views/WriteContract/writeContractStore.js @@ -288,7 +288,7 @@ export default class WriteContractStore { const build = this.builds[this.selectedBuild]; const version = build.longVersion; - const sourcecode = this.sourcecode.replace(/\n+/g, '\n').replace(/\s(\s+)/g, ' '); + const sourcecode = this.sourcecode.replace(/\s+/g, ' '); const hash = sha3(JSON.stringify({ version, sourcecode, optimize: this.optimize })); let promise = Promise.resolve(null); @@ -302,7 +302,7 @@ export default class WriteContractStore { } else { promise = this .compile({ - sourcecode: sourcecode, + sourcecode: this.sourcecode, build: build, optimize: this.optimize, files: this.files diff --git a/js/webpack/app.js b/js/webpack/app.js index df801533c..9044d470b 100644 --- a/js/webpack/app.js +++ b/js/webpack/app.js @@ -23,6 +23,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin'); +const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); const Shared = require('./shared'); const DAPPS = require('../src/dapps'); @@ -35,10 +36,13 @@ const isProd = ENV === 'production'; module.exports = { cache: !isProd, - devtool: isProd ? '#eval' : '#eval-source-map', + devtool: isProd ? '#hidden-source-map' : '#source-map', context: path.join(__dirname, '../src'), entry: Object.assign({}, Shared.dappsEntry, { + modals: './modals/index.js', + views: './views/index.js', + ui: './ui/index.js', index: './index.js' }), output: { @@ -162,13 +166,43 @@ module.exports = { filename: 'index.html', template: './index.ejs', favicon: FAVICON, - chunks: [ isProd ? null : 'commons', 'index' ] + chunks: [ + isProd ? null : 'commons', + 'common.modals', 'common.views', 'common.ui', + 'modals', 'views', 'ui', + 'index' + ] + }), + + new ScriptExtHtmlWebpackPlugin({ + sync: [ 'commons', 'vendor.js' ], + defaultAttribute: 'defer' }), new ServiceWorkerWebpackPlugin({ entry: path.join(__dirname, '../src/serviceWorker.js') }), + new webpack.optimize.CommonsChunkPlugin({ + filename: 'commons.modals.[hash:10].js', + name: 'common.modals', + minChunks: 2, + chunks: [ 'index', 'modals' ] + }), + + new webpack.optimize.CommonsChunkPlugin({ + filename: 'commons.views.[hash:10].js', + name: 'common.views', + minChunks: 2, + chunks: [ 'index', 'views' ] + }), + + new webpack.optimize.CommonsChunkPlugin({ + filename: 'commons.ui.[hash:10].js', + name: 'common.ui', + minChunks: 2 + }), + DappsHTMLInjection ); @@ -185,7 +219,7 @@ module.exports = { new webpack.optimize.CommonsChunkPlugin({ filename: 'commons.[hash:10].js', name: 'commons', - minChunks: Infinity + minChunks: 2 }) ); } diff --git a/js/webpack/dev.server.js b/js/webpack/dev.server.js index fc107488a..ccfd2026f 100644 --- a/js/webpack/dev.server.js +++ b/js/webpack/dev.server.js @@ -22,6 +22,7 @@ const webpackHotMiddleware = require('webpack-hot-middleware'); const http = require('http'); const express = require('express'); const ProgressBar = require('progress'); +const proxy = require('http-proxy-middleware'); const webpackConfig = require('./app'); const Shared = require('./shared'); @@ -33,6 +34,8 @@ let progressBar = { update: () => {} }; * and HMR to the plugins */ (function updateWebpackConfig () { + webpackConfig.performance = { hints: false }; + Object.keys(webpackConfig.entry).forEach((key) => { const entry = webpackConfig.entry[key]; @@ -81,13 +84,18 @@ app.use(webpackDevMiddleware(compiler, { } })); -app.use(express.static(webpackConfig.output.path)); +var wsProxy = proxy('ws://127.0.0.1:8180', { changeOrigin: true }); // Add the dev proxies in the express App Shared.addProxies(app); +app.use(express.static(webpackConfig.output.path)); +app.use(wsProxy); + const server = http.createServer(app); server.listen(process.env.PORT || 3000, function () { console.log('Listening on port', server.address().port); progressBar = new ProgressBar('[:bar] :percent :etas', { total: 50 }); }); + +server.on('upgrade', wsProxy.upgrade); diff --git a/js/webpack/vendor.js b/js/webpack/vendor.js index 7f1114144..daacab379 100644 --- a/js/webpack/vendor.js +++ b/js/webpack/vendor.js @@ -31,9 +31,11 @@ let modules = [ 'ethereumjs-tx', 'lodash', 'material-ui', + 'material-ui-chip-input', 'mobx', 'mobx-react', 'moment', + 'phoneformat.js', 'react', 'react-dom', 'react-redux', From 5ea70b1fd33a79c4fa1c0744965a044caff4ee11 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Wed, 21 Dec 2016 14:22:59 +0000 Subject: [PATCH 11/29] [ci skip] js-precompiled 20161221-141855 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36adce0b5..79a9fb35e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#af35fe9fa45377016ef90c55aae976fb44b35b55" +source = "git+https://github.com/ethcore/js-precompiled.git#0d99ff6eab50a33ab181ec5fef93c628297d0871" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index b98fe163b..3b3c129db 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.133", + "version": "0.2.134", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From bce69b2b0975d4e0580d95de404c44e20b10e75f Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Wed, 21 Dec 2016 19:30:49 +0100 Subject: [PATCH 12/29] Fix dApps not loading (#3935) --- js/webpack/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/webpack/app.js b/js/webpack/app.js index 9044d470b..5e68835f8 100644 --- a/js/webpack/app.js +++ b/js/webpack/app.js @@ -200,7 +200,8 @@ module.exports = { new webpack.optimize.CommonsChunkPlugin({ filename: 'commons.ui.[hash:10].js', name: 'common.ui', - minChunks: 2 + minChunks: 2, + chunks: [ 'index', 'ui' ] }), DappsHTMLInjection From 8114d50b47312235a2333810937bde0a70cb0ce6 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Wed, 21 Dec 2016 18:39:21 +0000 Subject: [PATCH 13/29] [ci skip] js-precompiled 20161221-183632 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79a9fb35e..07e581330 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#0d99ff6eab50a33ab181ec5fef93c628297d0871" +source = "git+https://github.com/ethcore/js-precompiled.git#6b69095e8110f97134a34a951673c172a3bcd4a8" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 3b3c129db..7c8fcd860 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.134", + "version": "0.2.135", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From a13135de30959e3a5bab29a6f4017c8516c4f004 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 22 Dec 2016 04:35:36 +0000 Subject: [PATCH 14/29] [ci skip] js-precompiled 20161222-043246 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07e581330..ab84566e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#6b69095e8110f97134a34a951673c172a3bcd4a8" +source = "git+https://github.com/ethcore/js-precompiled.git#2b9b86908f1c6256ec5b3e7c0634d072494939ca" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 7c8fcd860..628da4682 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.135", + "version": "0.2.136", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 70c9f7c80de6ac5109928ba28b15c6fe65d4ce7d Mon Sep 17 00:00:00 2001 From: gavinGuo <1536310027@qq.com> Date: Thu, 22 Dec 2016 14:51:25 +0800 Subject: [PATCH 15/29] Fixed compile error. --- parity/user_defaults.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/parity/user_defaults.rs b/parity/user_defaults.rs index a1078b634..6420a3074 100644 --- a/parity/user_defaults.rs +++ b/parity/user_defaults.rs @@ -77,24 +77,24 @@ impl Visitor for UserDefaultsVisitor { fn visit_map(&mut self, visitor: V) -> Result where V: MapVisitor { let mut map: BTreeMap = try!(BTreeMapVisitor::new().visit_map(visitor)); - let pruning: Value = try!(map.remove("pruning".into()).ok_or_else(|| Error::custom("missing pruning"))); + let pruning: Value = try!(map.remove("pruning").ok_or_else(|| Error::custom("missing pruning"))); let pruning = try!(pruning.as_str().ok_or_else(|| Error::custom("invalid pruning value"))); let pruning = try!(pruning.parse().map_err(|_| Error::custom("invalid pruning method"))); - let tracing: Value = try!(map.remove("tracing".into()).ok_or_else(|| Error::custom("missing tracing"))); + let tracing: Value = try!(map.remove("tracing").ok_or_else(|| Error::custom("missing tracing"))); let tracing = try!(tracing.as_bool().ok_or_else(|| Error::custom("invalid tracing value"))); - let fat_db: Value = map.remove("fat_db".into()).unwrap_or_else(|| Value::Bool(false)); + let fat_db: Value = map.remove("fat_db").unwrap_or_else(|| Value::Bool(false)); let fat_db = try!(fat_db.as_bool().ok_or_else(|| Error::custom("invalid fat_db value"))); - let mode: Value = map.remove("mode".into()).unwrap_or_else(|| Value::String("active".to_owned())); + let mode: Value = map.remove("mode").unwrap_or_else(|| Value::String("active".to_owned())); let mode = match try!(mode.as_str().ok_or_else(|| Error::custom("invalid mode value"))) { "offline" => Mode::Off, "dark" => { - let timeout = try!(map.remove("mode.timeout".into()).and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))); + let timeout = try!(map.remove("mode.timeout").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))); Mode::Dark(Duration::from_secs(timeout)) }, "passive" => { - let timeout = try!(map.remove("mode.timeout".into()).and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))); - let alarm = try!(map.remove("mode.alarm".into()).and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.alarm value"))); + let timeout = try!(map.remove("mode.timeout").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))); + let alarm = try!(map.remove("mode.alarm").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.alarm value"))); Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm)) }, "active" => Mode::Active, From be75cbfaaa36cbf5ee80d585d40896dfd72a1f8e Mon Sep 17 00:00:00 2001 From: Igor Artamonov Date: Thu, 22 Dec 2016 18:10:58 +0600 Subject: [PATCH 16/29] set CHAIN_ID for Classic (#3934) * configurable CHAIN_ID * set CHAIN_ID for Ethereum Classic --- ethcore/res/ethereum/classic.json | 1 + ethcore/res/ethereum/morden.json | 1 + ethcore/src/ethereum/ethash.rs | 4 ++-- ethcore/src/spec/spec.rs | 3 +++ json/src/spec/params.rs | 5 +++++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 223978ca4..c1879d459 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -27,6 +27,7 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", + "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f" }, diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index d21756250..2adea0f8c 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -27,6 +27,7 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2", + "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145" }, diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index feb749e9e..372ac0533 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -167,7 +167,7 @@ impl Engine for Ethash { fn signing_network_id(&self, env_info: &EnvInfo) -> Option { if env_info.number >= self.ethash_params.eip155_transition { - Some(self.params().network_id) + Some(self.params().chain_id) } else { None } @@ -316,7 +316,7 @@ impl Engine for Ethash { } if let Some(n) = t.network_id() { - if header.number() < self.ethash_params.eip155_transition || n != self.params().network_id { + if header.number() < self.ethash_params.eip155_transition || n != self.params().chain_id { return Err(TransactionError::InvalidNetworkId.into()) } } diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index bdcd5eee2..d3ba52b2e 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -38,6 +38,8 @@ pub struct CommonParams { pub maximum_extra_data_size: usize, /// Network id. pub network_id: u64, + /// Chain id. + pub chain_id: u64, /// Main subprotocol name. pub subprotocol_name: String, /// Minimum gas limit. @@ -52,6 +54,7 @@ impl From for CommonParams { account_start_nonce: p.account_start_nonce.into(), maximum_extra_data_size: p.maximum_extra_data_size.into(), network_id: p.network_id.into(), + chain_id: if let Some(n) = p.chain_id { n.into() } else { p.network_id.into() }, subprotocol_name: p.subprotocol_name.unwrap_or_else(|| "eth".to_owned()), min_gas_limit: p.min_gas_limit.into(), fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 882686319..aeda7d132 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -35,6 +35,10 @@ pub struct Params { /// Network id. #[serde(rename="networkID")] pub network_id: Uint, + /// Chain id. + #[serde(rename="chainID")] + pub chain_id: Option, + /// Name of the main ("eth") subprotocol. #[serde(rename="subprotocolName")] pub subprotocol_name: Option, @@ -58,6 +62,7 @@ mod tests { "homesteadTransition": "0x118c30", "maximumExtraDataSize": "0x20", "networkID" : "0x1", + "chainID" : "0x15", "subprotocolName" : "exp", "minGasLimit": "0x1388", "accountStartNonce": "0x00" From b444d23b3afc288a26e7621cb3e78dab31f7ba3c Mon Sep 17 00:00:00 2001 From: Paul Peregud Date: Thu, 22 Dec 2016 16:15:26 +0100 Subject: [PATCH 17/29] code example: do start before register_protocol (#3947) --- util/network/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 8d85731b0..a78199a48 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -45,8 +45,8 @@ //! //! fn main () { //! let mut service = NetworkService::new(NetworkConfiguration::new_local()).expect("Error creating network service"); -//! service.register_protocol(Arc::new(MyHandler), *b"myp", 1, &[1u8]); //! service.start().expect("Error starting service"); +//! service.register_protocol(Arc::new(MyHandler), *b"myp", 1, &[1u8]); //! //! // Wait for quit condition //! // ... From 00f4f128f2d0d4f4e0def03c02b2bf983b682daf Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 22 Dec 2016 16:33:05 +0100 Subject: [PATCH 18/29] Add missing Ethcore -> Parity headers (#3948) --- js/src/3rdparty/email-verification/index.js | 2 +- js/src/3rdparty/email-verification/terms-of-service.js | 2 +- js/src/3rdparty/etherscan/account.js | 2 +- js/src/3rdparty/etherscan/account.spec.js | 2 +- js/src/3rdparty/etherscan/call.js | 2 +- js/src/3rdparty/etherscan/index.js | 2 +- js/src/3rdparty/etherscan/links.js | 2 +- js/src/3rdparty/etherscan/stats.js | 2 +- js/src/3rdparty/etherscan/stats.spec.js | 2 +- js/src/3rdparty/shapeshift/helpers.spec.js | 2 +- js/src/3rdparty/shapeshift/index.js | 2 +- js/src/3rdparty/shapeshift/rpc.js | 2 +- js/src/3rdparty/shapeshift/rpc.spec.js | 2 +- js/src/3rdparty/shapeshift/shapeshift.js | 2 +- js/src/3rdparty/shapeshift/shapeshift.spec.js | 2 +- js/src/3rdparty/sms-verification/index.js | 2 +- js/src/3rdparty/sms-verification/terms-of-service.js | 2 +- js/src/dapps/basiccoin/AddressSelect/addressSelect.css | 2 +- js/src/dapps/basiccoin/Application/Header/header.css | 2 +- js/src/dapps/basiccoin/Application/Loading/loading.css | 2 +- js/src/dapps/basiccoin/Application/application.css | 2 +- js/src/dapps/basiccoin/Container/container.css | 2 +- js/src/dapps/basiccoin/Deploy/Deployment/deployment.css | 2 +- js/src/dapps/basiccoin/Deploy/Event/event.css | 2 +- js/src/dapps/basiccoin/Deploy/Events/events.css | 2 +- js/src/dapps/basiccoin/IdentityIcon/identityIcon.css | 2 +- js/src/dapps/basiccoin/Overview/Owner/owner.css | 2 +- js/src/dapps/basiccoin/Overview/Token/token.css | 2 +- js/src/dapps/basiccoin/Overview/overview.css | 2 +- js/src/dapps/basiccoin/Transfer/Send/send.css | 2 +- js/src/dapps/basiccoin/_form.css | 2 +- js/src/dapps/basiccoin/_status.css | 2 +- js/src/dapps/dappreg/Application/application.css | 2 +- js/src/dapps/dappreg/Button/button.css | 2 +- js/src/dapps/dappreg/ButtonBar/buttonBar.css | 2 +- js/src/dapps/dappreg/Dapp/dapp.css | 2 +- js/src/dapps/dappreg/Input/input.css | 2 +- js/src/dapps/dappreg/Modal/modal.css | 2 +- js/src/dapps/dappreg/Warning/warning.css | 2 +- js/src/dapps/githubhint/Application/application.css | 2 +- js/src/dapps/githubhint/Button/button.css | 2 +- js/src/dapps/githubhint/Events/events.css | 2 +- js/src/dapps/githubhint/IdentityIcon/identityIcon.css | 2 +- js/src/dapps/githubhint/Loading/loading.css | 2 +- js/src/dapps/registry/Accounts/accounts.css | 2 +- js/src/dapps/registry/Application/application.css | 2 +- js/src/dapps/registry/Events/events.css | 2 +- js/src/dapps/registry/IdentityIcon/identityIcon.css | 2 +- js/src/dapps/registry/Lookup/lookup.css | 2 +- js/src/dapps/registry/Names/names.css | 2 +- js/src/dapps/registry/Records/records.css | 2 +- js/src/dapps/signaturereg/Application/application.css | 2 +- js/src/dapps/signaturereg/Button/button.css | 2 +- js/src/dapps/signaturereg/Events/events.css | 2 +- js/src/dapps/signaturereg/Header/header.css | 2 +- js/src/dapps/signaturereg/IdentityIcon/identityIcon.css | 2 +- js/src/dapps/signaturereg/Import/import.css | 2 +- js/src/dapps/signaturereg/Loading/loading.css | 2 +- js/src/dapps/style.css | 2 +- .../tokenreg/Accounts/AccountSelector/account-selector.css | 2 +- js/src/dapps/tokenreg/Actions/actions.css | 2 +- js/src/dapps/tokenreg/Application/application.css | 2 +- js/src/dapps/tokenreg/Chip/chip.css | 2 +- js/src/dapps/tokenreg/IdentityIcon/identityIcon.css | 2 +- js/src/dapps/tokenreg/Inputs/inputs.css | 2 +- js/src/dapps/tokenreg/Loading/loading.css | 2 +- js/src/dapps/tokenreg/Status/status.css | 2 +- js/src/dapps/tokenreg/Tokens/Token/token.css | 2 +- js/src/dapps/tokenreg/Tokens/tokens.css | 2 +- js/src/error_pages.css | 2 +- js/src/modals/AddContract/addContract.css | 2 +- .../CreateAccount/AccountDetailsGeth/accountDetailsGeth.css | 2 +- js/src/modals/CreateAccount/NewGeth/newGeth.css | 2 +- js/src/modals/CreateAccount/createAccount.css | 2 +- js/src/modals/CreateWallet/createWallet.css | 2 +- js/src/modals/DeleteAccount/deleteAccount.css | 2 +- js/src/modals/DeployContract/deployContract.css | 2 +- js/src/modals/ExecuteContract/executeContract.css | 2 +- js/src/modals/FirstRun/TnC/tnc.css | 2 +- js/src/modals/LoadContract/loadContract.css | 2 +- js/src/modals/PasswordManager/passwordManager.css | 2 +- js/src/modals/SaveContract/saveContract.css | 2 +- js/src/modals/Shapeshift/OptionsStep/optionsStep.css | 2 +- js/src/modals/Shapeshift/Value/value.css | 2 +- js/src/modals/Shapeshift/shapeshift.css | 2 +- js/src/modals/Transfer/transfer.css | 2 +- js/src/modals/Verification/Done/done.css | 2 +- js/src/modals/Verification/GatherData/gatherData.css | 2 +- .../modals/Verification/SendConfirmation/sendConfirmation.css | 2 +- js/src/modals/Verification/SendRequest/sendRequest.css | 2 +- js/src/modals/Verification/email-store.js | 2 +- js/src/modals/Verification/how-it-works.js | 2 +- js/src/modals/Verification/index.js | 2 +- js/src/modals/Verification/sms-store.js | 2 +- js/src/modals/Verification/verification.css | 2 +- js/src/modals/WalletSettings/walletSettings.css | 2 +- js/src/reset.css | 2 +- js/src/ui/Actionbar/Import/import.css | 2 +- js/src/ui/Actionbar/Search/search.css | 2 +- js/src/ui/Actionbar/Sort/sort.css | 2 +- js/src/ui/Actionbar/actionbar.css | 2 +- js/src/ui/Badge/badge.css | 2 +- js/src/ui/Balance/balance.css | 2 +- js/src/ui/BlockStatus/blockStatus.css | 2 +- js/src/ui/Certifications/certifications.css | 2 +- js/src/ui/ConfirmDialog/confirmDialog.css | 2 +- js/src/ui/Container/Title/title.css | 2 +- js/src/ui/Container/container.css | 2 +- js/src/ui/CopyToClipboard/copyToClipboard.css | 2 +- js/src/ui/Errors/errors.css | 2 +- js/src/ui/Form/AddressSelect/addressSelect.css | 2 +- js/src/ui/Form/AutoComplete/autocomplete.css | 2 +- js/src/ui/Form/FormWrap/formWrap.css | 2 +- js/src/ui/Form/Input/input.css | 2 +- js/src/ui/Form/InputAddress/inputAddress.css | 2 +- js/src/ui/Form/InputChip/inputChip.css | 2 +- js/src/ui/Form/InputInline/inputInline.css | 2 +- js/src/ui/Form/RadioButtons/radioButtons.css | 2 +- js/src/ui/Form/TypedInput/typedInput.css | 2 +- js/src/ui/Form/form.css | 2 +- js/src/ui/GasPriceEditor/gasPriceEditor.css | 2 +- js/src/ui/GasPriceSelector/gasPriceSelector.css | 2 +- js/src/ui/IdentityIcon/identityIcon.css | 2 +- js/src/ui/Loading/loading.css | 2 +- js/src/ui/MethodDecoding/methodDecoding.css | 2 +- js/src/ui/MethodDecoding/methodDecodingStore.js | 2 +- js/src/ui/Modal/Busy/busy.css | 2 +- js/src/ui/Modal/Completed/completed.css | 2 +- js/src/ui/Modal/modal.css | 2 +- js/src/ui/Page/page.css | 2 +- js/src/ui/ShortenedHash/shortenedHash.css | 2 +- js/src/ui/Tags/tags.css | 2 +- js/src/ui/Tooltips/tooltips.css | 2 +- js/src/ui/TxHash/txHash.css | 2 +- js/src/ui/TxList/txList.css | 2 +- js/src/views/Account/Header/header.css | 2 +- js/src/views/Account/Transactions/transactions.css | 2 +- js/src/views/Account/account.css | 2 +- js/src/views/Accounts/List/list.css | 2 +- js/src/views/Accounts/accounts.css | 2 +- js/src/views/Address/address.css | 2 +- js/src/views/Addresses/addresses.css | 2 +- js/src/views/Application/FrameError/frameError.css | 2 +- js/src/views/Application/Status/status.css | 2 +- js/src/views/Application/TabBar/tabBar.css | 2 +- js/src/views/Application/application.css | 2 +- js/src/views/Connection/connection.css | 2 +- js/src/views/Contract/Queries/queries.css | 2 +- js/src/views/Contract/contract.css | 2 +- js/src/views/Dapp/dapp.css | 2 +- js/src/views/Dapps/AddDapps/AddDapps.css | 2 +- js/src/views/Dapps/Summary/summary.css | 2 +- js/src/views/Dapps/dapps.css | 2 +- js/src/views/ParityBar/parityBar.css | 2 +- js/src/views/Settings/Background/background.css | 2 +- js/src/views/Settings/Proxy/proxy.css | 2 +- js/src/views/Settings/Views/views.css | 2 +- js/src/views/Settings/layout.css | 2 +- js/src/views/Settings/settings.css | 2 +- js/src/views/Signer/_layout.css | 2 +- .../views/Signer/components/Account/AccountLink/accountLink.css | 2 +- js/src/views/Signer/components/Account/account.css | 2 +- js/src/views/Signer/components/SignRequest/signRequest.css | 2 +- .../TransactionMainDetails/transactionMainDetails.css | 2 +- .../Signer/components/TransactionPending/transactionPending.css | 2 +- .../transactionPendingFormConfirm.css | 2 +- .../transactionPendingFormReject.css | 2 +- .../TransactionPendingForm/transactionPendingForm.css | 2 +- js/src/views/Signer/containers/Embedded/embedded.css | 2 +- js/src/views/Signer/containers/RequestsPage/requestsPage.css | 2 +- js/src/views/Status/components/Call/Call.css | 2 +- js/src/views/Status/components/Calls/Calls.css | 2 +- js/src/views/Status/components/CallsToolbar/CallsToolbar.css | 2 +- js/src/views/Status/components/Debug/debug.css | 2 +- js/src/views/Status/components/EditableValue/EditableValue.css | 2 +- js/src/views/Status/components/JsonEditor/JsonEditor.css | 2 +- js/src/views/Status/components/Markdown/Markdown.css | 2 +- js/src/views/Status/components/Response/Response.css | 2 +- js/src/views/Status/components/RpcCalls/RpcCalls.css | 2 +- js/src/views/Status/components/RpcDocs/RpcDocs.css | 2 +- js/src/views/Status/components/RpcNav/RpcNav.css | 2 +- .../views/Status/components/ScrollTopButton/ScrollTopButton.css | 2 +- js/src/views/Status/components/Status/status.css | 2 +- js/src/views/Status/containers/StatusPage/statusPage.css | 2 +- js/src/views/Wallet/wallet.css | 2 +- js/src/views/WriteContract/writeContract.css | 2 +- 186 files changed, 186 insertions(+), 186 deletions(-) diff --git a/js/src/3rdparty/email-verification/index.js b/js/src/3rdparty/email-verification/index.js index 5b81f3f95..ca1b04138 100644 --- a/js/src/3rdparty/email-verification/index.js +++ b/js/src/3rdparty/email-verification/index.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/email-verification/terms-of-service.js b/js/src/3rdparty/email-verification/terms-of-service.js index 263b7e8f0..3c9b76781 100644 --- a/js/src/3rdparty/email-verification/terms-of-service.js +++ b/js/src/3rdparty/email-verification/terms-of-service.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/account.js b/js/src/3rdparty/etherscan/account.js index cb99c22c6..7b8c431a0 100644 --- a/js/src/3rdparty/etherscan/account.js +++ b/js/src/3rdparty/etherscan/account.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/account.spec.js b/js/src/3rdparty/etherscan/account.spec.js index 9dc36c254..aef48a93c 100644 --- a/js/src/3rdparty/etherscan/account.spec.js +++ b/js/src/3rdparty/etherscan/account.spec.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/call.js b/js/src/3rdparty/etherscan/call.js index 5c6cd5945..69c45a902 100644 --- a/js/src/3rdparty/etherscan/call.js +++ b/js/src/3rdparty/etherscan/call.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/index.js b/js/src/3rdparty/etherscan/index.js index ada1503cd..34b88bb68 100644 --- a/js/src/3rdparty/etherscan/index.js +++ b/js/src/3rdparty/etherscan/index.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/links.js b/js/src/3rdparty/etherscan/links.js index e85572850..158939356 100644 --- a/js/src/3rdparty/etherscan/links.js +++ b/js/src/3rdparty/etherscan/links.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/stats.js b/js/src/3rdparty/etherscan/stats.js index ecefefe7d..02a8027b2 100644 --- a/js/src/3rdparty/etherscan/stats.js +++ b/js/src/3rdparty/etherscan/stats.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/etherscan/stats.spec.js b/js/src/3rdparty/etherscan/stats.spec.js index 62152b6be..0f4d1a4a1 100644 --- a/js/src/3rdparty/etherscan/stats.spec.js +++ b/js/src/3rdparty/etherscan/stats.spec.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/shapeshift/helpers.spec.js b/js/src/3rdparty/shapeshift/helpers.spec.js index f2ea0f3f9..8ccec6791 100644 --- a/js/src/3rdparty/shapeshift/helpers.spec.js +++ b/js/src/3rdparty/shapeshift/helpers.spec.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/shapeshift/index.js b/js/src/3rdparty/shapeshift/index.js index 5dd91e4f4..a6c62320e 100644 --- a/js/src/3rdparty/shapeshift/index.js +++ b/js/src/3rdparty/shapeshift/index.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/shapeshift/rpc.js b/js/src/3rdparty/shapeshift/rpc.js index 919f0b07f..e3f1f58bd 100644 --- a/js/src/3rdparty/shapeshift/rpc.js +++ b/js/src/3rdparty/shapeshift/rpc.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/shapeshift/rpc.spec.js b/js/src/3rdparty/shapeshift/rpc.spec.js index 47d4e0052..582b77a53 100644 --- a/js/src/3rdparty/shapeshift/rpc.spec.js +++ b/js/src/3rdparty/shapeshift/rpc.spec.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/shapeshift/shapeshift.js b/js/src/3rdparty/shapeshift/shapeshift.js index 5743fcac1..39b8365ec 100644 --- a/js/src/3rdparty/shapeshift/shapeshift.js +++ b/js/src/3rdparty/shapeshift/shapeshift.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/shapeshift/shapeshift.spec.js b/js/src/3rdparty/shapeshift/shapeshift.spec.js index 01180e130..9fe2ca1f0 100644 --- a/js/src/3rdparty/shapeshift/shapeshift.spec.js +++ b/js/src/3rdparty/shapeshift/shapeshift.spec.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/sms-verification/index.js b/js/src/3rdparty/sms-verification/index.js index 65761223b..23e978972 100644 --- a/js/src/3rdparty/sms-verification/index.js +++ b/js/src/3rdparty/sms-verification/index.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/3rdparty/sms-verification/terms-of-service.js b/js/src/3rdparty/sms-verification/terms-of-service.js index f61b3c97d..d0bffb6bc 100644 --- a/js/src/3rdparty/sms-verification/terms-of-service.js +++ b/js/src/3rdparty/sms-verification/terms-of-service.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/AddressSelect/addressSelect.css b/js/src/dapps/basiccoin/AddressSelect/addressSelect.css index 818906708..5fe4b8c8d 100644 --- a/js/src/dapps/basiccoin/AddressSelect/addressSelect.css +++ b/js/src/dapps/basiccoin/AddressSelect/addressSelect.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Application/Header/header.css b/js/src/dapps/basiccoin/Application/Header/header.css index 5416d7c05..e3692f336 100644 --- a/js/src/dapps/basiccoin/Application/Header/header.css +++ b/js/src/dapps/basiccoin/Application/Header/header.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Application/Loading/loading.css b/js/src/dapps/basiccoin/Application/Loading/loading.css index 915cc77dc..4e2a7f2fa 100644 --- a/js/src/dapps/basiccoin/Application/Loading/loading.css +++ b/js/src/dapps/basiccoin/Application/Loading/loading.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Application/application.css b/js/src/dapps/basiccoin/Application/application.css index 97b66be87..abc4bf9ab 100644 --- a/js/src/dapps/basiccoin/Application/application.css +++ b/js/src/dapps/basiccoin/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Container/container.css b/js/src/dapps/basiccoin/Container/container.css index 7cc00e11e..79f362775 100644 --- a/js/src/dapps/basiccoin/Container/container.css +++ b/js/src/dapps/basiccoin/Container/container.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Deploy/Deployment/deployment.css b/js/src/dapps/basiccoin/Deploy/Deployment/deployment.css index f24729cf7..bc1e2d188 100644 --- a/js/src/dapps/basiccoin/Deploy/Deployment/deployment.css +++ b/js/src/dapps/basiccoin/Deploy/Deployment/deployment.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Deploy/Event/event.css b/js/src/dapps/basiccoin/Deploy/Event/event.css index 40768f6dc..c347a43f9 100644 --- a/js/src/dapps/basiccoin/Deploy/Event/event.css +++ b/js/src/dapps/basiccoin/Deploy/Event/event.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Deploy/Events/events.css b/js/src/dapps/basiccoin/Deploy/Events/events.css index 3cefaacb0..b57d7cda0 100644 --- a/js/src/dapps/basiccoin/Deploy/Events/events.css +++ b/js/src/dapps/basiccoin/Deploy/Events/events.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/IdentityIcon/identityIcon.css b/js/src/dapps/basiccoin/IdentityIcon/identityIcon.css index 6abbcf808..4047c0e7e 100644 --- a/js/src/dapps/basiccoin/IdentityIcon/identityIcon.css +++ b/js/src/dapps/basiccoin/IdentityIcon/identityIcon.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Overview/Owner/owner.css b/js/src/dapps/basiccoin/Overview/Owner/owner.css index f94945722..b3a30d3c0 100644 --- a/js/src/dapps/basiccoin/Overview/Owner/owner.css +++ b/js/src/dapps/basiccoin/Overview/Owner/owner.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Overview/Token/token.css b/js/src/dapps/basiccoin/Overview/Token/token.css index 5324aa7c5..311f3778b 100644 --- a/js/src/dapps/basiccoin/Overview/Token/token.css +++ b/js/src/dapps/basiccoin/Overview/Token/token.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Overview/overview.css b/js/src/dapps/basiccoin/Overview/overview.css index 9757a8145..40a666571 100644 --- a/js/src/dapps/basiccoin/Overview/overview.css +++ b/js/src/dapps/basiccoin/Overview/overview.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/Transfer/Send/send.css b/js/src/dapps/basiccoin/Transfer/Send/send.css index f24729cf7..bc1e2d188 100644 --- a/js/src/dapps/basiccoin/Transfer/Send/send.css +++ b/js/src/dapps/basiccoin/Transfer/Send/send.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/_form.css b/js/src/dapps/basiccoin/_form.css index ffafdbeaf..16ba3da45 100644 --- a/js/src/dapps/basiccoin/_form.css +++ b/js/src/dapps/basiccoin/_form.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/basiccoin/_status.css b/js/src/dapps/basiccoin/_status.css index 8fd93cfe4..18cc5d9bf 100644 --- a/js/src/dapps/basiccoin/_status.css +++ b/js/src/dapps/basiccoin/_status.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/Application/application.css b/js/src/dapps/dappreg/Application/application.css index f171d8127..da4bc1b5e 100644 --- a/js/src/dapps/dappreg/Application/application.css +++ b/js/src/dapps/dappreg/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/Button/button.css b/js/src/dapps/dappreg/Button/button.css index a66736e46..734c20ae2 100644 --- a/js/src/dapps/dappreg/Button/button.css +++ b/js/src/dapps/dappreg/Button/button.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/ButtonBar/buttonBar.css b/js/src/dapps/dappreg/ButtonBar/buttonBar.css index 0aa84ee29..e8a831225 100644 --- a/js/src/dapps/dappreg/ButtonBar/buttonBar.css +++ b/js/src/dapps/dappreg/ButtonBar/buttonBar.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/Dapp/dapp.css b/js/src/dapps/dappreg/Dapp/dapp.css index 0fef89cab..b6061da80 100644 --- a/js/src/dapps/dappreg/Dapp/dapp.css +++ b/js/src/dapps/dappreg/Dapp/dapp.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/Input/input.css b/js/src/dapps/dappreg/Input/input.css index bd453a510..390133528 100644 --- a/js/src/dapps/dappreg/Input/input.css +++ b/js/src/dapps/dappreg/Input/input.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/Modal/modal.css b/js/src/dapps/dappreg/Modal/modal.css index 9c40393b2..0fa409f56 100644 --- a/js/src/dapps/dappreg/Modal/modal.css +++ b/js/src/dapps/dappreg/Modal/modal.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/dappreg/Warning/warning.css b/js/src/dapps/dappreg/Warning/warning.css index bc1cd40d9..3114d2b64 100644 --- a/js/src/dapps/dappreg/Warning/warning.css +++ b/js/src/dapps/dappreg/Warning/warning.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/githubhint/Application/application.css b/js/src/dapps/githubhint/Application/application.css index 61929f552..15daac7c9 100644 --- a/js/src/dapps/githubhint/Application/application.css +++ b/js/src/dapps/githubhint/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/githubhint/Button/button.css b/js/src/dapps/githubhint/Button/button.css index 28519094b..94b7f97f9 100644 --- a/js/src/dapps/githubhint/Button/button.css +++ b/js/src/dapps/githubhint/Button/button.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/githubhint/Events/events.css b/js/src/dapps/githubhint/Events/events.css index a33c09236..400a291bc 100644 --- a/js/src/dapps/githubhint/Events/events.css +++ b/js/src/dapps/githubhint/Events/events.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/githubhint/IdentityIcon/identityIcon.css b/js/src/dapps/githubhint/IdentityIcon/identityIcon.css index 3fa1df99e..6e708cac3 100644 --- a/js/src/dapps/githubhint/IdentityIcon/identityIcon.css +++ b/js/src/dapps/githubhint/IdentityIcon/identityIcon.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/githubhint/Loading/loading.css b/js/src/dapps/githubhint/Loading/loading.css index b77d1a237..4885f1af2 100644 --- a/js/src/dapps/githubhint/Loading/loading.css +++ b/js/src/dapps/githubhint/Loading/loading.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/Accounts/accounts.css b/js/src/dapps/registry/Accounts/accounts.css index 344a92867..73bd9ce5f 100644 --- a/js/src/dapps/registry/Accounts/accounts.css +++ b/js/src/dapps/registry/Accounts/accounts.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/Application/application.css b/js/src/dapps/registry/Application/application.css index b46afbcf7..7b235d730 100644 --- a/js/src/dapps/registry/Application/application.css +++ b/js/src/dapps/registry/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/Events/events.css b/js/src/dapps/registry/Events/events.css index 66277dae3..58ad75c01 100644 --- a/js/src/dapps/registry/Events/events.css +++ b/js/src/dapps/registry/Events/events.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/IdentityIcon/identityIcon.css b/js/src/dapps/registry/IdentityIcon/identityIcon.css index 3fa1df99e..6e708cac3 100644 --- a/js/src/dapps/registry/IdentityIcon/identityIcon.css +++ b/js/src/dapps/registry/IdentityIcon/identityIcon.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/Lookup/lookup.css b/js/src/dapps/registry/Lookup/lookup.css index 12ddd040c..66b4dc6a3 100644 --- a/js/src/dapps/registry/Lookup/lookup.css +++ b/js/src/dapps/registry/Lookup/lookup.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/Names/names.css b/js/src/dapps/registry/Names/names.css index a058d41ac..4507e38d4 100644 --- a/js/src/dapps/registry/Names/names.css +++ b/js/src/dapps/registry/Names/names.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/registry/Records/records.css b/js/src/dapps/registry/Records/records.css index 72b62595d..a2224125a 100644 --- a/js/src/dapps/registry/Records/records.css +++ b/js/src/dapps/registry/Records/records.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/Application/application.css b/js/src/dapps/signaturereg/Application/application.css index 4675b064e..c29493deb 100644 --- a/js/src/dapps/signaturereg/Application/application.css +++ b/js/src/dapps/signaturereg/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/Button/button.css b/js/src/dapps/signaturereg/Button/button.css index 444359c79..d0b91accf 100644 --- a/js/src/dapps/signaturereg/Button/button.css +++ b/js/src/dapps/signaturereg/Button/button.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/Events/events.css b/js/src/dapps/signaturereg/Events/events.css index 5e9960e0e..ebdcfbe09 100644 --- a/js/src/dapps/signaturereg/Events/events.css +++ b/js/src/dapps/signaturereg/Events/events.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/Header/header.css b/js/src/dapps/signaturereg/Header/header.css index 8d95b959c..7d9d57b39 100644 --- a/js/src/dapps/signaturereg/Header/header.css +++ b/js/src/dapps/signaturereg/Header/header.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/IdentityIcon/identityIcon.css b/js/src/dapps/signaturereg/IdentityIcon/identityIcon.css index 3fa1df99e..6e708cac3 100644 --- a/js/src/dapps/signaturereg/IdentityIcon/identityIcon.css +++ b/js/src/dapps/signaturereg/IdentityIcon/identityIcon.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/Import/import.css b/js/src/dapps/signaturereg/Import/import.css index 8f9788c34..46b7c378e 100644 --- a/js/src/dapps/signaturereg/Import/import.css +++ b/js/src/dapps/signaturereg/Import/import.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/signaturereg/Loading/loading.css b/js/src/dapps/signaturereg/Loading/loading.css index b77d1a237..4885f1af2 100644 --- a/js/src/dapps/signaturereg/Loading/loading.css +++ b/js/src/dapps/signaturereg/Loading/loading.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/style.css b/js/src/dapps/style.css index b177a15f9..9139d3e73 100644 --- a/js/src/dapps/style.css +++ b/js/src/dapps/style.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Accounts/AccountSelector/account-selector.css b/js/src/dapps/tokenreg/Accounts/AccountSelector/account-selector.css index f6f8476bb..bf3e2809e 100644 --- a/js/src/dapps/tokenreg/Accounts/AccountSelector/account-selector.css +++ b/js/src/dapps/tokenreg/Accounts/AccountSelector/account-selector.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Actions/actions.css b/js/src/dapps/tokenreg/Actions/actions.css index d8eba57f1..187877e7c 100644 --- a/js/src/dapps/tokenreg/Actions/actions.css +++ b/js/src/dapps/tokenreg/Actions/actions.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Application/application.css b/js/src/dapps/tokenreg/Application/application.css index 94ca6302e..e01bde6e1 100644 --- a/js/src/dapps/tokenreg/Application/application.css +++ b/js/src/dapps/tokenreg/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Chip/chip.css b/js/src/dapps/tokenreg/Chip/chip.css index 5c28d56ce..4ed334135 100644 --- a/js/src/dapps/tokenreg/Chip/chip.css +++ b/js/src/dapps/tokenreg/Chip/chip.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/IdentityIcon/identityIcon.css b/js/src/dapps/tokenreg/IdentityIcon/identityIcon.css index 2b645d823..163c7531f 100644 --- a/js/src/dapps/tokenreg/IdentityIcon/identityIcon.css +++ b/js/src/dapps/tokenreg/IdentityIcon/identityIcon.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Inputs/inputs.css b/js/src/dapps/tokenreg/Inputs/inputs.css index f8bea1148..0e5e406f0 100644 --- a/js/src/dapps/tokenreg/Inputs/inputs.css +++ b/js/src/dapps/tokenreg/Inputs/inputs.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Loading/loading.css b/js/src/dapps/tokenreg/Loading/loading.css index dbdb98e42..97d16ad9b 100644 --- a/js/src/dapps/tokenreg/Loading/loading.css +++ b/js/src/dapps/tokenreg/Loading/loading.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Status/status.css b/js/src/dapps/tokenreg/Status/status.css index 7333194b7..d465ba1df 100644 --- a/js/src/dapps/tokenreg/Status/status.css +++ b/js/src/dapps/tokenreg/Status/status.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Tokens/Token/token.css b/js/src/dapps/tokenreg/Tokens/Token/token.css index cfd01e3d6..6372eb57c 100644 --- a/js/src/dapps/tokenreg/Tokens/Token/token.css +++ b/js/src/dapps/tokenreg/Tokens/Token/token.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/dapps/tokenreg/Tokens/tokens.css b/js/src/dapps/tokenreg/Tokens/tokens.css index 20aaecef4..7bb105659 100644 --- a/js/src/dapps/tokenreg/Tokens/tokens.css +++ b/js/src/dapps/tokenreg/Tokens/tokens.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/error_pages.css b/js/src/error_pages.css index 0b098d29a..eca8a506a 100644 --- a/js/src/error_pages.css +++ b/js/src/error_pages.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/AddContract/addContract.css b/js/src/modals/AddContract/addContract.css index 0821a180e..53d47c1a4 100644 --- a/js/src/modals/AddContract/addContract.css +++ b/js/src/modals/AddContract/addContract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/CreateAccount/AccountDetailsGeth/accountDetailsGeth.css b/js/src/modals/CreateAccount/AccountDetailsGeth/accountDetailsGeth.css index cee245e39..fd4da0710 100644 --- a/js/src/modals/CreateAccount/AccountDetailsGeth/accountDetailsGeth.css +++ b/js/src/modals/CreateAccount/AccountDetailsGeth/accountDetailsGeth.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/CreateAccount/NewGeth/newGeth.css b/js/src/modals/CreateAccount/NewGeth/newGeth.css index 8bf6d2cdd..94c143b03 100644 --- a/js/src/modals/CreateAccount/NewGeth/newGeth.css +++ b/js/src/modals/CreateAccount/NewGeth/newGeth.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/CreateAccount/createAccount.css b/js/src/modals/CreateAccount/createAccount.css index b87029a36..c3ce00cd1 100644 --- a/js/src/modals/CreateAccount/createAccount.css +++ b/js/src/modals/CreateAccount/createAccount.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/CreateWallet/createWallet.css b/js/src/modals/CreateWallet/createWallet.css index 01c079260..df3e221f9 100644 --- a/js/src/modals/CreateWallet/createWallet.css +++ b/js/src/modals/CreateWallet/createWallet.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/DeleteAccount/deleteAccount.css b/js/src/modals/DeleteAccount/deleteAccount.css index 9cd72c6ab..116a39346 100644 --- a/js/src/modals/DeleteAccount/deleteAccount.css +++ b/js/src/modals/DeleteAccount/deleteAccount.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/DeployContract/deployContract.css b/js/src/modals/DeployContract/deployContract.css index 90097df81..d8ebfce1f 100644 --- a/js/src/modals/DeployContract/deployContract.css +++ b/js/src/modals/DeployContract/deployContract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/ExecuteContract/executeContract.css b/js/src/modals/ExecuteContract/executeContract.css index 6b7132912..b2c6be369 100644 --- a/js/src/modals/ExecuteContract/executeContract.css +++ b/js/src/modals/ExecuteContract/executeContract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/FirstRun/TnC/tnc.css b/js/src/modals/FirstRun/TnC/tnc.css index 22643ed09..996f2340f 100644 --- a/js/src/modals/FirstRun/TnC/tnc.css +++ b/js/src/modals/FirstRun/TnC/tnc.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/LoadContract/loadContract.css b/js/src/modals/LoadContract/loadContract.css index f3144eeb8..b1d2ca6f6 100644 --- a/js/src/modals/LoadContract/loadContract.css +++ b/js/src/modals/LoadContract/loadContract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/PasswordManager/passwordManager.css b/js/src/modals/PasswordManager/passwordManager.css index f538ef546..725532bb0 100644 --- a/js/src/modals/PasswordManager/passwordManager.css +++ b/js/src/modals/PasswordManager/passwordManager.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/SaveContract/saveContract.css b/js/src/modals/SaveContract/saveContract.css index 01b8ed434..1672ea7a2 100644 --- a/js/src/modals/SaveContract/saveContract.css +++ b/js/src/modals/SaveContract/saveContract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Shapeshift/OptionsStep/optionsStep.css b/js/src/modals/Shapeshift/OptionsStep/optionsStep.css index 3433e3d7a..ab602e040 100644 --- a/js/src/modals/Shapeshift/OptionsStep/optionsStep.css +++ b/js/src/modals/Shapeshift/OptionsStep/optionsStep.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Shapeshift/Value/value.css b/js/src/modals/Shapeshift/Value/value.css index 3f4a40fd4..440bb102d 100644 --- a/js/src/modals/Shapeshift/Value/value.css +++ b/js/src/modals/Shapeshift/Value/value.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Shapeshift/shapeshift.css b/js/src/modals/Shapeshift/shapeshift.css index 2af32756a..159fbdb71 100644 --- a/js/src/modals/Shapeshift/shapeshift.css +++ b/js/src/modals/Shapeshift/shapeshift.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Transfer/transfer.css b/js/src/modals/Transfer/transfer.css index 28612f299..6e3ae9aa2 100644 --- a/js/src/modals/Transfer/transfer.css +++ b/js/src/modals/Transfer/transfer.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/Done/done.css b/js/src/modals/Verification/Done/done.css index 18c410f3e..c4ca978ae 100644 --- a/js/src/modals/Verification/Done/done.css +++ b/js/src/modals/Verification/Done/done.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/GatherData/gatherData.css b/js/src/modals/Verification/GatherData/gatherData.css index 13563b6a5..aea1aceba 100644 --- a/js/src/modals/Verification/GatherData/gatherData.css +++ b/js/src/modals/Verification/GatherData/gatherData.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/SendConfirmation/sendConfirmation.css b/js/src/modals/Verification/SendConfirmation/sendConfirmation.css index d2395f24d..adb6af159 100644 --- a/js/src/modals/Verification/SendConfirmation/sendConfirmation.css +++ b/js/src/modals/Verification/SendConfirmation/sendConfirmation.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/SendRequest/sendRequest.css b/js/src/modals/Verification/SendRequest/sendRequest.css index d2395f24d..adb6af159 100644 --- a/js/src/modals/Verification/SendRequest/sendRequest.css +++ b/js/src/modals/Verification/SendRequest/sendRequest.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/email-store.js b/js/src/modals/Verification/email-store.js index 941164b1c..a12d1968d 100644 --- a/js/src/modals/Verification/email-store.js +++ b/js/src/modals/Verification/email-store.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/how-it-works.js b/js/src/modals/Verification/how-it-works.js index 6abdc80dd..def99205a 100644 --- a/js/src/modals/Verification/how-it-works.js +++ b/js/src/modals/Verification/how-it-works.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/index.js b/js/src/modals/Verification/index.js index 9c29a7165..b9063f3bc 100644 --- a/js/src/modals/Verification/index.js +++ b/js/src/modals/Verification/index.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/sms-store.js b/js/src/modals/Verification/sms-store.js index 3c58b6ef9..7b1b859db 100644 --- a/js/src/modals/Verification/sms-store.js +++ b/js/src/modals/Verification/sms-store.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/Verification/verification.css b/js/src/modals/Verification/verification.css index 968671e63..3c8886e8e 100644 --- a/js/src/modals/Verification/verification.css +++ b/js/src/modals/Verification/verification.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/modals/WalletSettings/walletSettings.css b/js/src/modals/WalletSettings/walletSettings.css index ae52013cd..207828b18 100644 --- a/js/src/modals/WalletSettings/walletSettings.css +++ b/js/src/modals/WalletSettings/walletSettings.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/reset.css b/js/src/reset.css index b1ee22d03..c9e94e627 100644 --- a/js/src/reset.css +++ b/js/src/reset.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Actionbar/Import/import.css b/js/src/ui/Actionbar/Import/import.css index 90686ee52..5efa7d868 100644 --- a/js/src/ui/Actionbar/Import/import.css +++ b/js/src/ui/Actionbar/Import/import.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Actionbar/Search/search.css b/js/src/ui/Actionbar/Search/search.css index 956a9e2e3..c36c89a29 100644 --- a/js/src/ui/Actionbar/Search/search.css +++ b/js/src/ui/Actionbar/Search/search.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Actionbar/Sort/sort.css b/js/src/ui/Actionbar/Sort/sort.css index ff592ca2f..adc38ee71 100644 --- a/js/src/ui/Actionbar/Sort/sort.css +++ b/js/src/ui/Actionbar/Sort/sort.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Actionbar/actionbar.css b/js/src/ui/Actionbar/actionbar.css index 73c5687f4..aacc3fc39 100644 --- a/js/src/ui/Actionbar/actionbar.css +++ b/js/src/ui/Actionbar/actionbar.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Badge/badge.css b/js/src/ui/Badge/badge.css index 3653bdae8..4a5eb2c13 100644 --- a/js/src/ui/Badge/badge.css +++ b/js/src/ui/Badge/badge.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Balance/balance.css b/js/src/ui/Balance/balance.css index f36133fe6..a27904832 100644 --- a/js/src/ui/Balance/balance.css +++ b/js/src/ui/Balance/balance.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/BlockStatus/blockStatus.css b/js/src/ui/BlockStatus/blockStatus.css index ed86646f0..342354b38 100644 --- a/js/src/ui/BlockStatus/blockStatus.css +++ b/js/src/ui/BlockStatus/blockStatus.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Certifications/certifications.css b/js/src/ui/Certifications/certifications.css index bff45ce5f..6ce6ac2ae 100644 --- a/js/src/ui/Certifications/certifications.css +++ b/js/src/ui/Certifications/certifications.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/ConfirmDialog/confirmDialog.css b/js/src/ui/ConfirmDialog/confirmDialog.css index 6bb860bd3..50c44c554 100644 --- a/js/src/ui/ConfirmDialog/confirmDialog.css +++ b/js/src/ui/ConfirmDialog/confirmDialog.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Container/Title/title.css b/js/src/ui/Container/Title/title.css index e277b7b82..341c25a7f 100644 --- a/js/src/ui/Container/Title/title.css +++ b/js/src/ui/Container/Title/title.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Container/container.css b/js/src/ui/Container/container.css index d5c2ef336..b8e050b38 100644 --- a/js/src/ui/Container/container.css +++ b/js/src/ui/Container/container.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/CopyToClipboard/copyToClipboard.css b/js/src/ui/CopyToClipboard/copyToClipboard.css index 6cc8d8030..8fd1c7b39 100644 --- a/js/src/ui/CopyToClipboard/copyToClipboard.css +++ b/js/src/ui/CopyToClipboard/copyToClipboard.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Errors/errors.css b/js/src/ui/Errors/errors.css index 216993e4f..46813160e 100644 --- a/js/src/ui/Errors/errors.css +++ b/js/src/ui/Errors/errors.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/AddressSelect/addressSelect.css b/js/src/ui/Form/AddressSelect/addressSelect.css index 01bc8901d..60a6d42cf 100644 --- a/js/src/ui/Form/AddressSelect/addressSelect.css +++ b/js/src/ui/Form/AddressSelect/addressSelect.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/AutoComplete/autocomplete.css b/js/src/ui/Form/AutoComplete/autocomplete.css index 9fad53edb..e8bbabb30 100644 --- a/js/src/ui/Form/AutoComplete/autocomplete.css +++ b/js/src/ui/Form/AutoComplete/autocomplete.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/FormWrap/formWrap.css b/js/src/ui/Form/FormWrap/formWrap.css index 31a73e6ee..96c594971 100644 --- a/js/src/ui/Form/FormWrap/formWrap.css +++ b/js/src/ui/Form/FormWrap/formWrap.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/Input/input.css b/js/src/ui/Form/Input/input.css index b4d535eb9..8721047e5 100644 --- a/js/src/ui/Form/Input/input.css +++ b/js/src/ui/Form/Input/input.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/InputAddress/inputAddress.css b/js/src/ui/Form/InputAddress/inputAddress.css index 37598a759..604725ebc 100644 --- a/js/src/ui/Form/InputAddress/inputAddress.css +++ b/js/src/ui/Form/InputAddress/inputAddress.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/InputChip/inputChip.css b/js/src/ui/Form/InputChip/inputChip.css index 6d6d495e9..d66ac22f1 100644 --- a/js/src/ui/Form/InputChip/inputChip.css +++ b/js/src/ui/Form/InputChip/inputChip.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/InputInline/inputInline.css b/js/src/ui/Form/InputInline/inputInline.css index fc320a3ca..9e898d0f5 100644 --- a/js/src/ui/Form/InputInline/inputInline.css +++ b/js/src/ui/Form/InputInline/inputInline.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/RadioButtons/radioButtons.css b/js/src/ui/Form/RadioButtons/radioButtons.css index ed92a86d5..08db3e3d6 100644 --- a/js/src/ui/Form/RadioButtons/radioButtons.css +++ b/js/src/ui/Form/RadioButtons/radioButtons.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/TypedInput/typedInput.css b/js/src/ui/Form/TypedInput/typedInput.css index ab911edac..6a4410f3d 100644 --- a/js/src/ui/Form/TypedInput/typedInput.css +++ b/js/src/ui/Form/TypedInput/typedInput.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Form/form.css b/js/src/ui/Form/form.css index 4a4be1002..f4a8b8f7c 100644 --- a/js/src/ui/Form/form.css +++ b/js/src/ui/Form/form.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/GasPriceEditor/gasPriceEditor.css b/js/src/ui/GasPriceEditor/gasPriceEditor.css index bcb99a63b..80b7dd313 100644 --- a/js/src/ui/GasPriceEditor/gasPriceEditor.css +++ b/js/src/ui/GasPriceEditor/gasPriceEditor.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/GasPriceSelector/gasPriceSelector.css b/js/src/ui/GasPriceSelector/gasPriceSelector.css index ce5bd55e8..1917eeb28 100644 --- a/js/src/ui/GasPriceSelector/gasPriceSelector.css +++ b/js/src/ui/GasPriceSelector/gasPriceSelector.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/IdentityIcon/identityIcon.css b/js/src/ui/IdentityIcon/identityIcon.css index 34da4ebeb..042cbdde9 100644 --- a/js/src/ui/IdentityIcon/identityIcon.css +++ b/js/src/ui/IdentityIcon/identityIcon.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Loading/loading.css b/js/src/ui/Loading/loading.css index dbdb98e42..97d16ad9b 100644 --- a/js/src/ui/Loading/loading.css +++ b/js/src/ui/Loading/loading.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/MethodDecoding/methodDecoding.css b/js/src/ui/MethodDecoding/methodDecoding.css index 9ef8a2779..c606ab853 100644 --- a/js/src/ui/MethodDecoding/methodDecoding.css +++ b/js/src/ui/MethodDecoding/methodDecoding.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/MethodDecoding/methodDecodingStore.js b/js/src/ui/MethodDecoding/methodDecodingStore.js index 24433e541..92c6d1096 100644 --- a/js/src/ui/MethodDecoding/methodDecodingStore.js +++ b/js/src/ui/MethodDecoding/methodDecodingStore.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Ethcore (UK) Ltd. +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Modal/Busy/busy.css b/js/src/ui/Modal/Busy/busy.css index ea2cb9485..cc0465906 100644 --- a/js/src/ui/Modal/Busy/busy.css +++ b/js/src/ui/Modal/Busy/busy.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Modal/Completed/completed.css b/js/src/ui/Modal/Completed/completed.css index e843e7c66..b5cff6322 100644 --- a/js/src/ui/Modal/Completed/completed.css +++ b/js/src/ui/Modal/Completed/completed.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Modal/modal.css b/js/src/ui/Modal/modal.css index 723ddda69..1e79cb75b 100644 --- a/js/src/ui/Modal/modal.css +++ b/js/src/ui/Modal/modal.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Page/page.css b/js/src/ui/Page/page.css index 06d4f7274..185a335c0 100644 --- a/js/src/ui/Page/page.css +++ b/js/src/ui/Page/page.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/ShortenedHash/shortenedHash.css b/js/src/ui/ShortenedHash/shortenedHash.css index 7184a5fec..6743add0c 100644 --- a/js/src/ui/ShortenedHash/shortenedHash.css +++ b/js/src/ui/ShortenedHash/shortenedHash.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Tags/tags.css b/js/src/ui/Tags/tags.css index f17fd1064..ccd1d097b 100644 --- a/js/src/ui/Tags/tags.css +++ b/js/src/ui/Tags/tags.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/Tooltips/tooltips.css b/js/src/ui/Tooltips/tooltips.css index 9b63487e6..3e49b6d0a 100644 --- a/js/src/ui/Tooltips/tooltips.css +++ b/js/src/ui/Tooltips/tooltips.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/TxHash/txHash.css b/js/src/ui/TxHash/txHash.css index c5b54e351..8c73f01e7 100644 --- a/js/src/ui/TxHash/txHash.css +++ b/js/src/ui/TxHash/txHash.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/ui/TxList/txList.css b/js/src/ui/TxList/txList.css index ebe672bf8..eadf0e2ee 100644 --- a/js/src/ui/TxList/txList.css +++ b/js/src/ui/TxList/txList.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Account/Header/header.css b/js/src/views/Account/Header/header.css index 26c2a5b22..6c1527129 100644 --- a/js/src/views/Account/Header/header.css +++ b/js/src/views/Account/Header/header.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Account/Transactions/transactions.css b/js/src/views/Account/Transactions/transactions.css index 6b44d298f..de8543bb1 100644 --- a/js/src/views/Account/Transactions/transactions.css +++ b/js/src/views/Account/Transactions/transactions.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Account/account.css b/js/src/views/Account/account.css index a9a039c83..e415a3d8a 100644 --- a/js/src/views/Account/account.css +++ b/js/src/views/Account/account.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Accounts/List/list.css b/js/src/views/Accounts/List/list.css index 6c23d32e1..4caa7a69a 100644 --- a/js/src/views/Accounts/List/list.css +++ b/js/src/views/Accounts/List/list.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Accounts/accounts.css b/js/src/views/Accounts/accounts.css index 317905fd5..2a7cdcec9 100644 --- a/js/src/views/Accounts/accounts.css +++ b/js/src/views/Accounts/accounts.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Address/address.css b/js/src/views/Address/address.css index cd44688bb..1dc3dd6af 100644 --- a/js/src/views/Address/address.css +++ b/js/src/views/Address/address.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Addresses/addresses.css b/js/src/views/Addresses/addresses.css index 5bbbf8a7e..a5d27548b 100644 --- a/js/src/views/Addresses/addresses.css +++ b/js/src/views/Addresses/addresses.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Application/FrameError/frameError.css b/js/src/views/Application/FrameError/frameError.css index 0cec767ba..d8330a486 100644 --- a/js/src/views/Application/FrameError/frameError.css +++ b/js/src/views/Application/FrameError/frameError.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Application/Status/status.css b/js/src/views/Application/Status/status.css index 4eeb4b918..518411a94 100644 --- a/js/src/views/Application/Status/status.css +++ b/js/src/views/Application/Status/status.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Application/TabBar/tabBar.css b/js/src/views/Application/TabBar/tabBar.css index 172750c8f..8df18a01f 100644 --- a/js/src/views/Application/TabBar/tabBar.css +++ b/js/src/views/Application/TabBar/tabBar.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Application/application.css b/js/src/views/Application/application.css index 9d957d6c9..f30f82ce3 100644 --- a/js/src/views/Application/application.css +++ b/js/src/views/Application/application.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Connection/connection.css b/js/src/views/Connection/connection.css index 968902bfa..7e497bf44 100644 --- a/js/src/views/Connection/connection.css +++ b/js/src/views/Connection/connection.css @@ -1,4 +1,4 @@ -/* Copyright 2015; 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Contract/Queries/queries.css b/js/src/views/Contract/Queries/queries.css index 41bf00265..eabbb77ea 100644 --- a/js/src/views/Contract/Queries/queries.css +++ b/js/src/views/Contract/Queries/queries.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Contract/contract.css b/js/src/views/Contract/contract.css index f49da0831..4752fd04a 100644 --- a/js/src/views/Contract/contract.css +++ b/js/src/views/Contract/contract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Dapp/dapp.css b/js/src/views/Dapp/dapp.css index e95f9d0ae..b0f8f06e6 100644 --- a/js/src/views/Dapp/dapp.css +++ b/js/src/views/Dapp/dapp.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Dapps/AddDapps/AddDapps.css b/js/src/views/Dapps/AddDapps/AddDapps.css index be4438196..120ee0870 100644 --- a/js/src/views/Dapps/AddDapps/AddDapps.css +++ b/js/src/views/Dapps/AddDapps/AddDapps.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Dapps/Summary/summary.css b/js/src/views/Dapps/Summary/summary.css index 5390b1ea7..ba5896b75 100644 --- a/js/src/views/Dapps/Summary/summary.css +++ b/js/src/views/Dapps/Summary/summary.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Dapps/dapps.css b/js/src/views/Dapps/dapps.css index 0fb1a07b5..a3fa929b8 100644 --- a/js/src/views/Dapps/dapps.css +++ b/js/src/views/Dapps/dapps.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/ParityBar/parityBar.css b/js/src/views/ParityBar/parityBar.css index d6fd3a538..a955bd687 100644 --- a/js/src/views/ParityBar/parityBar.css +++ b/js/src/views/ParityBar/parityBar.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Settings/Background/background.css b/js/src/views/Settings/Background/background.css index 825b9fe26..2cae97f23 100644 --- a/js/src/views/Settings/Background/background.css +++ b/js/src/views/Settings/Background/background.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Settings/Proxy/proxy.css b/js/src/views/Settings/Proxy/proxy.css index 0e8d84630..2b8aa6c4f 100644 --- a/js/src/views/Settings/Proxy/proxy.css +++ b/js/src/views/Settings/Proxy/proxy.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Settings/Views/views.css b/js/src/views/Settings/Views/views.css index b907c1ab2..c643f00b3 100644 --- a/js/src/views/Settings/Views/views.css +++ b/js/src/views/Settings/Views/views.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Settings/layout.css b/js/src/views/Settings/layout.css index 18c78ee8a..69a2e035c 100644 --- a/js/src/views/Settings/layout.css +++ b/js/src/views/Settings/layout.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Settings/settings.css b/js/src/views/Settings/settings.css index 1eab3aac3..6bd7831cd 100644 --- a/js/src/views/Settings/settings.css +++ b/js/src/views/Settings/settings.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/_layout.css b/js/src/views/Signer/_layout.css index 40e5df3e8..c0001b39c 100644 --- a/js/src/views/Signer/_layout.css +++ b/js/src/views/Signer/_layout.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/Account/AccountLink/accountLink.css b/js/src/views/Signer/components/Account/AccountLink/accountLink.css index e7489895d..3936af53e 100644 --- a/js/src/views/Signer/components/Account/AccountLink/accountLink.css +++ b/js/src/views/Signer/components/Account/AccountLink/accountLink.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/Account/account.css b/js/src/views/Signer/components/Account/account.css index 3cc9a2f82..a0453b760 100644 --- a/js/src/views/Signer/components/Account/account.css +++ b/js/src/views/Signer/components/Account/account.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/SignRequest/signRequest.css b/js/src/views/Signer/components/SignRequest/signRequest.css index 4361e0626..f8c20c71e 100644 --- a/js/src/views/Signer/components/SignRequest/signRequest.css +++ b/js/src/views/Signer/components/SignRequest/signRequest.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.css b/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.css index 2a42789ea..b30d028cc 100644 --- a/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.css +++ b/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/TransactionPending/transactionPending.css b/js/src/views/Signer/components/TransactionPending/transactionPending.css index dbda27135..860718de0 100644 --- a/js/src/views/Signer/components/TransactionPending/transactionPending.css +++ b/js/src/views/Signer/components/TransactionPending/transactionPending.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormConfirm/transactionPendingFormConfirm.css b/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormConfirm/transactionPendingFormConfirm.css index 7ab5a46a6..263bb9e8b 100644 --- a/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormConfirm/transactionPendingFormConfirm.css +++ b/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormConfirm/transactionPendingFormConfirm.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormReject/transactionPendingFormReject.css b/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormReject/transactionPendingFormReject.css index 9e91456ca..6ddd200d5 100644 --- a/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormReject/transactionPendingFormReject.css +++ b/js/src/views/Signer/components/TransactionPendingForm/TransactionPendingFormReject/transactionPendingFormReject.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/components/TransactionPendingForm/transactionPendingForm.css b/js/src/views/Signer/components/TransactionPendingForm/transactionPendingForm.css index feb456bce..9431b0c4e 100644 --- a/js/src/views/Signer/components/TransactionPendingForm/transactionPendingForm.css +++ b/js/src/views/Signer/components/TransactionPendingForm/transactionPendingForm.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/containers/Embedded/embedded.css b/js/src/views/Signer/containers/Embedded/embedded.css index fcd49a851..9c3ce59fb 100644 --- a/js/src/views/Signer/containers/Embedded/embedded.css +++ b/js/src/views/Signer/containers/Embedded/embedded.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Signer/containers/RequestsPage/requestsPage.css b/js/src/views/Signer/containers/RequestsPage/requestsPage.css index f26f66e86..71cbb3f5a 100644 --- a/js/src/views/Signer/containers/RequestsPage/requestsPage.css +++ b/js/src/views/Signer/containers/RequestsPage/requestsPage.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/Call/Call.css b/js/src/views/Status/components/Call/Call.css index e9184490c..2f712ba36 100644 --- a/js/src/views/Status/components/Call/Call.css +++ b/js/src/views/Status/components/Call/Call.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/Calls/Calls.css b/js/src/views/Status/components/Calls/Calls.css index b881edda6..0ce5970d0 100644 --- a/js/src/views/Status/components/Calls/Calls.css +++ b/js/src/views/Status/components/Calls/Calls.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/CallsToolbar/CallsToolbar.css b/js/src/views/Status/components/CallsToolbar/CallsToolbar.css index 2dce82c00..15c988e5a 100644 --- a/js/src/views/Status/components/CallsToolbar/CallsToolbar.css +++ b/js/src/views/Status/components/CallsToolbar/CallsToolbar.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/Debug/debug.css b/js/src/views/Status/components/Debug/debug.css index 2199b97ce..c3584e3ca 100644 --- a/js/src/views/Status/components/Debug/debug.css +++ b/js/src/views/Status/components/Debug/debug.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/EditableValue/EditableValue.css b/js/src/views/Status/components/EditableValue/EditableValue.css index 1f617dc16..eb1fd4fc9 100644 --- a/js/src/views/Status/components/EditableValue/EditableValue.css +++ b/js/src/views/Status/components/EditableValue/EditableValue.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/JsonEditor/JsonEditor.css b/js/src/views/Status/components/JsonEditor/JsonEditor.css index 243f43a59..4650e0174 100644 --- a/js/src/views/Status/components/JsonEditor/JsonEditor.css +++ b/js/src/views/Status/components/JsonEditor/JsonEditor.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/Markdown/Markdown.css b/js/src/views/Status/components/Markdown/Markdown.css index a6a643632..201f6126e 100644 --- a/js/src/views/Status/components/Markdown/Markdown.css +++ b/js/src/views/Status/components/Markdown/Markdown.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/Response/Response.css b/js/src/views/Status/components/Response/Response.css index be93437d4..09758cdce 100644 --- a/js/src/views/Status/components/Response/Response.css +++ b/js/src/views/Status/components/Response/Response.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/RpcCalls/RpcCalls.css b/js/src/views/Status/components/RpcCalls/RpcCalls.css index d33ea3614..fb98c5d05 100644 --- a/js/src/views/Status/components/RpcCalls/RpcCalls.css +++ b/js/src/views/Status/components/RpcCalls/RpcCalls.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/RpcDocs/RpcDocs.css b/js/src/views/Status/components/RpcDocs/RpcDocs.css index 27faba6da..5bdb0b077 100644 --- a/js/src/views/Status/components/RpcDocs/RpcDocs.css +++ b/js/src/views/Status/components/RpcDocs/RpcDocs.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/RpcNav/RpcNav.css b/js/src/views/Status/components/RpcNav/RpcNav.css index 793620c4a..bb5e6af8b 100644 --- a/js/src/views/Status/components/RpcNav/RpcNav.css +++ b/js/src/views/Status/components/RpcNav/RpcNav.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/ScrollTopButton/ScrollTopButton.css b/js/src/views/Status/components/ScrollTopButton/ScrollTopButton.css index dfaf7193d..61c6a07dd 100644 --- a/js/src/views/Status/components/ScrollTopButton/ScrollTopButton.css +++ b/js/src/views/Status/components/ScrollTopButton/ScrollTopButton.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/components/Status/status.css b/js/src/views/Status/components/Status/status.css index c55179fef..05fff4d82 100644 --- a/js/src/views/Status/components/Status/status.css +++ b/js/src/views/Status/components/Status/status.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Status/containers/StatusPage/statusPage.css b/js/src/views/Status/containers/StatusPage/statusPage.css index bda975813..54f67b9c2 100644 --- a/js/src/views/Status/containers/StatusPage/statusPage.css +++ b/js/src/views/Status/containers/StatusPage/statusPage.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/Wallet/wallet.css b/js/src/views/Wallet/wallet.css index aaedb64b2..92df879f5 100644 --- a/js/src/views/Wallet/wallet.css +++ b/js/src/views/Wallet/wallet.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify diff --git a/js/src/views/WriteContract/writeContract.css b/js/src/views/WriteContract/writeContract.css index 3db18bf39..a19e98517 100644 --- a/js/src/views/WriteContract/writeContract.css +++ b/js/src/views/WriteContract/writeContract.css @@ -1,4 +1,4 @@ -/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. /* This file is part of Parity. /* /* Parity is free software: you can redistribute it and/or modify From 25f1c1dcc91929d32d2a9f3434c5fd588efcd4a2 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 22 Dec 2016 15:42:00 +0000 Subject: [PATCH 19/29] [ci skip] js-precompiled 20161222-153857 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab84566e2..20cab93c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#2b9b86908f1c6256ec5b3e7c0634d072494939ca" +source = "git+https://github.com/ethcore/js-precompiled.git#2577e145984700d6b4960e20ce672e8add3151db" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 628da4682..2ae85fbe9 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.136", + "version": "0.2.137", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 692ec9715895382bdb71c48ec1c877b6b3c568bb Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Thu, 22 Dec 2016 17:07:18 +0100 Subject: [PATCH 20/29] Update Webpack to 2.2 RC2 (#3952) --- js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/package.json b/js/package.json index 2ae85fbe9..8183b9d7b 100644 --- a/js/package.json +++ b/js/package.json @@ -126,7 +126,7 @@ "stylelint": "7.6.0", "stylelint-config-standard": "15.0.0", "url-loader": "0.5.7", - "webpack": "2.2.0-rc.1", + "webpack": "2.2.0-rc.2", "webpack-dev-middleware": "1.8.4", "webpack-error-notification": "0.1.6", "webpack-hot-middleware": "2.13.2", From 203b419080c98688837c353ad959a9de8d88b347 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 22 Dec 2016 17:21:48 +0100 Subject: [PATCH 21/29] Fix manual input token (#3945) * Fix manual input token (invalid regex) * .trim() on token * Add ^ & $ matching --- js/src/views/Connection/connection.js | 56 +++++++++++++++++++++------ 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/js/src/views/Connection/connection.js b/js/src/views/Connection/connection.js index 51b0c8018..4f2ae7b1d 100644 --- a/js/src/views/Connection/connection.js +++ b/js/src/views/Connection/connection.js @@ -15,6 +15,7 @@ // along with Parity. If not, see . import React, { Component, PropTypes } from 'react'; +import { FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import ActionCompareArrows from 'material-ui/svg-icons/action/compare-arrows'; @@ -67,7 +68,7 @@ class Connection extends Component {
- +
{ typeIcon } @@ -87,16 +88,38 @@ class Connection extends Component { if (needsToken && !isConnecting) { return (
-
Unable to make a connection to the Parity Secure API. To update your secure token or to generate a new one, run parity signer new-token and supply the token below
+
+ parity signer new-token + } } /> +
+ ) + } + hint={ + + } + label={ + + } onChange={ this.onChangeToken } - /> + value={ token } />
); @@ -104,7 +127,9 @@ class Connection extends Component { return (
- Connecting to the Parity Secure API. +
); } @@ -112,13 +137,17 @@ class Connection extends Component { renderPing () { return (
- Connecting to the Parity Node. If this informational message persists, please ensure that your Parity node is running and reachable on the network. +
); } - onChangeToken = (event, token) => { - const validToken = /[a-zA-Z0-9]{4}-?[a-zA-Z0-9]{4}-?[a-zA-Z0-9]{4}-?[a-zA-Z0-9]{4}/.test(token); + onChangeToken = (event, _token) => { + const token = _token.trim(); + const validToken = /^[a-zA-Z0-9]{4}(-)?[a-zA-Z0-9]{4}(-)?[a-zA-Z0-9]{4}(-)?[a-zA-Z0-9]{4}$/.test(token); + this.setState({ token, validToken }, () => { validToken && this.setToken(); }); @@ -133,7 +162,10 @@ class Connection extends Component { api .updateToken(token, 0) .then((isValid) => { - this.setState({ loading: isValid || false, validToken: isValid }); + this.setState({ + loading: isValid || false, + validToken: isValid + }); }); } } From 1140f9c9f82bd332759993c3a7fb4f7bf0805990 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Thu, 22 Dec 2016 17:21:59 +0100 Subject: [PATCH 22/29] Remove ui/views/modals bundles (#3946) --- js/webpack/app.js | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/js/webpack/app.js b/js/webpack/app.js index 5e68835f8..2d2d15c70 100644 --- a/js/webpack/app.js +++ b/js/webpack/app.js @@ -40,9 +40,6 @@ module.exports = { context: path.join(__dirname, '../src'), entry: Object.assign({}, Shared.dappsEntry, { - modals: './modals/index.js', - views: './views/index.js', - ui: './ui/index.js', index: './index.js' }), output: { @@ -168,8 +165,6 @@ module.exports = { favicon: FAVICON, chunks: [ isProd ? null : 'commons', - 'common.modals', 'common.views', 'common.ui', - 'modals', 'views', 'ui', 'index' ] }), @@ -183,27 +178,6 @@ module.exports = { entry: path.join(__dirname, '../src/serviceWorker.js') }), - new webpack.optimize.CommonsChunkPlugin({ - filename: 'commons.modals.[hash:10].js', - name: 'common.modals', - minChunks: 2, - chunks: [ 'index', 'modals' ] - }), - - new webpack.optimize.CommonsChunkPlugin({ - filename: 'commons.views.[hash:10].js', - name: 'common.views', - minChunks: 2, - chunks: [ 'index', 'views' ] - }), - - new webpack.optimize.CommonsChunkPlugin({ - filename: 'commons.ui.[hash:10].js', - name: 'common.ui', - minChunks: 2, - chunks: [ 'index', 'ui' ] - }), - DappsHTMLInjection ); From 7dd988860fb23c818e898c1ada0b6bad67e3a3b1 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 22 Dec 2016 16:31:24 +0000 Subject: [PATCH 23/29] [ci skip] js-precompiled 20161222-162822 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20cab93c8..5471d9dd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#2577e145984700d6b4960e20ce672e8add3151db" +source = "git+https://github.com/ethcore/js-precompiled.git#7ceaad815d78400aefcef4d7d8504f89b6ef69d5" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 8183b9d7b..c900f5163 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.137", + "version": "0.2.138", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From c2e5b78c5b63136a5b40d290a32b4daf5a60e480 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 22 Dec 2016 17:44:29 +0100 Subject: [PATCH 24/29] Update babel-loader for WebPack 2.2-rc (#3953) * Update babel loader for WebPack 2.2 * Force build --- js/package.json | 2 +- js/scripts/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/package.json b/js/package.json index c900f5163..ea7316e37 100644 --- a/js/package.json +++ b/js/package.json @@ -53,7 +53,7 @@ "babel-cli": "6.18.0", "babel-core": "6.20.0", "babel-eslint": "7.1.1", - "babel-loader": "6.2.8", + "babel-loader": "6.2.10", "babel-plugin-lodash": "3.2.10", "babel-plugin-react-intl": "2.2.0", "babel-plugin-transform-class-properties": "6.18.0", diff --git a/js/scripts/test.js b/js/scripts/test.js index 78f2f99bd..f7bfd140f 100644 --- a/js/scripts/test.js +++ b/js/scripts/test.js @@ -1 +1 @@ -// test script 6 +// test script 7 From 1645419bc86d7df72e39de9df9f12ed0f5b1fbbd Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 22 Dec 2016 16:51:32 +0000 Subject: [PATCH 25/29] [ci skip] js-precompiled 20161222-164848 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5471d9dd3..cdd232cfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#7ceaad815d78400aefcef4d7d8504f89b6ef69d5" +source = "git+https://github.com/ethcore/js-precompiled.git#be31a3bd84c692445148dc18d4ee292fd024a28b" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index ea7316e37..dbd08f6a1 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.138", + "version": "0.2.139", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From f0387c33c63b1175386d371f46a89317270b5623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 22 Dec 2016 18:26:39 +0100 Subject: [PATCH 26/29] Global Fetch Service (#3915) * Dapps web Conflicts: dapps/src/apps/fetcher.rs dapps/src/handlers/fetch.rs * Rewriting fetch * Parity-wide fetch service * Obey the limits and support cancellation. * Removing temporary files. * Actually use Fetch for dapps * Re-implementing file fetching to avoid temporary files. * Serde to 0.8.19 * Fixing content & dapps fetch --- Cargo.lock | 346 +- Cargo.toml | 3 +- dapps/Cargo.toml | 2 + dapps/src/api/api.rs | 6 +- dapps/src/apps/fetcher.rs | 445 --- dapps/src/apps/fetcher/installers.rs | 255 ++ dapps/src/apps/fetcher/mod.rs | 265 ++ dapps/src/apps/mod.rs | 15 +- dapps/src/handlers/fetch.rs | 154 +- dapps/src/lib.rs | 46 +- dapps/src/page/local.rs | 9 +- dapps/src/router/mod.rs | 6 +- dapps/src/tests/helpers.rs | 5 +- dapps/src/web.rs | 180 + hash-fetch/Cargo.toml | 8 +- hash-fetch/src/client.rs | 101 +- hash-fetch/src/lib.rs | 12 +- hash-fetch/src/urlhint.rs | 21 +- parity/dapps.rs | 8 +- parity/main.rs | 9 +- parity/rpc_apis.rs | 13 +- parity/run.rs | 33 +- rpc/Cargo.toml | 11 +- rpc/src/lib.rs | 3 + rpc/src/v1/helpers/errors.rs | 3 +- rpc/src/v1/impls/parity_set.rs | 67 +- rpc/src/v1/tests/helpers/fetch.rs | 29 +- rpc/src/v1/tests/mocked/parity_set.rs | 3 +- updater/Cargo.toml | 3 +- updater/src/lib.rs | 3 +- updater/src/updater.rs | 22 +- util/fetch/Cargo.toml | 9 +- util/fetch/src/client.rs | 277 +- util/fetch/src/fetch_file.rs | 176 - util/fetch/src/lib.rs | 10 +- util/https-fetch/examples/fetch.rs | 15 - util/https-fetch/src/ca-certificates.crt | 4496 ---------------------- util/https-fetch/src/ca-github.crt | 93 - util/https-fetch/src/client.rs | 220 -- util/https-fetch/src/http.rs | 399 -- util/https-fetch/src/lib.rs | 28 - util/https-fetch/src/tlsclient.rs | 251 -- util/https-fetch/src/url.rs | 81 - util/reactor/Cargo.toml | 11 + util/reactor/src/lib.rs | 142 + 45 files changed, 1677 insertions(+), 6617 deletions(-) delete mode 100644 dapps/src/apps/fetcher.rs create mode 100644 dapps/src/apps/fetcher/installers.rs create mode 100644 dapps/src/apps/fetcher/mod.rs create mode 100644 dapps/src/web.rs delete mode 100644 util/fetch/src/fetch_file.rs delete mode 100644 util/https-fetch/examples/fetch.rs delete mode 100644 util/https-fetch/src/ca-certificates.crt delete mode 100644 util/https-fetch/src/ca-github.crt delete mode 100644 util/https-fetch/src/client.rs delete mode 100644 util/https-fetch/src/http.rs delete mode 100644 util/https-fetch/src/lib.rs delete mode 100644 util/https-fetch/src/tlsclient.rs delete mode 100644 util/https-fetch/src/url.rs create mode 100644 util/reactor/Cargo.toml create mode 100644 util/reactor/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index cdd232cfe..864b146b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,13 +26,14 @@ dependencies = [ "ethcore-util 1.5.0", "ethsync 1.5.0", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.5.0", + "parity-reactor 0.1.0", "parity-rpc-client 1.4.0", "parity-updater 1.5.0", "regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)", @@ -42,13 +43,22 @@ dependencies = [ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "advapi32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aho-corasick" version = "0.5.1" @@ -98,11 +108,6 @@ dependencies = [ "syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "base64" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bit-set" version = "0.4.0" @@ -126,6 +131,11 @@ name = "bitflags" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "blastfig" version = "0.3.3" @@ -200,9 +210,35 @@ dependencies = [ ] [[package]] -name = "crossbeam" -version = "0.2.9" +name = "core-foundation" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crypt32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "ctrlc" @@ -281,7 +317,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -305,7 +341,7 @@ dependencies = [ "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.5.0", @@ -364,6 +400,7 @@ dependencies = [ "ethcore-rpc 1.5.0", "ethcore-util 1.5.0", "fetch 0.1.0", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)", "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)", @@ -373,10 +410,11 @@ dependencies = [ "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.5.0", + "parity-reactor 0.1.0", "parity-ui 1.5.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -396,7 +434,7 @@ dependencies = [ name = "ethcore-io" version = "1.5.0" dependencies = [ - "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.1 (git+https://github.com/ethcore/mio)", "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -531,16 +569,19 @@ dependencies = [ "ethstore 0.1.0", "ethsync 1.5.0", "fetch 0.1.0", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-macros 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-reactor 0.1.0", "parity-updater 1.5.0", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.1.0", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -637,7 +678,7 @@ version = "0.1.0" dependencies = [ "ethcore-util 1.5.0", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -670,7 +711,7 @@ dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -721,10 +762,11 @@ dependencies = [ name = "fetch" version = "0.1.0" dependencies = [ - "https-fetch 0.1.0", - "hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -744,6 +786,16 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "futures-cpupool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gcc" version = "0.3.35" @@ -752,6 +804,15 @@ dependencies = [ "rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gdi32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "glob" version = "0.2.11" @@ -783,19 +844,9 @@ name = "httparse" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "https-fetch" -version = "0.1.0" -dependencies = [ - "ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)", - "rustls 0.1.2 (git+https://github.com/ctz/rustls)", -] - [[package]] name = "hyper" -version = "0.9.10" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -803,7 +854,7 @@ dependencies = [ "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -847,7 +898,7 @@ name = "igd" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -892,7 +943,7 @@ source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec33 dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -929,7 +980,7 @@ version = "0.1.0" source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a" dependencies = [ "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1103,6 +1154,22 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miow" version = "0.1.3" @@ -1142,6 +1209,18 @@ dependencies = [ "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "native-tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "openssl 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "net2" version = "0.2.23" @@ -1276,6 +1355,14 @@ dependencies = [ "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "num_cpus" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "number_prefix" version = "0.2.5" @@ -1298,6 +1385,28 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "openssl" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "owning_ref" version = "0.2.2" @@ -1324,11 +1433,23 @@ dependencies = [ "ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-util 1.5.0", "fetch 0.1.0", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-reactor 0.1.0", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-reactor" +version = "0.1.0" +dependencies = [ + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity-rpc-client" version = "1.4.0" @@ -1342,7 +1463,7 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1386,6 +1507,7 @@ dependencies = [ "ipc-common-types 1.5.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.5.0", + "parity-reactor 0.1.0", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1444,6 +1566,11 @@ dependencies = [ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pkg-config" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "podio" version = "0.1.5" @@ -1574,12 +1701,17 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "ring" -version = "0.4.3" +name = "reqwest" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1682,16 +1814,51 @@ dependencies = [ ] [[package]] -name = "rustls" -version = "0.1.2" -source = "git+https://github.com/ctz/rustls#3d2db624997004b7b18ba4463d6081f37598b2f5" +name = "schannel" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scoped-tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "secur32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "security-framework" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "security-framework-sys" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1726,7 +1893,7 @@ dependencies = [ [[package]] name = "serde" -version = "0.8.4" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1759,7 +1926,16 @@ dependencies = [ "dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_urlencoded" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1978,6 +2154,18 @@ name = "tiny-keccak" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "tokio-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.1.28" @@ -2038,11 +2226,6 @@ name = "unicode-xid" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "untrusted" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "url" version = "1.2.0" @@ -2052,6 +2235,15 @@ dependencies = [ "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "user32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "using_queue" version = "0.1.0" @@ -2084,17 +2276,6 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "webpki" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ring 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "winapi" version = "0.2.8" @@ -2162,17 +2343,18 @@ dependencies = [ ] [metadata] +"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" "checksum aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67077478f0a03952bed2e6786338d400d40c25e9836e08ad50af96607317fd03" "checksum ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f46cd5b1d660c938e3f92dfe7a73d832b3281479363dd0cd9c1c2fbf60f7962" "checksum app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7d1c0d48a81bbb13043847f957971f4d87c81542d80ece5e84ba3cba4058fd4" "checksum arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "16e3bdb2f54b3ace0285975d59a97cf8ed3855294b2b6bc651fcf22a9c352975" "checksum aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07d344974f0a155f091948aa389fb1b912d3a58414fbdb9c8d446d193ee3496a" "checksum aster 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4df293303e8a52e1df7984ac1415e195f5fcbf51e4bb7bda54557861a3954a08" -"checksum base64 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2015e3793554aa5b6007e3a72959e84c1070039e74f13dde08fa64afe1ddd892" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" +"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum blastfig 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09640e0509d97d5cdff03a9f5daf087a8e04c735c3b113a75139634a19cfc7b2" "checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d" "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" @@ -2183,7 +2365,10 @@ dependencies = [ "checksum clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "ce96ec05bfe018a0d5d43da115e54850ea2217981ff0f2e462780ab9d594651a" "checksum cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90266f45846f14a1e986c77d1e9c2626b8c342ed806fe60241ec38cc8697b245" "checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591" -"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc" +"checksum core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20a6d0448d3a99d977ae4a2aa5a98d886a923e863e81ad9ff814645b6feb3bbd" +"checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5" +"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" +"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)" = "" "checksum daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "271ec51b7e0bee92f0d04601422c73eb76ececf197026711c97ad25038a010cf" "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" @@ -2196,14 +2381,16 @@ dependencies = [ "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" "checksum futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bad0a2ac64b227fdc10c254051ae5af542cf19c9328704fd4092f7914196897" +"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82" "checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312" +"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" "checksum heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "abb306abb8d398e053cfb1b3e7b72c2f580be048b85745c52652954f8ad1439c" "checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58" "checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae" "checksum hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)" = "" -"checksum hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "eb27e8a3e8f17ac43ffa41bbda9cf5ad3f9f13ef66fa4873409d4902310275f7" +"checksum hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb3fc65554155980167fb821d05c7c66177f92464976c0b676a19d9e03387a7" "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" "checksum igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c8c12b1795b8b168f577c45fa10379b3814dcb11b7ab702406001f0d63f40484" "checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c" @@ -2232,10 +2419,12 @@ dependencies = [ "checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" "checksum mio 0.6.0-dev (git+https://github.com/ethcore/mio?branch=timer-fix)" = "" "checksum mio 0.6.1 (git+https://github.com/ethcore/mio)" = "" +"checksum mio 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "410a1a0ff76f5a226f1e4e3ff1756128e65cd30166e39c3892283e2ac09d5b67" "checksum miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bfc6782530ac8ace97af10a540054a37126b63b0702ddaaa243b73b5745b9a" "checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8" "checksum nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)" = "" "checksum nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)" = "" +"checksum native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4e52995154bb6f0b41e4379a279482c9387c1632e3798ba4e511ef8c54ee09" "checksum net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a816012ca11cb47009693c1e0c6130e26d39e4d97ee2a13c50e868ec83e3204" "checksum nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f05c2fc965fc1cd6b73fa57fa7b89f288178737f2f3ce9e63e4a6a141189000e" "checksum nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7bb1da2be7da3cbffda73fc681d509ffd9e665af478d2bee1907cee0bc64b2" @@ -2250,9 +2439,12 @@ dependencies = [ "checksum num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "48cdcc9ff4ae2a8296805ac15af88b3d88ce62128ded0cb74ffb63a587502a84" "checksum num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "51eab148f171aefad295f8cece636fc488b9b392ef544da31ea4b8ef6b9e9c39" "checksum num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "51fedae97a05f7353612fe017ab705a37e6db8f4d67c5c6fe739a9e70d6eed09" +"checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3" "checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77" "checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" +"checksum openssl 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "12be61c7eaa23228316ff02c39807e4c1b1af84ba81420f19fd58dade304b25c" +"checksum openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d2845e841700e7b04282ceaa115407ea84e0db918ae689ad9ceb6f06fa6046bd" "checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7" "checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab" "checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "" @@ -2262,6 +2454,7 @@ dependencies = [ "checksum phf_codegen 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8af7ae7c3f75a502292b491e5cc0a1f69e3407744abe6e57e2a3b712bb82f01d" "checksum phf_generator 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "db005608fd99800c8c74106a7c894cf582055b689aa14a79462cefdcb7dc1cc3" "checksum phf_shared 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "fee4d039930e4f45123c9b15976cf93a499847b6483dc09c42ea0ec4940f2aa6" +"checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa" "checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0" "checksum primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e31b86efadeaeb1235452171a66689682783149a6249ff334a2c5d8218d00a4" "checksum primal-bit 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "464a91febc06166783d4f5ba3577b5ed8dda8e421012df80bfe48a971ed7be8f" @@ -2278,7 +2471,7 @@ dependencies = [ "checksum rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "655df67c314c30fa3055a365eae276eb88aa4f3413a352a1ab32c1320eda41ea" "checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29" "checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9" -"checksum ring 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2f6547bf9640f1d3cc4e771f82374ec8fd237c17eeb3ff5cd5ccbe22377a09" +"checksum reqwest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83186fee0d4dbeb95e610b77b05b05cf5b31703dd375222acb74c3dff4be957c" "checksum rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)" = "" "checksum rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)" = "" "checksum rotor 0.6.3 (git+https://github.com/ethcore/rotor)" = "" @@ -2287,15 +2480,20 @@ dependencies = [ "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" -"checksum rustls 0.1.2 (git+https://github.com/ctz/rustls)" = "" +"checksum schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "167852e03fcd0029c3ddebb5afb0715b2996f6e262b2c2aceaa7cd84edd4b158" +"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" +"checksum security-framework 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52186fcf3b391c9f0ccdce9a2ac708f7cc81b3f89e149b34bd9279fb1b23f9fa" +"checksum security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c84067e6297c1f09514a8666d8bbc1268817ec4a6c0f30f12f6201e1f34bd2a1" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" "checksum semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2ff60ecdb19c255841c066cbfa5f8c2a4ada1eb3ae47c77ab6667128da71f5" "checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9" -"checksum serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b1dfda9ebb31d29fa8b94d7eb3031a86a8dcec065f0fe268a30f98867bf45775" +"checksum serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)" = "58a19c0871c298847e6b68318484685cd51fa5478c0c905095647540031356e5" "checksum serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e422ae53d7933f59c6ff57e7b5870b5c9094b1f473f78ec33d89f8a692c3ec02" "checksum serde_codegen_internals 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f877e2781ed0a323295d1c9f0e26556117b5a11489fc47b1848dfb98b3173d21" "checksum serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e10f8a9d94b06cf5d3bef66475f04c8ff90950f1be7004c357ff9472ccbaebc" +"checksum serde_urlencoded 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "53d4ebaa8d1d4f90d1b63dfca81ccd98ac20e1e479dbae393cbaf60f6fecd8d8" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d" "checksum siphasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c44e42fa187b5a8782489cf7740cc27c3125806be2bf33563cf5e02e9533fcd" @@ -2323,6 +2521,7 @@ dependencies = [ "checksum thread_local 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0694f51610ef7cfac7a1b81de7f1602ee5356e76541bcd62c40e71933338cab1" "checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" "checksum tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7aef43048292ca0bae4ab32180e85f6202cf2816c2a210c396a84b99dab9270" +"checksum tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "52416b3e937abac22a543a7f1c66bd37feb60137ff1ab42390fa02df85347e58" "checksum toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "fcd27a04ca509aff336ba5eb2abc58d456f52c4ff64d9724d88acb85ead560b6" "checksum toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a442dfc13508e603c3f763274361db7f79d7469a0e95c411cde53662ab30fc72" "checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616" @@ -2332,13 +2531,12 @@ dependencies = [ "checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f" "checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172" "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" -"checksum untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5d9bc0e6e73a10975d1fbff8ac3541e221181b0d8998351600fb5523de634c0d" "checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119" +"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0795a11576d29ae80525a3fda315bf7b534f8feb9d34101e5fe63fb95bb2fd24" "checksum vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56b639f935488eb40f06d17c3e3bcc3054f6f75d264e187b1107c8d1cba8d31c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum webpki 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "813503a5985585e0812d430cd1328ee322f47f66629c8ed4ecab939cf9e92f91" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum ws 0.5.3 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)" = "" diff --git a/Cargo.toml b/Cargo.toml index 1eed33821..18ada1185 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,8 @@ rpc-cli = { path = "rpc_cli" } parity-rpc-client = { path = "rpc_client" } ethcore-light = { path = "ethcore/light" } parity-hash-fetch = { path = "hash-fetch" } -parity-updater = { path = "updater" } +parity-updater = { path = "updater" } +parity-reactor = { path = "util/reactor" } [target.'cfg(windows)'.dependencies] winapi = "0.2" diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index 75e8e346c..e7af02942 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -12,6 +12,7 @@ build = "build.rs" rand = "0.3.14" log = "0.3" env_logger = "0.3" +futures = "0.1" jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" } jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git" } hyper = { default-features = false, git = "https://github.com/ethcore/hyper" } @@ -33,6 +34,7 @@ ethcore-util = { path = "../util" } fetch = { path = "../util/fetch" } parity-ui = { path = "./ui" } parity-hash-fetch = { path = "../hash-fetch" } +parity-reactor = { path = "../util/reactor" } clippy = { version = "0.0.103", optional = true} diff --git a/dapps/src/api/api.rs b/dapps/src/api/api.rs index 440396898..fcd6d9921 100644 --- a/dapps/src/api/api.rs +++ b/dapps/src/api/api.rs @@ -23,7 +23,7 @@ use hyper::header::AccessControlAllowOrigin; use api::types::{App, ApiError}; use api::response; -use apps::fetcher::ContentFetcher; +use apps::fetcher::Fetcher; use handlers::extract_url; use endpoint::{Endpoint, Endpoints, Handler, EndpointPath}; @@ -33,11 +33,11 @@ use jsonrpc_http_server::cors; pub struct RestApi { cors_domains: Option>, endpoints: Arc, - fetcher: Arc, + fetcher: Arc, } impl RestApi { - pub fn new(cors_domains: Vec, endpoints: Arc, fetcher: Arc) -> Box { + pub fn new(cors_domains: Vec, endpoints: Arc, fetcher: Arc) -> Box { Box::new(RestApi { cors_domains: Some(cors_domains.into_iter().map(AccessControlAllowOrigin::Value).collect()), endpoints: endpoints, diff --git a/dapps/src/apps/fetcher.rs b/dapps/src/apps/fetcher.rs deleted file mode 100644 index 006858e73..000000000 --- a/dapps/src/apps/fetcher.rs +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -//! Fetchable Dapps support. -//! Manages downloaded (cached) Dapps and downloads them when necessary. -//! Uses `URLHint` to resolve addresses into Dapps bundle file location. - -use zip; -use std::{fs, env, fmt}; -use std::io::{self, Read, Write}; -use std::path::PathBuf; -use std::sync::Arc; -use rustc_serialize::hex::FromHex; -use hash_fetch::urlhint::{URLHintContract, URLHint, URLHintResult}; - -use hyper; -use hyper::status::StatusCode; - -use random_filename; -use SyncStatus; -use util::{Mutex, H256}; -use util::sha3::sha3; -use page::{LocalPageEndpoint, PageCache}; -use handlers::{ContentHandler, ContentFetcherHandler, ContentValidator}; -use endpoint::{Endpoint, EndpointPath, Handler}; -use apps::cache::{ContentCache, ContentStatus}; -use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest, serialize_manifest, Manifest}; - -/// Limit of cached dapps/content -const MAX_CACHED_DAPPS: usize = 20; - -pub struct ContentFetcher { - dapps_path: PathBuf, - resolver: R, - cache: Arc>, - sync: Arc, - embeddable_on: Option<(String, u16)>, -} - -impl Drop for ContentFetcher { - fn drop(&mut self) { - // Clear cache path - let _ = fs::remove_dir_all(&self.dapps_path); - } -} - -impl ContentFetcher { - - pub fn new(resolver: R, sync_status: Arc, embeddable_on: Option<(String, u16)>) -> Self { - let mut dapps_path = env::temp_dir(); - dapps_path.push(random_filename()); - - ContentFetcher { - dapps_path: dapps_path, - resolver: resolver, - sync: sync_status, - cache: Arc::new(Mutex::new(ContentCache::default())), - embeddable_on: embeddable_on, - } - } - - fn still_syncing(address: Option<(String, u16)>) -> Box { - Box::new(ContentHandler::error( - StatusCode::ServiceUnavailable, - "Sync In Progress", - "Your node is still syncing. We cannot resolve any content before it's fully synced.", - Some("Refresh"), - address, - )) - } - - #[cfg(test)] - fn set_status(&self, content_id: &str, status: ContentStatus) { - self.cache.lock().insert(content_id.to_owned(), status); - } - - pub fn contains(&self, content_id: &str) -> bool { - { - let mut cache = self.cache.lock(); - // Check if we already have the app - if cache.get(content_id).is_some() { - return true; - } - } - // fallback to resolver - if let Ok(content_id) = content_id.from_hex() { - // else try to resolve the app_id - let has_content = self.resolver.resolve(content_id).is_some(); - // if there is content or we are syncing return true - has_content || self.sync.is_major_importing() - } else { - false - } - } - - pub fn to_async_handler(&self, path: EndpointPath, control: hyper::Control) -> Box { - let mut cache = self.cache.lock(); - let content_id = path.app_id.clone(); - - let (new_status, handler) = { - let status = cache.get(&content_id); - match status { - // Just serve the content - Some(&mut ContentStatus::Ready(ref endpoint)) => { - (None, endpoint.to_async_handler(path, control)) - }, - // Content is already being fetched - Some(&mut ContentStatus::Fetching(ref fetch_control)) => { - trace!(target: "dapps", "Content fetching in progress. Waiting..."); - (None, fetch_control.to_async_handler(path, control)) - }, - // We need to start fetching the content - None => { - trace!(target: "dapps", "Content unavailable. Fetching... {:?}", content_id); - let content_hex = content_id.from_hex().expect("to_handler is called only when `contains` returns true."); - let content = self.resolver.resolve(content_hex); - - let cache = self.cache.clone(); - let id = content_id.clone(); - let on_done = move |result: Option| { - let mut cache = cache.lock(); - match result { - Some(endpoint) => { - cache.insert(id.clone(), ContentStatus::Ready(endpoint)); - }, - // In case of error - None => { - cache.remove(&id); - }, - } - }; - - match content { - // Don't serve dapps if we are still syncing (but serve content) - Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => { - (None, Self::still_syncing(self.embeddable_on.clone())) - }, - Some(URLHintResult::Dapp(dapp)) => { - let (handler, fetch_control) = ContentFetcherHandler::new( - dapp.url(), - path, - control, - DappInstaller { - id: content_id.clone(), - dapps_path: self.dapps_path.clone(), - on_done: Box::new(on_done), - embeddable_on: self.embeddable_on.clone(), - }, - self.embeddable_on.clone(), - ); - - (Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box) - }, - Some(URLHintResult::Content(content)) => { - let (handler, fetch_control) = ContentFetcherHandler::new( - content.url, - path, - control, - ContentInstaller { - id: content_id.clone(), - mime: content.mime, - content_path: self.dapps_path.clone(), - on_done: Box::new(on_done), - }, - self.embeddable_on.clone(), - ); - - (Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box) - }, - None if self.sync.is_major_importing() => { - (None, Self::still_syncing(self.embeddable_on.clone())) - }, - None => { - // This may happen when sync status changes in between - // `contains` and `to_handler` - (None, Box::new(ContentHandler::error( - StatusCode::NotFound, - "Resource Not Found", - "Requested resource was not found.", - None, - self.embeddable_on.clone(), - )) as Box) - }, - } - }, - } - }; - - if let Some(status) = new_status { - cache.clear_garbage(MAX_CACHED_DAPPS); - cache.insert(content_id, status); - } - - handler - } -} - -#[derive(Debug)] -pub enum ValidationError { - Io(io::Error), - Zip(zip::result::ZipError), - InvalidContentId, - ManifestNotFound, - ManifestSerialization(String), - HashMismatch { expected: H256, got: H256, }, -} - -impl fmt::Display for ValidationError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - ValidationError::Io(ref io) => write!(f, "Unexpected IO error occured: {:?}", io), - ValidationError::Zip(ref zip) => write!(f, "Unable to read ZIP archive: {:?}", zip), - ValidationError::InvalidContentId => write!(f, "ID is invalid. It should be 256 bits keccak hash of content."), - ValidationError::ManifestNotFound => write!(f, "Downloaded Dapp bundle did not contain valid manifest.json file."), - ValidationError::ManifestSerialization(ref err) => { - write!(f, "There was an error during Dapp Manifest serialization: {:?}", err) - }, - ValidationError::HashMismatch { ref expected, ref got } => { - write!(f, "Hash of downloaded content did not match. Expected:{:?}, Got:{:?}.", expected, got) - }, - } - } -} - -impl From for ValidationError { - fn from(err: io::Error) -> Self { - ValidationError::Io(err) - } -} - -impl From for ValidationError { - fn from(err: zip::result::ZipError) -> Self { - ValidationError::Zip(err) - } -} - -struct ContentInstaller { - id: String, - mime: String, - content_path: PathBuf, - on_done: Box) + Send>, -} - -impl ContentValidator for ContentInstaller { - type Error = ValidationError; - - fn validate_and_install(&self, path: PathBuf) -> Result { - let validate = || { - // Create dir - try!(fs::create_dir_all(&self.content_path)); - - // Validate hash - let mut file_reader = io::BufReader::new(try!(fs::File::open(&path))); - let hash = try!(sha3(&mut file_reader)); - let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); - if id != hash { - return Err(ValidationError::HashMismatch { - expected: id, - got: hash, - }); - } - - // And prepare path for a file - let filename = path.file_name().expect("We always fetch a file."); - let mut content_path = self.content_path.clone(); - content_path.push(&filename); - - if content_path.exists() { - try!(fs::remove_dir_all(&content_path)) - } - - try!(fs::copy(&path, &content_path)); - Ok(LocalPageEndpoint::single_file(content_path, self.mime.clone(), PageCache::Enabled)) - }; - - // Make sure to always call on_done (even in case of errors)! - let result = validate(); - (self.on_done)(result.as_ref().ok().cloned()); - result - } -} - - -struct DappInstaller { - id: String, - dapps_path: PathBuf, - on_done: Box) + Send>, - embeddable_on: Option<(String, u16)>, -} - -impl DappInstaller { - fn find_manifest(zip: &mut zip::ZipArchive) -> Result<(Manifest, PathBuf), ValidationError> { - for i in 0..zip.len() { - let mut file = try!(zip.by_index(i)); - - if !file.name().ends_with(MANIFEST_FILENAME) { - continue; - } - - // try to read manifest - let mut manifest = String::new(); - let manifest = file - .read_to_string(&mut manifest).ok() - .and_then(|_| deserialize_manifest(manifest).ok()); - - if let Some(manifest) = manifest { - let mut manifest_location = PathBuf::from(file.name()); - manifest_location.pop(); // get rid of filename - return Ok((manifest, manifest_location)); - } - } - - Err(ValidationError::ManifestNotFound) - } - - fn dapp_target_path(&self, manifest: &Manifest) -> PathBuf { - let mut target = self.dapps_path.clone(); - target.push(&manifest.id); - target - } -} - -impl ContentValidator for DappInstaller { - type Error = ValidationError; - - fn validate_and_install(&self, path: PathBuf) -> Result { - trace!(target: "dapps", "Opening dapp bundle at {:?}", path); - let validate = || { - let mut file_reader = io::BufReader::new(try!(fs::File::open(path))); - let hash = try!(sha3(&mut file_reader)); - let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); - if id != hash { - return Err(ValidationError::HashMismatch { - expected: id, - got: hash, - }); - } - let file = file_reader.into_inner(); - // Unpack archive - let mut zip = try!(zip::ZipArchive::new(file)); - // First find manifest file - let (mut manifest, manifest_dir) = try!(Self::find_manifest(&mut zip)); - // Overwrite id to match hash - manifest.id = self.id.clone(); - - let target = self.dapp_target_path(&manifest); - - // Remove old directory - if target.exists() { - warn!(target: "dapps", "Overwriting existing dapp: {}", manifest.id); - try!(fs::remove_dir_all(target.clone())); - } - - // Unpack zip - for i in 0..zip.len() { - let mut file = try!(zip.by_index(i)); - // TODO [todr] Check if it's consistent on windows. - let is_dir = file.name().chars().rev().next() == Some('/'); - - let file_path = PathBuf::from(file.name()); - let location_in_manifest_base = file_path.strip_prefix(&manifest_dir); - // Create files that are inside manifest directory - if let Ok(location_in_manifest_base) = location_in_manifest_base { - let p = target.join(location_in_manifest_base); - // Check if it's a directory - if is_dir { - try!(fs::create_dir_all(p)); - } else { - let mut target = try!(fs::File::create(p)); - try!(io::copy(&mut file, &mut target)); - } - } - } - - // Write manifest - let manifest_str = try!(serialize_manifest(&manifest).map_err(ValidationError::ManifestSerialization)); - let manifest_path = target.join(MANIFEST_FILENAME); - let mut manifest_file = try!(fs::File::create(manifest_path)); - try!(manifest_file.write_all(manifest_str.as_bytes())); - // Create endpoint - let endpoint = LocalPageEndpoint::new(target, manifest.clone().into(), PageCache::Enabled, self.embeddable_on.clone()); - Ok(endpoint) - }; - - let result = validate(); - (self.on_done)(result.as_ref().ok().cloned()); - result - } -} - -#[cfg(test)] -mod tests { - use std::env; - use std::sync::Arc; - use util::Bytes; - use hash_fetch::urlhint::{URLHint, URLHintResult}; - - use apps::cache::ContentStatus; - use endpoint::EndpointInfo; - use page::LocalPageEndpoint; - use super::ContentFetcher; - - struct FakeResolver; - impl URLHint for FakeResolver { - fn resolve(&self, _id: Bytes) -> Option { - None - } - } - - #[test] - fn should_true_if_contains_the_app() { - // given - let path = env::temp_dir(); - let fetcher = ContentFetcher::new(FakeResolver, Arc::new(|| false), None); - let handler = LocalPageEndpoint::new(path, EndpointInfo { - name: "fake".into(), - description: "".into(), - version: "".into(), - author: "".into(), - icon_url: "".into(), - }, Default::default(), None); - - // when - fetcher.set_status("test", ContentStatus::Ready(handler)); - fetcher.set_status("test2", ContentStatus::Fetching(Default::default())); - - // then - assert_eq!(fetcher.contains("test"), true); - assert_eq!(fetcher.contains("test2"), true); - assert_eq!(fetcher.contains("test3"), false); - } -} diff --git a/dapps/src/apps/fetcher/installers.rs b/dapps/src/apps/fetcher/installers.rs new file mode 100644 index 000000000..7c7517fa4 --- /dev/null +++ b/dapps/src/apps/fetcher/installers.rs @@ -0,0 +1,255 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +use zip; +use std::{fs, fmt}; +use std::io::{self, Read, Write}; +use std::path::PathBuf; +use fetch::{self, Mime}; +use util::H256; + +use util::sha3::sha3; +use page::{LocalPageEndpoint, PageCache}; +use handlers::ContentValidator; +use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest, serialize_manifest, Manifest}; + +type OnDone = Box) + Send>; + +fn write_response_and_check_hash( + id: &str, + mut content_path: PathBuf, + filename: &str, + response: fetch::Response +) -> Result<(fs::File, PathBuf), ValidationError> { + // try to parse id + let id = try!(id.parse().map_err(|_| ValidationError::InvalidContentId)); + + // check if content exists + if content_path.exists() { + warn!(target: "dapps", "Overwriting existing content at 0x{:?}", id); + try!(fs::remove_dir_all(&content_path)) + } + + // create directory + try!(fs::create_dir_all(&content_path)); + + // append filename + content_path.push(filename); + + // Now write the response + let mut file = io::BufWriter::new(try!(fs::File::create(&content_path))); + let mut reader = io::BufReader::new(response); + try!(io::copy(&mut reader, &mut file)); + try!(file.flush()); + + // Validate hash + // TODO [ToDr] calculate sha3 in-flight while reading the response + let mut file = io::BufReader::new(try!(fs::File::open(&content_path))); + let hash = try!(sha3(&mut file)); + if id == hash { + Ok((file.into_inner(), content_path)) + } else { + Err(ValidationError::HashMismatch { + expected: id, + got: hash, + }) + } +} + +pub struct Content { + id: String, + mime: Mime, + content_path: PathBuf, + on_done: OnDone, +} + +impl Content { + pub fn new(id: String, mime: Mime, content_path: PathBuf, on_done: OnDone) -> Self { + Content { + id: id, + mime: mime, + content_path: content_path, + on_done: on_done, + } + } +} + +impl ContentValidator for Content { + type Error = ValidationError; + + fn validate_and_install(&self, response: fetch::Response) -> Result { + let validate = |content_path: PathBuf| { + // Create dir + let (_, content_path) = try!(write_response_and_check_hash(self.id.as_str(), content_path.clone(), self.id.as_str(), response)); + + Ok(LocalPageEndpoint::single_file(content_path, self.mime.clone(), PageCache::Enabled)) + }; + + // Prepare path for a file + let content_path = self.content_path.join(&self.id); + // Make sure to always call on_done (even in case of errors)! + let result = validate(content_path.clone()); + // remove the file if there was an error + if result.is_err() { + // Ignore errors since the file might not exist + let _ = fs::remove_dir_all(&content_path); + } + (self.on_done)(result.as_ref().ok().cloned()); + result + } +} + +pub struct Dapp { + id: String, + dapps_path: PathBuf, + on_done: OnDone, + embeddable_on: Option<(String, u16)>, +} + +impl Dapp { + pub fn new(id: String, dapps_path: PathBuf, on_done: OnDone, embeddable_on: Option<(String, u16)>) -> Self { + Dapp { + id: id, + dapps_path: dapps_path, + on_done: on_done, + embeddable_on: embeddable_on, + } + } + + fn find_manifest(zip: &mut zip::ZipArchive) -> Result<(Manifest, PathBuf), ValidationError> { + for i in 0..zip.len() { + let mut file = try!(zip.by_index(i)); + + if !file.name().ends_with(MANIFEST_FILENAME) { + continue; + } + + // try to read manifest + let mut manifest = String::new(); + let manifest = file + .read_to_string(&mut manifest).ok() + .and_then(|_| deserialize_manifest(manifest).ok()); + + if let Some(manifest) = manifest { + let mut manifest_location = PathBuf::from(file.name()); + manifest_location.pop(); // get rid of filename + return Ok((manifest, manifest_location)); + } + } + + Err(ValidationError::ManifestNotFound) + } +} + +impl ContentValidator for Dapp { + type Error = ValidationError; + + fn validate_and_install(&self, response: fetch::Response) -> Result { + let validate = |dapp_path: PathBuf| { + let (file, zip_path) = try!(write_response_and_check_hash(self.id.as_str(), dapp_path.clone(), &format!("{}.zip", self.id), response)); + trace!(target: "dapps", "Opening dapp bundle at {:?}", zip_path); + // Unpack archive + let mut zip = try!(zip::ZipArchive::new(file)); + // First find manifest file + let (mut manifest, manifest_dir) = try!(Self::find_manifest(&mut zip)); + // Overwrite id to match hash + manifest.id = self.id.clone(); + + // Unpack zip + for i in 0..zip.len() { + let mut file = try!(zip.by_index(i)); + let is_dir = file.name().chars().rev().next() == Some('/'); + + let file_path = PathBuf::from(file.name()); + let location_in_manifest_base = file_path.strip_prefix(&manifest_dir); + // Create files that are inside manifest directory + if let Ok(location_in_manifest_base) = location_in_manifest_base { + let p = dapp_path.join(location_in_manifest_base); + // Check if it's a directory + if is_dir { + try!(fs::create_dir_all(p)); + } else { + let mut target = try!(fs::File::create(p)); + try!(io::copy(&mut file, &mut target)); + } + } + } + + // Remove zip + try!(fs::remove_file(&zip_path)); + + // Write manifest + let manifest_str = try!(serialize_manifest(&manifest).map_err(ValidationError::ManifestSerialization)); + let manifest_path = dapp_path.join(MANIFEST_FILENAME); + let mut manifest_file = try!(fs::File::create(manifest_path)); + try!(manifest_file.write_all(manifest_str.as_bytes())); + // Create endpoint + let endpoint = LocalPageEndpoint::new(dapp_path, manifest.clone().into(), PageCache::Enabled, self.embeddable_on.clone()); + Ok(endpoint) + }; + + // Prepare directory for dapp + let target = self.dapps_path.join(&self.id); + // Validate the dapp + let result = validate(target.clone()); + // remove the file if there was an error + if result.is_err() { + // Ignore errors since the file might not exist + let _ = fs::remove_dir_all(&target); + } + (self.on_done)(result.as_ref().ok().cloned()); + result + } +} + +#[derive(Debug)] +pub enum ValidationError { + Io(io::Error), + Zip(zip::result::ZipError), + InvalidContentId, + ManifestNotFound, + ManifestSerialization(String), + HashMismatch { expected: H256, got: H256, }, +} + +impl fmt::Display for ValidationError { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self { + ValidationError::Io(ref io) => write!(f, "Unexpected IO error occured: {:?}", io), + ValidationError::Zip(ref zip) => write!(f, "Unable to read ZIP archive: {:?}", zip), + ValidationError::InvalidContentId => write!(f, "ID is invalid. It should be 256 bits keccak hash of content."), + ValidationError::ManifestNotFound => write!(f, "Downloaded Dapp bundle did not contain valid manifest.json file."), + ValidationError::ManifestSerialization(ref err) => { + write!(f, "There was an error during Dapp Manifest serialization: {:?}", err) + }, + ValidationError::HashMismatch { ref expected, ref got } => { + write!(f, "Hash of downloaded content did not match. Expected:{:?}, Got:{:?}.", expected, got) + }, + } + } +} + +impl From for ValidationError { + fn from(err: io::Error) -> Self { + ValidationError::Io(err) + } +} + +impl From for ValidationError { + fn from(err: zip::result::ZipError) -> Self { + ValidationError::Zip(err) + } +} diff --git a/dapps/src/apps/fetcher/mod.rs b/dapps/src/apps/fetcher/mod.rs new file mode 100644 index 000000000..f28bc1ff2 --- /dev/null +++ b/dapps/src/apps/fetcher/mod.rs @@ -0,0 +1,265 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Fetchable Dapps support. +//! Manages downloaded (cached) Dapps and downloads them when necessary. +//! Uses `URLHint` to resolve addresses into Dapps bundle file location. + +mod installers; + +use std::{fs, env}; +use std::path::PathBuf; +use std::sync::Arc; +use rustc_serialize::hex::FromHex; +use fetch::{Client as FetchClient, Fetch}; +use hash_fetch::urlhint::{URLHintContract, URLHint, URLHintResult}; +use parity_reactor::Remote; + +use hyper; +use hyper::status::StatusCode; + +use {SyncStatus, random_filename}; +use util::Mutex; +use page::LocalPageEndpoint; +use handlers::{ContentHandler, ContentFetcherHandler}; +use endpoint::{Endpoint, EndpointPath, Handler}; +use apps::cache::{ContentCache, ContentStatus}; + +/// Limit of cached dapps/content +const MAX_CACHED_DAPPS: usize = 20; + +pub trait Fetcher: Send + Sync + 'static { + fn contains(&self, content_id: &str) -> bool; + + fn to_async_handler(&self, path: EndpointPath, control: hyper::Control) -> Box; +} + +pub struct ContentFetcher { + dapps_path: PathBuf, + resolver: R, + cache: Arc>, + sync: Arc, + embeddable_on: Option<(String, u16)>, + remote: Remote, + fetch: F, +} + +impl Drop for ContentFetcher { + fn drop(&mut self) { + // Clear cache path + let _ = fs::remove_dir_all(&self.dapps_path); + } +} + +impl ContentFetcher { + + pub fn new(resolver: R, sync_status: Arc, embeddable_on: Option<(String, u16)>, remote: Remote, fetch: F) -> Self { + let mut dapps_path = env::temp_dir(); + dapps_path.push(random_filename()); + + ContentFetcher { + dapps_path: dapps_path, + resolver: resolver, + sync: sync_status, + cache: Arc::new(Mutex::new(ContentCache::default())), + embeddable_on: embeddable_on, + remote: remote, + fetch: fetch, + } + } + + fn still_syncing(address: Option<(String, u16)>) -> Box { + Box::new(ContentHandler::error( + StatusCode::ServiceUnavailable, + "Sync In Progress", + "Your node is still syncing. We cannot resolve any content before it's fully synced.", + Some("Refresh"), + address, + )) + } + + #[cfg(test)] + fn set_status(&self, content_id: &str, status: ContentStatus) { + self.cache.lock().insert(content_id.to_owned(), status); + } +} + +impl Fetcher for ContentFetcher { + fn contains(&self, content_id: &str) -> bool { + { + let mut cache = self.cache.lock(); + // Check if we already have the app + if cache.get(content_id).is_some() { + return true; + } + } + // fallback to resolver + if let Ok(content_id) = content_id.from_hex() { + // else try to resolve the app_id + let has_content = self.resolver.resolve(content_id).is_some(); + // if there is content or we are syncing return true + has_content || self.sync.is_major_importing() + } else { + false + } + } + + fn to_async_handler(&self, path: EndpointPath, control: hyper::Control) -> Box { + let mut cache = self.cache.lock(); + let content_id = path.app_id.clone(); + + let (new_status, handler) = { + let status = cache.get(&content_id); + match status { + // Just serve the content + Some(&mut ContentStatus::Ready(ref endpoint)) => { + (None, endpoint.to_async_handler(path, control)) + }, + // Content is already being fetched + Some(&mut ContentStatus::Fetching(ref fetch_control)) => { + trace!(target: "dapps", "Content fetching in progress. Waiting..."); + (None, fetch_control.to_async_handler(path, control)) + }, + // We need to start fetching the content + None => { + trace!(target: "dapps", "Content unavailable. Fetching... {:?}", content_id); + let content_hex = content_id.from_hex().expect("to_handler is called only when `contains` returns true."); + let content = self.resolver.resolve(content_hex); + + let cache = self.cache.clone(); + let id = content_id.clone(); + let on_done = move |result: Option| { + let mut cache = cache.lock(); + match result { + Some(endpoint) => cache.insert(id.clone(), ContentStatus::Ready(endpoint)), + // In case of error + None => cache.remove(&id), + }; + }; + + match content { + // Don't serve dapps if we are still syncing (but serve content) + Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => { + (None, Self::still_syncing(self.embeddable_on.clone())) + }, + Some(URLHintResult::Dapp(dapp)) => { + let (handler, fetch_control) = ContentFetcherHandler::new( + dapp.url(), + path, + control, + installers::Dapp::new( + content_id.clone(), + self.dapps_path.clone(), + Box::new(on_done), + self.embeddable_on.clone(), + ), + self.embeddable_on.clone(), + self.remote.clone(), + self.fetch.clone(), + ); + + (Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box) + }, + Some(URLHintResult::Content(content)) => { + let (handler, fetch_control) = ContentFetcherHandler::new( + content.url, + path, + control, + installers::Content::new( + content_id.clone(), + content.mime, + self.dapps_path.clone(), + Box::new(on_done), + ), + self.embeddable_on.clone(), + self.remote.clone(), + self.fetch.clone(), + ); + + (Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box) + }, + None if self.sync.is_major_importing() => { + (None, Self::still_syncing(self.embeddable_on.clone())) + }, + None => { + // This may happen when sync status changes in between + // `contains` and `to_handler` + (None, Box::new(ContentHandler::error( + StatusCode::NotFound, + "Resource Not Found", + "Requested resource was not found.", + None, + self.embeddable_on.clone(), + )) as Box) + }, + } + }, + } + }; + + if let Some(status) = new_status { + cache.clear_garbage(MAX_CACHED_DAPPS); + cache.insert(content_id, status); + } + + handler + } +} + +#[cfg(test)] +mod tests { + use std::env; + use std::sync::Arc; + use util::Bytes; + use fetch::Client; + use hash_fetch::urlhint::{URLHint, URLHintResult}; + use parity_reactor::Remote; + + use apps::cache::ContentStatus; + use endpoint::EndpointInfo; + use page::LocalPageEndpoint; + use super::{ContentFetcher, Fetcher}; + + struct FakeResolver; + impl URLHint for FakeResolver { + fn resolve(&self, _id: Bytes) -> Option { + None + } + } + + #[test] + fn should_true_if_contains_the_app() { + // given + let path = env::temp_dir(); + let fetcher = ContentFetcher::new(FakeResolver, Arc::new(|| false), None, Remote::new_sync(), Client::new().unwrap()); + let handler = LocalPageEndpoint::new(path, EndpointInfo { + name: "fake".into(), + description: "".into(), + version: "".into(), + author: "".into(), + icon_url: "".into(), + }, Default::default(), None); + + // when + fetcher.set_status("test", ContentStatus::Ready(handler)); + fetcher.set_status("test2", ContentStatus::Fetching(Default::default())); + + // then + assert_eq!(fetcher.contains("test"), true); + assert_eq!(fetcher.contains("test2"), true); + assert_eq!(fetcher.contains("test3"), false); + } +} diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 3f3b1aaba..27da43f8d 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -17,7 +17,10 @@ use endpoint::{Endpoints, Endpoint}; use page::PageEndpoint; use proxypac::ProxyPac; +use web::Web; +use fetch::Fetch; use parity_dapps::WebApp; +use parity_reactor::Remote; mod cache; mod fs; @@ -27,22 +30,24 @@ pub mod manifest; extern crate parity_ui; pub const HOME_PAGE: &'static str = "home"; -pub const DAPPS_DOMAIN : &'static str = ".parity"; -pub const RPC_PATH : &'static str = "rpc"; -pub const API_PATH : &'static str = "api"; -pub const UTILS_PATH : &'static str = "parity-utils"; +pub const DAPPS_DOMAIN: &'static str = ".parity"; +pub const RPC_PATH: &'static str = "rpc"; +pub const API_PATH: &'static str = "api"; +pub const UTILS_PATH: &'static str = "parity-utils"; +pub const WEB_PATH: &'static str = "web"; pub fn utils() -> Box { Box::new(PageEndpoint::with_prefix(parity_ui::App::default(), UTILS_PATH.to_owned())) } -pub fn all_endpoints(dapps_path: String, signer_address: Option<(String, u16)>) -> Endpoints { +pub fn all_endpoints(dapps_path: String, signer_address: Option<(String, u16)>, remote: Remote, fetch: F) -> Endpoints { // fetch fs dapps at first to avoid overwriting builtins let mut pages = fs::local_endpoints(dapps_path, signer_address.clone()); // NOTE [ToDr] Dapps will be currently embeded on 8180 insert::(&mut pages, "ui", Embeddable::Yes(signer_address.clone())); pages.insert("proxy".into(), ProxyPac::boxed(signer_address)); + pages.insert(WEB_PATH.into(), Web::boxed(remote, fetch)); pages } diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index d62b425d9..b0a3cde23 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -16,13 +16,14 @@ //! Hyper Server Handler that fetches a file during a request (proxy). -use std::{fs, fmt}; -use std::path::PathBuf; +use std::fmt; use std::sync::{mpsc, Arc}; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Instant, Duration}; +use fetch::{self, Fetch}; +use futures::Future; +use parity_reactor::Remote; use util::Mutex; -use fetch::{Client, Fetch, FetchResult}; use hyper::{server, Decoder, Encoder, Next, Method, Control}; use hyper::net::HttpStream; @@ -39,7 +40,7 @@ enum FetchState { Waiting, NotStarted(String), Error(ContentHandler), - InProgress(mpsc::Receiver), + InProgress(mpsc::Receiver), Done(LocalPageEndpoint, Box), } @@ -48,10 +49,10 @@ enum WaitResult { Done(LocalPageEndpoint), } -pub trait ContentValidator { +pub trait ContentValidator: Send + 'static { type Error: fmt::Debug + fmt::Display; - fn validate_and_install(&self, path: PathBuf) -> Result; + fn validate_and_install(&self, fetch::Response) -> Result; } pub struct FetchControl { @@ -160,33 +161,36 @@ impl server::Handler for WaitingHandler { } } -pub struct ContentFetcherHandler { +pub struct ContentFetcherHandler { fetch_control: Arc, - control: Option, + control: Control, + remote: Remote, status: FetchState, - client: Option, - installer: H, + fetch: F, + installer: Option, path: EndpointPath, uri: RequestUri, embeddable_on: Option<(String, u16)>, } -impl ContentFetcherHandler { +impl ContentFetcherHandler { pub fn new( url: String, path: EndpointPath, control: Control, handler: H, embeddable_on: Option<(String, u16)>, + remote: Remote, + fetch: F, ) -> (Self, Arc) { let fetch_control = Arc::new(FetchControl::default()); - let client = Client::default(); let handler = ContentFetcherHandler { fetch_control: fetch_control.clone(), - control: Some(control), - client: Some(client), + control: control, + remote: remote, + fetch: fetch, status: FetchState::NotStarted(url), - installer: handler, + installer: Some(handler), path: path, uri: RequestUri::default(), embeddable_on: embeddable_on, @@ -195,41 +199,74 @@ impl ContentFetcherHandler { (handler, fetch_control) } - fn close_client(client: &mut Option) { - client.take() - .expect("After client is closed we are going into write, hence we can never close it again") - .close(); - } + fn fetch_content(&self, url: &str, installer: H) -> mpsc::Receiver { + let (tx, rx) = mpsc::channel(); + let abort = self.fetch_control.abort.clone(); - fn fetch_content(client: &mut Client, url: &str, abort: Arc, control: Control) -> Result, String> { - client.request(url, abort, Box::new(move || { - trace!(target: "dapps", "Fetching finished."); + let control = self.control.clone(); + let embeddable_on = self.embeddable_on.clone(); + let uri = self.uri.clone(); + let path = self.path.clone(); + + let future = self.fetch.fetch_with_abort(url, abort.into()).then(move |result| { + trace!(target: "dapps", "Fetching content finished. Starting validation: {:?}", result); + let new_state = match result { + Ok(response) => match installer.validate_and_install(response) { + Ok(endpoint) => { + trace!(target: "dapps", "Validation OK. Returning response."); + let mut handler = endpoint.to_page_handler(path); + handler.set_uri(&uri); + FetchState::Done(endpoint, handler) + }, + Err(e) => { + trace!(target: "dapps", "Error while validating content: {:?}", e); + FetchState::Error(ContentHandler::error( + StatusCode::BadGateway, + "Invalid Dapp", + "Downloaded bundle does not contain a valid content.", + Some(&format!("{:?}", e)), + embeddable_on, + )) + }, + }, + Err(e) => { + warn!(target: "dapps", "Unable to fetch content: {:?}", e); + FetchState::Error(ContentHandler::error( + StatusCode::BadGateway, + "Download Error", + "There was an error when fetching the content.", + Some(&format!("{:?}", e)), + embeddable_on, + )) + }, + }; + // Content may be resolved when the connection is already dropped. + let _ = tx.send(new_state); // Ignoring control errors let _ = control.ready(Next::read()); - })).map_err(|e| format!("{:?}", e)) + Ok(()) as Result<(), ()> + }); + + // make sure to run within fetch thread pool. + let future = self.fetch.process(future); + // spawn to event loop + self.remote.spawn(future); + + rx } } -impl server::Handler for ContentFetcherHandler { +impl server::Handler for ContentFetcherHandler { fn on_request(&mut self, request: server::Request) -> Next { + self.uri = request.uri().clone(); + let installer = self.installer.take().expect("Installer always set initialy; installer used only in on_request; on_request invoked only once; qed"); let status = if let FetchState::NotStarted(ref url) = self.status { Some(match *request.method() { // Start fetching content Method::Get => { trace!(target: "dapps", "Fetching content from: {:?}", url); - let control = self.control.take().expect("on_request is called only once, thus control is always Some"); - let client = self.client.as_mut().expect("on_request is called before client is closed."); - let fetch = Self::fetch_content(client, url, self.fetch_control.abort.clone(), control); - match fetch { - Ok(receiver) => FetchState::InProgress(receiver), - Err(e) => FetchState::Error(ContentHandler::error( - StatusCode::BadGateway, - "Unable To Start Content Download", - "Could not initialize download of the content. It might be a problem with the remote server.", - Some(&format!("{}", e)), - self.embeddable_on.clone(), - )), - } + let receiver = self.fetch_content(url, installer); + FetchState::InProgress(receiver) }, // or return error _ => FetchState::Error(ContentHandler::error( @@ -246,7 +283,6 @@ impl server::Handler for ContentFetcherHandler< self.fetch_control.set_status(&status); self.status = status; } - self.uri = request.uri().clone(); Next::read() } @@ -263,50 +299,14 @@ impl server::Handler for ContentFetcherHandler< None, self.embeddable_on.clone(), ); - Self::close_client(&mut self.client); (Some(FetchState::Error(timeout)), Next::write()) }, FetchState::InProgress(ref receiver) => { // Check if there is an answer let rec = receiver.try_recv(); match rec { - // Unpack and validate - Ok(Ok(path)) => { - trace!(target: "dapps", "Fetching content finished. Starting validation ({:?})", path); - Self::close_client(&mut self.client); - // Unpack and verify - let state = match self.installer.validate_and_install(path.clone()) { - Err(e) => { - trace!(target: "dapps", "Error while validating content: {:?}", e); - FetchState::Error(ContentHandler::error( - StatusCode::BadGateway, - "Invalid Dapp", - "Downloaded bundle does not contain a valid content.", - Some(&format!("{:?}", e)), - self.embeddable_on.clone(), - )) - }, - Ok(endpoint) => { - let mut handler = endpoint.to_page_handler(self.path.clone()); - handler.set_uri(&self.uri); - FetchState::Done(endpoint, handler) - }, - }; - // Remove temporary zip file - let _ = fs::remove_file(path); - (Some(state), Next::write()) - }, - Ok(Err(e)) => { - warn!(target: "dapps", "Unable to fetch content: {:?}", e); - let error = ContentHandler::error( - StatusCode::BadGateway, - "Download Error", - "There was an error when fetching the content.", - Some(&format!("{:?}", e)), - self.embeddable_on.clone(), - ); - (Some(FetchState::Error(error)), Next::write()) - }, + // just return the new state + Ok(state) => (Some(state), Next::write()), // wait some more _ => (None, Next::wait()) } diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 72a246596..521c24797 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -61,6 +61,9 @@ extern crate parity_hash_fetch as hash_fetch; extern crate linked_hash_map; extern crate fetch; extern crate parity_dapps_glue as parity_dapps; +extern crate futures; +extern crate parity_reactor; + #[macro_use] extern crate log; #[macro_use] @@ -81,6 +84,7 @@ mod rpc; mod api; mod proxypac; mod url; +mod web; #[cfg(test)] mod tests; @@ -89,9 +93,11 @@ use std::net::SocketAddr; use std::collections::HashMap; use hash_fetch::urlhint::ContractClient; +use fetch::{Fetch, Client as FetchClient}; use jsonrpc_core::{IoHandler, IoDelegate}; use router::auth::{Authorization, NoAuth, HttpBasicAuth}; use ethcore_rpc::Extendable; +use parity_reactor::Remote; use self::apps::{HOME_PAGE, DAPPS_DOMAIN}; @@ -112,6 +118,8 @@ pub struct ServerBuilder { registrar: Arc, sync_status: Arc, signer_address: Option<(String, u16)>, + remote: Remote, + fetch: Option, } impl Extendable for ServerBuilder { @@ -122,16 +130,23 @@ impl Extendable for ServerBuilder { impl ServerBuilder { /// Construct new dapps server - pub fn new(dapps_path: String, registrar: Arc) -> Self { + pub fn new(dapps_path: String, registrar: Arc, remote: Remote) -> Self { ServerBuilder { dapps_path: dapps_path, handler: Arc::new(IoHandler::new()), registrar: registrar, sync_status: Arc::new(|| false), signer_address: None, + remote: remote, + fetch: None, } } + /// Set a fetch client to use. + pub fn with_fetch(&mut self, fetch: FetchClient) { + self.fetch = Some(fetch); + } + /// Change default sync status. pub fn with_sync_status(&mut self, status: Arc) { self.sync_status = status; @@ -154,6 +169,8 @@ impl ServerBuilder { self.signer_address.clone(), self.registrar.clone(), self.sync_status.clone(), + self.remote.clone(), + try!(self.fetch()), ) } @@ -169,8 +186,17 @@ impl ServerBuilder { self.signer_address.clone(), self.registrar.clone(), self.sync_status.clone(), + self.remote.clone(), + try!(self.fetch()), ) } + + fn fetch(&self) -> Result { + match self.fetch.clone() { + Some(fetch) => Ok(fetch), + None => FetchClient::new().map_err(|_| ServerError::FetchInitialization), + } + } } /// Webapps HTTP server. @@ -206,7 +232,7 @@ impl Server { } } - fn start_http( + fn start_http( addr: &SocketAddr, hosts: Option>, authorization: A, @@ -215,11 +241,19 @@ impl Server { signer_address: Option<(String, u16)>, registrar: Arc, sync_status: Arc, + remote: Remote, + fetch: F, ) -> Result { let panic_handler = Arc::new(Mutex::new(None)); let authorization = Arc::new(authorization); - let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(hash_fetch::urlhint::URLHintContract::new(registrar), sync_status, signer_address.clone())); - let endpoints = Arc::new(apps::all_endpoints(dapps_path, signer_address.clone())); + let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new( + hash_fetch::urlhint::URLHintContract::new(registrar), + sync_status, + signer_address.clone(), + remote.clone(), + fetch.clone(), + )); + let endpoints = Arc::new(apps::all_endpoints(dapps_path, signer_address.clone(), remote.clone(), fetch.clone())); let cors_domains = Self::cors_domains(signer_address.clone()); let special = Arc::new({ @@ -287,6 +321,8 @@ pub enum ServerError { IoError(std::io::Error), /// Other `hyper` error Other(hyper::error::Error), + /// Fetch service initialization error + FetchInitialization, } impl From for ServerError { @@ -299,7 +335,7 @@ impl From for ServerError { } /// Random filename -pub fn random_filename() -> String { +fn random_filename() -> String { use ::rand::Rng; let mut rng = ::rand::OsRng::new().unwrap(); rng.gen_ascii_chars().take(12).collect() diff --git a/dapps/src/page/local.rs b/dapps/src/page/local.rs index e8ab9ce14..08f942cea 100644 --- a/dapps/src/page/local.rs +++ b/dapps/src/page/local.rs @@ -20,11 +20,12 @@ use std::fs; use std::path::{Path, PathBuf}; use page::handler::{self, PageCache, PageHandlerWaiting}; use endpoint::{Endpoint, EndpointInfo, EndpointPath, Handler}; +use mime::Mime; #[derive(Debug, Clone)] pub struct LocalPageEndpoint { path: PathBuf, - mime: Option, + mime: Option, info: Option, cache: PageCache, embeddable_on: Option<(String, u16)>, @@ -41,7 +42,7 @@ impl LocalPageEndpoint { } } - pub fn single_file(path: PathBuf, mime: String, cache: PageCache) -> Self { + pub fn single_file(path: PathBuf, mime: Mime, cache: PageCache) -> Self { LocalPageEndpoint { path: path, mime: Some(mime), @@ -55,9 +56,9 @@ impl LocalPageEndpoint { self.path.clone() } - fn page_handler_with_mime(&self, path: EndpointPath, mime: &str) -> handler::PageHandler { + fn page_handler_with_mime(&self, path: EndpointPath, mime: &Mime) -> handler::PageHandler { handler::PageHandler { - app: LocalSingleFile { path: self.path.clone(), mime: mime.into() }, + app: LocalSingleFile { path: self.path.clone(), mime: format!("{}", mime) }, prefix: None, path: path, file: handler::ServedFile::new(None), diff --git a/dapps/src/router/mod.rs b/dapps/src/router/mod.rs index b444b1526..77ab2e7f6 100644 --- a/dapps/src/router/mod.rs +++ b/dapps/src/router/mod.rs @@ -27,7 +27,7 @@ use url::{Url, Host}; use hyper::{self, server, Next, Encoder, Decoder, Control, StatusCode}; use hyper::net::HttpStream; use apps::{self, DAPPS_DOMAIN}; -use apps::fetcher::ContentFetcher; +use apps::fetcher::Fetcher; use endpoint::{Endpoint, Endpoints, EndpointPath}; use handlers::{Redirection, extract_url, ContentHandler}; use self::auth::{Authorization, Authorized}; @@ -45,7 +45,7 @@ pub struct Router { control: Option, signer_address: Option<(String, u16)>, endpoints: Arc, - fetch: Arc, + fetch: Arc, special: Arc>>, authorization: Arc, allowed_hosts: Option>, @@ -169,7 +169,7 @@ impl Router { pub fn new( control: Control, signer_address: Option<(String, u16)>, - content_fetcher: Arc, + content_fetcher: Arc, endpoints: Arc, special: Arc>>, authorization: Arc, diff --git a/dapps/src/tests/helpers.rs b/dapps/src/tests/helpers.rs index 87edd00e0..e3870b93d 100644 --- a/dapps/src/tests/helpers.rs +++ b/dapps/src/tests/helpers.rs @@ -25,6 +25,7 @@ use Server; use hash_fetch::urlhint::ContractClient; use util::{Bytes, Address, Mutex, ToPretty}; use devtools::http_client; +use parity_reactor::Remote; const REGISTRAR: &'static str = "8e4e9b13d4b45cb0befc93c3061b1408f67316b2"; const URLHINT: &'static str = "deadbeefcafe0000000000000000000000000000"; @@ -74,7 +75,7 @@ pub fn init_server(hosts: Option>, is_syncing: bool) -> (Server, Arc let registrar = Arc::new(FakeRegistrar::new()); let mut dapps_path = env::temp_dir(); dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading"); - let mut builder = ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar.clone()); + let mut builder = ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar.clone(), Remote::new_sync()); builder.with_sync_status(Arc::new(move || is_syncing)); builder.with_signer_address(Some(("127.0.0.1".into(), SIGNER_PORT))); ( @@ -88,7 +89,7 @@ pub fn serve_with_auth(user: &str, pass: &str) -> Server { let registrar = Arc::new(FakeRegistrar::new()); let mut dapps_path = env::temp_dir(); dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading"); - let mut builder = ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar); + let mut builder = ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar.clone(), Remote::new_sync()); builder.with_signer_address(Some(("127.0.0.1".into(), SIGNER_PORT))); builder.start_basic_auth_http(&"127.0.0.1:0".parse().unwrap(), None, user, pass).unwrap() } diff --git a/dapps/src/web.rs b/dapps/src/web.rs new file mode 100644 index 000000000..e0f3a7b56 --- /dev/null +++ b/dapps/src/web.rs @@ -0,0 +1,180 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Serving web-based content (proxying) + +use endpoint::{Endpoint, Handler, EndpointPath}; +use handlers::{ContentFetcherHandler, ContentHandler, ContentValidator, Redirection, extract_url}; +use page::{LocalPageEndpoint}; +use fetch::{self, Fetch}; +use url::Url; +use hyper::{self, server, net, Next, Encoder, Decoder}; +use hyper::status::StatusCode; +use parity_reactor::Remote; +use apps::WEB_PATH; + +pub struct Web { + remote: Remote, + fetch: F, +} + +impl Web { + pub fn boxed(remote: Remote, fetch: F) -> Box { + Box::new(Web { + remote: remote, + fetch: fetch, + }) + } +} + +impl Endpoint for Web { + fn to_async_handler(&self, path: EndpointPath, control: hyper::Control) -> Box { + Box::new(WebHandler { + control: control, + state: State::Initial, + path: path, + remote: self.remote.clone(), + fetch: self.fetch.clone(), + }) + } +} + +pub struct WebInstaller; + +impl ContentValidator for WebInstaller { + type Error = String; + + fn validate_and_install(&self, _response: fetch::Response) -> Result { + // let path = unimplemented!(); + // let mime = response.content_type().unwrap_or(mime!(Text/Html)); + // Ok(LocalPageEndpoint::single_file(path, mime, PageCache::Enabled)) + Err("unimplemented".into()) + } +} + +enum State { + Initial, + Error(ContentHandler), + Redirecting(Redirection), + Fetching(ContentFetcherHandler), +} + +struct WebHandler { + control: hyper::Control, + state: State, + path: EndpointPath, + remote: Remote, + fetch: F, +} + +impl WebHandler { + fn extract_target_url(url: Option) -> Result> { + let path = match url { + Some(url) => url.path, + None => { + return Err(State::Error( + ContentHandler::error(StatusCode::BadRequest, "Invalid URL", "Couldn't parse URL", None, None) + )); + } + }; + + // TODO [ToDr] Check if token supplied in URL is correct. + + // Support domain based routing. + let idx = match path.get(0).map(|m| m.as_ref()) { + Some(WEB_PATH) => 1, + _ => 0, + }; + + // Validate protocol + let protocol = match path.get(idx).map(|a| a.as_str()) { + Some("http") => "http", + Some("https") => "https", + _ => { + return Err(State::Error( + ContentHandler::error(StatusCode::BadRequest, "Invalid Protocol", "Invalid protocol used", None, None) + )); + } + }; + + // Redirect if address to main page does not end with / + if let None = path.get(idx + 2) { + return Err(State::Redirecting( + Redirection::new(&format!("/{}/", path.join("/"))) + )); + } + + Ok(format!("{}://{}", protocol, path[2..].join("/"))) + } +} + +impl server::Handler for WebHandler { + fn on_request(&mut self, request: server::Request) -> Next { + let url = extract_url(&request); + + // First extract the URL (reject invalid URLs) + let target_url = match Self::extract_target_url(url) { + Ok(url) => url, + Err(error) => { + self.state = error; + return Next::write(); + } + }; + + let (mut handler, _control) = ContentFetcherHandler::new( + target_url, + self.path.clone(), + self.control.clone(), + WebInstaller, + None, + self.remote.clone(), + self.fetch.clone(), + ); + let res = handler.on_request(request); + self.state = State::Fetching(handler); + + res + } + + fn on_request_readable(&mut self, decoder: &mut Decoder) -> Next { + match self.state { + State::Initial => Next::end(), + State::Error(ref mut handler) => handler.on_request_readable(decoder), + State::Redirecting(ref mut handler) => handler.on_request_readable(decoder), + State::Fetching(ref mut handler) => handler.on_request_readable(decoder), + } + } + + fn on_response(&mut self, res: &mut server::Response) -> Next { + match self.state { + State::Initial => Next::end(), + State::Error(ref mut handler) => handler.on_response(res), + State::Redirecting(ref mut handler) => handler.on_response(res), + State::Fetching(ref mut handler) => handler.on_response(res), + } + } + + fn on_response_writable(&mut self, encoder: &mut Encoder) -> Next { + match self.state { + State::Initial => Next::end(), + State::Error(ref mut handler) => handler.on_response_writable(encoder), + State::Redirecting(ref mut handler) => handler.on_response_writable(encoder), + State::Fetching(ref mut handler) => handler.on_response_writable(encoder), + } + } +} + + diff --git a/hash-fetch/Cargo.toml b/hash-fetch/Cargo.toml index fa98f2fce..328d53eb1 100644 --- a/hash-fetch/Cargo.toml +++ b/hash-fetch/Cargo.toml @@ -7,9 +7,13 @@ version = "1.5.0" authors = ["Parity Technologies "] [dependencies] -log = "0.3" -rustc-serialize = "0.3" ethabi = "0.2.2" +futures = "0.1" +log = "0.3" +mime = "0.2" mime_guess = "1.6.1" +rand = "0.3" +rustc-serialize = "0.3" fetch = { path = "../util/fetch" } ethcore-util = { path = "../util" } +parity-reactor = { path = "../util/reactor" } diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index 57a1b104f..bc173e80d 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -17,13 +17,15 @@ //! Hash-addressed content resolver & fetcher. use std::{io, fs}; +use std::io::Write; use std::sync::Arc; use std::path::PathBuf; -use util::{Mutex, H256, sha3}; -use fetch::{Fetch, FetchError, Client as FetchClient}; - +use fetch::{Fetch, Response, Error as FetchError, Client as FetchClient}; +use futures::Future; +use parity_reactor::Remote; use urlhint::{ContractClient, URLHintContract, URLHint, URLHintResult}; +use util::{H256, sha3}; /// API for fetching by hash. pub trait HashFetch: Send + Sync + 'static { @@ -33,7 +35,7 @@ pub trait HashFetch: Send + Sync + 'static { /// 2. `on_done` - callback function invoked when the content is ready (or there was error during fetch) /// /// This function may fail immediately when fetch cannot be initialized or content cannot be resolved. - fn fetch(&self, hash: H256, on_done: Box) + Send>) -> Result<(), Error>; + fn fetch(&self, hash: H256, on_done: Box) + Send>); } /// Hash-fetching error. @@ -67,53 +69,94 @@ impl From for Error { } /// Default Hash-fetching client using on-chain contract to resolve hashes to URLs. -pub struct Client { +pub struct Client { contract: URLHintContract, - fetch: Mutex, + fetch: F, + remote: Remote, } impl Client { - /// Creates new instance of the `Client` given on-chain contract client. - pub fn new(contract: Arc) -> Self { + /// Creates new instance of the `Client` given on-chain contract client and task runner. + pub fn new(contract: Arc, remote: Remote) -> Self { + Client::with_fetch(contract, FetchClient::new().unwrap(), remote) + } +} + +impl Client { + + /// Creates new instance of the `Client` given on-chain contract client, fetch service and task runner. + pub fn with_fetch(contract: Arc, fetch: F, remote: Remote) -> Self { Client { contract: URLHintContract::new(contract), - fetch: Mutex::new(FetchClient::default()), + fetch: fetch, + remote: remote, } } } -impl HashFetch for Client { - fn fetch(&self, hash: H256, on_done: Box) + Send>) -> Result<(), Error> { +impl HashFetch for Client { + fn fetch(&self, hash: H256, on_done: Box) + Send>) { debug!(target: "fetch", "Fetching: {:?}", hash); - let url = try!( - self.contract.resolve(hash.to_vec()).map(|content| match content { + let url = self.contract.resolve(hash.to_vec()).map(|content| match content { URLHintResult::Dapp(dapp) => { dapp.url() }, URLHintResult::Content(content) => { content.url }, - }).ok_or_else(|| Error::NoResolution) - ); + }).ok_or_else(|| Error::NoResolution); debug!(target: "fetch", "Resolved {:?} to {:?}. Fetching...", hash, url); - self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| { - fn validate_hash(hash: H256, result: Result) -> Result { - let path = try!(result); - let mut file_reader = io::BufReader::new(try!(fs::File::open(&path))); - let content_hash = try!(sha3(&mut file_reader)); + match url { + Err(err) => on_done(Err(err)), + Ok(url) => { + let future = self.fetch.fetch(&url).then(move |result| { + fn validate_hash(path: PathBuf, hash: H256, result: Result) -> Result { + let response = try!(result); + // Read the response + let mut reader = io::BufReader::new(response); + let mut writer = io::BufWriter::new(try!(fs::File::create(&path))); + try!(io::copy(&mut reader, &mut writer)); + try!(writer.flush()); - if content_hash != hash { - Err(Error::HashMismatch{ got: content_hash, expected: hash }) - } else { - Ok(path) - } - } + // And validate the hash + let mut file_reader = io::BufReader::new(try!(fs::File::open(&path))); + let content_hash = try!(sha3(&mut file_reader)); + if content_hash != hash { + Err(Error::HashMismatch{ got: content_hash, expected: hash }) + } else { + Ok(path) + } + } - debug!(target: "fetch", "Content fetched, validating hash ({:?})", hash); - on_done(validate_hash(hash, result)) - })).map_err(Into::into) + debug!(target: "fetch", "Content fetched, validating hash ({:?})", hash); + let path = random_temp_path(); + let res = validate_hash(path.clone(), hash, result); + if let Err(ref err) = res { + trace!(target: "fetch", "Error: {:?}", err); + // Remove temporary file in case of error + let _ = fs::remove_dir_all(&path); + } + on_done(res); + + Ok(()) as Result<(), ()> + }); + self.remote.spawn(self.fetch.process(future)); + }, + } } } + +fn random_temp_path() -> PathBuf { + use ::rand::Rng; + use ::std::env; + + let mut rng = ::rand::OsRng::new().expect("Reliable random source is required to work."); + let file: String = rng.gen_ascii_chars().take(12).collect(); + + let mut path = env::temp_dir(); + path.push(file); + path +} diff --git a/hash-fetch/src/lib.rs b/hash-fetch/src/lib.rs index e333b6df2..1b66b0ea5 100644 --- a/hash-fetch/src/lib.rs +++ b/hash-fetch/src/lib.rs @@ -20,11 +20,17 @@ #[macro_use] extern crate log; -extern crate rustc_serialize; -extern crate mime_guess; +#[macro_use] +extern crate mime; + extern crate ethabi; extern crate ethcore_util as util; -extern crate fetch; +pub extern crate fetch; +extern crate futures; +extern crate mime_guess; +extern crate rand; +extern crate rustc_serialize; +extern crate parity_reactor; mod client; diff --git a/hash-fetch/src/urlhint.rs b/hash-fetch/src/urlhint.rs index 79575e8f3..0b7b4fa4f 100644 --- a/hash-fetch/src/urlhint.rs +++ b/hash-fetch/src/urlhint.rs @@ -19,6 +19,7 @@ use std::fmt; use std::sync::Arc; use rustc_serialize::hex::ToHex; +use mime::Mime; use mime_guess; use ethabi::{Interface, Contract, Token}; @@ -76,7 +77,7 @@ pub struct Content { /// URL of the content pub url: String, /// MIME type of the content - pub mime: String, + pub mime: Mime, /// Content owner address pub owner: Address, } @@ -183,7 +184,7 @@ impl URLHintContract { let commit = GithubApp::commit(&commit); if commit == Some(Default::default()) { - let mime = guess_mime_type(&account_slash_repo).unwrap_or("application/octet-stream".into()); + let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime!(Application/_)); return Some(URLHintResult::Content(Content { url: account_slash_repo, mime: mime, @@ -235,7 +236,7 @@ impl URLHint for URLHintContract { } } -fn guess_mime_type(url: &str) -> Option { +fn guess_mime_type(url: &str) -> Option { const CONTENT_TYPE: &'static str = "content-type="; let mut it = url.split('#'); @@ -247,14 +248,14 @@ fn guess_mime_type(url: &str) -> Option { for meta in metas.split('&') { let meta = meta.to_lowercase(); if meta.starts_with(CONTENT_TYPE) { - return Some(meta[CONTENT_TYPE.len()..].to_owned()); + return meta[CONTENT_TYPE.len()..].parse().ok(); } } } url.and_then(|url| { url.split('.').last() }).and_then(|extension| { - mime_guess::get_mime_type_str(extension).map(Into::into) + mime_guess::get_mime_type_opt(extension) }) } @@ -369,7 +370,7 @@ mod tests { // then assert_eq!(res, Some(URLHintResult::Content(Content { url: "https://ethcore.io/assets/images/ethcore-black-horizontal.png".into(), - mime: "image/png".into(), + mime: mime!(Image/Png), owner: Address::from_str("deadcafebeefbeefcafedeaddeedfeedffffffff").unwrap(), }))) } @@ -401,9 +402,9 @@ mod tests { assert_eq!(guess_mime_type(url1), None); - assert_eq!(guess_mime_type(url2), Some("image/png".into())); - assert_eq!(guess_mime_type(url3), Some("image/png".into())); - assert_eq!(guess_mime_type(url4), Some("image/jpeg".into())); - assert_eq!(guess_mime_type(url5), Some("image/png".into())); + assert_eq!(guess_mime_type(url2), Some(mime!(Image/Png))); + assert_eq!(guess_mime_type(url3), Some(mime!(Image/Png))); + assert_eq!(guess_mime_type(url4), Some(mime!(Image/Jpeg))); + assert_eq!(guess_mime_type(url5), Some(mime!(Image/Png))); } } diff --git a/parity/dapps.rs b/parity/dapps.rs index 80fe8d675..7f0550427 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -21,6 +21,8 @@ use ethcore::client::Client; use ethsync::SyncProvider; use helpers::replace_home; use dir::default_data_path; +use hash_fetch::fetch::Client as FetchClient; +use parity_reactor::Remote; #[derive(Debug, PartialEq, Clone)] pub struct Configuration { @@ -53,6 +55,8 @@ pub struct Dependencies { pub apis: Arc, pub client: Arc, pub sync: Arc, + pub remote: Remote, + pub fetch: FetchClient, } pub fn new(configuration: Configuration, deps: Dependencies) -> Result, String> { @@ -128,10 +132,12 @@ mod server { let mut server = dapps::ServerBuilder::new( dapps_path, - Arc::new(Registrar { client: deps.client.clone() }) + Arc::new(Registrar { client: deps.client.clone() }), + deps.remote.clone(), ); let sync = deps.sync.clone(); let client = deps.client.clone(); + server.with_fetch(deps.fetch.clone()); server.with_sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info()))); server.with_signer_address(signer_address); diff --git a/parity/main.rs b/parity/main.rs index 91aab42a7..6bab26cc3 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -56,6 +56,7 @@ extern crate regex; extern crate isatty; extern crate toml; extern crate app_dirs; +extern crate parity_reactor; #[macro_use] extern crate ethcore_util as util; @@ -203,7 +204,7 @@ fn updates_path(name: &str) -> PathBuf { fn latest_exe_path() -> Option { File::open(updates_path("latest")).ok() .and_then(|mut f| { let mut exe = String::new(); f.read_to_string(&mut exe).ok().map(|_| updates_path(&exe)) }) -} +} // Starts ~/.parity-updates/parity and returns the code it exits with. fn run_parity() -> Option { @@ -220,7 +221,7 @@ fn run_parity() -> Option { const PLEASE_RESTART_EXIT_CODE: i32 = 69; // Run our version of parity. -// Returns the exit error code. +// Returns the exit error code. fn main_direct(can_restart: bool) -> i32 { let mut alt_mains = HashMap::new(); sync_main(&mut alt_mains); @@ -271,9 +272,9 @@ fn main() { trace_main!("Starting up {} (force-direct: {}, development: {}, same-name: {}, have-update: {}, non-updated-current: {})", std::env::current_exe().map(|x| format!("{}", x.display())).unwrap_or("".to_owned()), force_direct, development, same_name, have_update, is_non_updated_current); if !force_direct && !development && same_name && have_update && is_non_updated_current { // looks like we're not running ~/.parity-updates/parity when the user is expecting otherwise. - // Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly. + // Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly. loop { - // If we fail to run the updated parity then fallback to local version. + // If we fail to run the updated parity then fallback to local version. trace_main!("Attempting to run latest update ({})...", latest_exe.as_ref().expect("guarded by have_update; latest_exe must exist for have_update; qed").display()); let exit_code = run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct(true) }); trace_main!("Latest exited with {}", exit_code); diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 30a8c596c..5260b9df5 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -28,6 +28,8 @@ use ethsync::{ManageNetwork, SyncProvider}; use ethcore_rpc::{Extendable, NetworkSettings}; pub use ethcore_rpc::SignerService; use updater::Updater; +use hash_fetch::fetch::Client as FetchClient; +use parity_reactor::Remote; #[derive(Debug, PartialEq, Clone, Eq, Hash)] pub enum Api { @@ -122,6 +124,8 @@ pub struct Dependencies { pub geth_compatibility: bool, pub dapps_interface: Option, pub dapps_port: Option, + pub fetch: FetchClient, + pub remote: Remote, } fn to_modules(apis: &[Api]) -> BTreeMap { @@ -242,7 +246,14 @@ pub fn setup_rpc(server: T, deps: Arc, apis: ApiSet server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate()); }, Api::ParitySet => { - server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.updater, &deps.net_service).to_delegate()) + server.add_delegate(ParitySetClient::new( + &deps.client, + &deps.miner, + &deps.updater, + &deps.net_service, + deps.fetch.clone(), + deps.remote.clone(), + ).to_delegate()) }, Api::Traces => { server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate()) diff --git a/parity/run.rs b/parity/run.rs index a2f36e5fe..8ef995c09 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -32,6 +32,8 @@ use ethcore::verification::queue::VerifierSettings; use ethsync::SyncConfig; use informant::Informant; use updater::{UpdatePolicy, Updater}; +use parity_reactor::{EventLoop, EventLoopHandle}; +use hash_fetch::fetch::Client as FetchClient; use rpc::{HttpServer, IpcServer, HttpConfiguration, IpcConfiguration}; use signer::SignerServer; @@ -304,10 +306,23 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R chain_notify.start(); } + // spin up event loop + let event_loop = EventLoop::spawn(); + + // fetch service + let fetch = try!(FetchClient::new().map_err(|e| format!("Error starting fetch client: {:?}", e))); + // the updater service - let updater = Updater::new(Arc::downgrade(&(service.client() as Arc)), Arc::downgrade(&sync_provider), update_policy); + let updater = Updater::new( + Arc::downgrade(&(service.client() as Arc)), + Arc::downgrade(&sync_provider), + update_policy, + fetch.clone(), + event_loop.remote(), + ); service.add_notify(updater.clone()); + // set up dependencies for rpc servers let signer_path = cmd.signer_conf.signer_path.clone(); let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies { @@ -334,6 +349,8 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R true => Some(cmd.dapps_conf.port), false => None, }, + fetch: fetch.clone(), + remote: event_loop.remote(), }); let dependencies = rpc::Dependencies { @@ -351,6 +368,8 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R apis: deps_for_rpc_apis.clone(), client: client.clone(), sync: sync_provider.clone(), + remote: event_loop.remote(), + fetch: fetch.clone(), }; let dapps_server = try!(dapps::new(cmd.dapps_conf.clone(), dapps_deps)); @@ -409,7 +428,16 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R } // Handle exit - let restart = wait_for_exit(panic_handler, http_server, ipc_server, dapps_server, signer_server, updater, can_restart); + let restart = wait_for_exit( + panic_handler, + http_server, + ipc_server, + dapps_server, + signer_server, + event_loop.into(), + updater, + can_restart, + ); info!("Finishing work, please wait..."); @@ -468,6 +496,7 @@ fn wait_for_exit( _ipc_server: Option, _dapps_server: Option, _signer_server: Option, + _event_loop: EventLoopHandle, updater: Arc, can_restart: bool ) -> bool { diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 7a219dd35..9031f6adf 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -9,9 +9,15 @@ build = "build.rs" [lib] [dependencies] +futures = "0.1" log = "0.3" +rustc-serialize = "0.3" serde = "0.8" serde_json = "0.8" +time = "0.1" +rand = "0.3" +semver = "0.5" +transient-hashmap = "0.1" jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" } jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git" } jsonrpc-ipc-server = { git = "https://github.com/ethcore/jsonrpc.git" } @@ -29,13 +35,10 @@ ethcore-devtools = { path = "../devtools" } parity-updater = { path = "../updater" } rlp = { path = "../util/rlp" } fetch = { path = "../util/fetch" } -rustc-serialize = "0.3" -transient-hashmap = "0.1" +parity-reactor = { path = "../util/reactor" } serde_macros = { version = "0.8.0", optional = true } clippy = { version = "0.0.103", optional = true} ethcore-ipc = { path = "../ipc/rpc" } -time = "0.1" -semver = "0.5" [build-dependencies] serde_codegen = { version = "0.8.0", optional = true } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 972c09316..8f178cfff 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -38,7 +38,10 @@ extern crate ethcore_ipc; extern crate time; extern crate rlp; extern crate fetch; +extern crate futures; +extern crate rand; extern crate parity_updater as updater; +extern crate parity_reactor; #[macro_use] extern crate log; diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 4e1ab64eb..83b3b0c58 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -24,7 +24,6 @@ use std::fmt; use rlp::DecoderError; use ethcore::error::{Error as EthcoreError, CallError, TransactionError}; use ethcore::account_provider::{Error as AccountError}; -use fetch::FetchError; use jsonrpc_core::{Error, ErrorCode, Value}; mod codes { @@ -203,7 +202,7 @@ pub fn encryption_error(error: T) -> Error { } } -pub fn from_fetch_error(error: FetchError) -> Error { +pub fn from_fetch_error(error: T) -> Error { Error { code: ErrorCode::ServerError(codes::FETCH_ERROR), message: "Error while fetching content.".into(), diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 4399f18f9..6af40a389 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -15,16 +15,18 @@ // along with Parity. If not, see . /// Parity-specific rpc interface for operations altering the settings. -use std::{fs, io}; -use std::sync::{Arc, Weak, mpsc}; +use std::io; +use std::sync::{Arc, Weak}; use ethcore::miner::MinerService; use ethcore::client::MiningBlockChainClient; use ethcore::mode::Mode; use ethsync::ManageNetwork; -use fetch::{Client as FetchClient, Fetch}; -use util::{Mutex, sha3}; +use fetch::{self, Fetch}; +use futures::Future; +use util::sha3; use updater::{Service as UpdateService}; +use parity_reactor::Remote; use jsonrpc_core::Error; use jsonrpc_macros::Ready; @@ -33,7 +35,7 @@ use v1::traits::ParitySet; use v1::types::{Bytes, H160, H256, U256, ReleaseInfo}; /// Parity-specific rpc interface for operations altering the settings. -pub struct ParitySetClient where +pub struct ParitySetClient where C: MiningBlockChainClient, M: MinerService, U: UpdateService, @@ -43,18 +45,8 @@ pub struct ParitySetClient where miner: Weak, updater: Weak, net: Weak, - fetch: Mutex, -} - -impl ParitySetClient where - C: MiningBlockChainClient, - M: MinerService, - U: UpdateService, -{ - /// Creates new `ParitySetClient` with default `FetchClient`. - pub fn new(client: &Arc, miner: &Arc, updater: &Arc, net: &Arc) -> Self { - Self::with_fetch(client, miner, updater, net) - } + fetch: F, + remote: Remote, } impl ParitySetClient where @@ -63,14 +55,15 @@ impl ParitySetClient where U: UpdateService, F: Fetch, { - /// Creates new `ParitySetClient` with default `FetchClient`. - pub fn with_fetch(client: &Arc, miner: &Arc, updater: &Arc, net: &Arc) -> Self { + /// Creates new `ParitySetClient` with given `Fetch`. + pub fn new(client: &Arc, miner: &Arc, updater: &Arc, net: &Arc, fetch: F, remote: Remote) -> Self { ParitySetClient { client: Arc::downgrade(client), miner: Arc::downgrade(miner), updater: Arc::downgrade(updater), net: Arc::downgrade(net), - fetch: Mutex::new(F::default()), + fetch: fetch, + remote: remote, } } @@ -199,41 +192,23 @@ impl ParitySet for ParitySetClient where fn hash_content(&self, ready: Ready, url: String) { let res = self.active(); - let hash_content = |result| { - let path = try!(result); - let mut file = io::BufReader::new(try!(fs::File::open(&path))); - // Try to hash - let result = sha3(&mut file); - // Remove file (always) - try!(fs::remove_file(&path)); - // Return the result - Ok(try!(result)) - }; - match res { Err(e) => ready.ready(Err(e)), Ok(()) => { - let (tx, rx) = mpsc::channel(); - let res = self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| { - let result = hash_content(result) + let task = self.fetch.fetch(&url).then(move |result| { + let result = result .map_err(errors::from_fetch_error) + .and_then(|response| { + sha3(&mut io::BufReader::new(response)).map_err(errors::from_fetch_error) + }) .map(Into::into); // Receive ready and invoke with result. - let ready: Ready = rx.recv().expect( - "recv() fails when `tx` has been dropped, if this closure is invoked `tx` is not dropped (`res == Ok()`); qed" - ); ready.ready(result); - })); + Ok(()) as Result<(), ()> + }); - // Either invoke ready right away or transfer it to the closure. - if let Err(e) = res { - ready.ready(Err(errors::from_fetch_error(e))); - } else { - tx.send(ready).expect( - "send() fails when `rx` end is dropped, if `res == Ok()`: `rx` is moved to the closure; qed" - ); - } + self.remote.spawn(task); } } } diff --git a/rpc/src/v1/tests/helpers/fetch.rs b/rpc/src/v1/tests/helpers/fetch.rs index bdf9ea65b..b55e4caca 100644 --- a/rpc/src/v1/tests/helpers/fetch.rs +++ b/rpc/src/v1/tests/helpers/fetch.rs @@ -16,29 +16,24 @@ //! Test implementation of fetch client. -use std::io::Write; -use std::{env, fs, thread}; -use std::sync::Arc; -use std::sync::atomic::AtomicBool; -use fetch::{Fetch, FetchError, FetchResult}; +use std::{io, thread}; +use futures::{self, Future}; +use fetch::{self, Fetch}; /// Test implementation of fetcher. Will always return the same file. -#[derive(Default)] +#[derive(Default, Clone)] pub struct TestFetch; impl Fetch for TestFetch { - fn request_async(&mut self, _url: &str, _abort: Arc, on_done: Box) -> Result<(), FetchError> { + type Result = futures::BoxFuture; + + fn fetch_with_abort(&self, _url: &str, _abort: fetch::Abort) -> Self::Result { + let (tx, rx) = futures::oneshot(); thread::spawn(move || { - let mut path = env::temp_dir(); - path.push(Self::random_filename()); - - let mut file = fs::File::create(&path).unwrap(); - file.write_all(b"Some content").unwrap(); - - on_done(Ok(path)); + let cursor = io::Cursor::new(b"Some content"); + tx.complete(fetch::Response::from_reader(cursor)); }); - Ok(()) + + rx.map_err(|_| fetch::Error::Aborted).boxed() } } - - diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index a9d62d21a..e36b69058 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -22,6 +22,7 @@ use util::{U256, Address}; use ethcore::miner::MinerService; use ethcore::client::TestBlockChainClient; use ethsync::ManageNetwork; +use parity_reactor::Remote; use jsonrpc_core::{IoHandler, GenericIoHandler}; use v1::{ParitySet, ParitySetClient}; @@ -47,7 +48,7 @@ fn updater_service() -> Arc { pub type TestParitySetClient = ParitySetClient; fn parity_set_client(client: &Arc, miner: &Arc, updater: &Arc, net: &Arc) -> TestParitySetClient { - ParitySetClient::with_fetch(client, miner, updater, &(net.clone() as Arc)) + ParitySetClient::new(client, miner, updater, &(net.clone() as Arc), TestFetch::default(), Remote::new_sync()) } #[test] diff --git a/updater/Cargo.toml b/updater/Cargo.toml index 9a6242b25..31ca30c43 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -12,13 +12,14 @@ ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] log = "0.3" ethabi = "0.2.2" +target_info = "0.1" ethcore = { path = "../ethcore" } ethsync = { path = "../sync" } ethcore-util = { path = "../util" } parity-hash-fetch = { path = "../hash-fetch" } ipc-common-types = { path = "../ipc-common-types" } ethcore-ipc = { path = "../ipc/rpc" } -target_info = "0.1" +parity-reactor = { path = "../util/reactor" } [profile.release] debug = true diff --git a/updater/src/lib.rs b/updater/src/lib.rs index 9dbcc94a5..50ffc6ddc 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -25,6 +25,7 @@ extern crate ethabi; extern crate ethsync; extern crate ethcore_ipc as ipc; extern crate target_info; +extern crate parity_reactor; mod updater; mod operations; @@ -37,4 +38,4 @@ mod service { pub use service::{Service}; pub use types::all::{ReleaseInfo, OperationsInfo, CapState, VersionInfo, ReleaseTrack}; -pub use updater::{Updater, UpdateFilter, UpdatePolicy}; \ No newline at end of file +pub use updater::{Updater, UpdateFilter, UpdatePolicy}; diff --git a/updater/src/updater.rs b/updater/src/updater.rs index f347308e4..4406451ef 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -21,12 +21,14 @@ use std::path::{PathBuf}; use target_info::Target; use util::misc; use ipc_common_types::{VersionInfo, ReleaseTrack}; -use util::path::restrict_permissions_owner; +use util::path::restrict_permissions_owner; use util::{Address, H160, H256, FixedHash, Mutex, Bytes}; use ethsync::{SyncProvider}; use ethcore::client::{BlockId, BlockChainClient, ChainNotify}; use hash_fetch::{self as fetch, HashFetch}; +use hash_fetch::fetch::Client as FetchService; use operations::Operations; +use parity_reactor::Remote; use service::{Service}; use types::all::{ReleaseInfo, OperationsInfo, CapState}; @@ -35,7 +37,7 @@ use types::all::{ReleaseInfo, OperationsInfo, CapState}; pub enum UpdateFilter { /// All releases following the same track. All, - /// As with `All`, but only those which are known to be critical. + /// As with `All`, but only those which are known to be critical. Critical, /// None. None, @@ -112,7 +114,7 @@ fn platform() -> String { } impl Updater { - pub fn new(client: Weak, sync: Weak, update_policy: UpdatePolicy) -> Arc { + pub fn new(client: Weak, sync: Weak, update_policy: UpdatePolicy, fetch: FetchService, remote: Remote) -> Arc { let r = Arc::new(Updater { update_policy: update_policy, weak_self: Mutex::new(Default::default()), @@ -124,7 +126,7 @@ impl Updater { this: VersionInfo::this(), state: Mutex::new(Default::default()), }); - *r.fetcher.lock() = Some(fetch::Client::new(r.clone())); + *r.fetcher.lock() = Some(fetch::Client::with_fetch(r.clone(), fetch, remote)); *r.weak_self.lock() = Arc::downgrade(&r); r.poll(); r @@ -132,7 +134,7 @@ impl Updater { /// Set a closure to call when we want to restart the client pub fn set_exit_handler(&self, f: F) where F: Fn() + 'static + Send { - *self.exit_handler.lock() = Some(Box::new(f)); + *self.exit_handler.lock() = Some(Box::new(f)); } fn collect_release_info(operations: &Operations, release_id: &H256) -> Result { @@ -159,7 +161,7 @@ impl Updater { trace!(target: "updater", "Looking up this_fork for our release: {}/{:?}", CLIENT_ID, hh); let this_fork = operations.release(CLIENT_ID, &self.this.hash.into()).ok() .and_then(|(fork, track, _, _)| { - trace!(target: "updater", "Operations returned fork={}, track={}", fork as u64, track); + trace!(target: "updater", "Operations returned fork={}, track={}", fork as u64, track); if track > 0 {Some(fork as u64)} else {None} }); @@ -250,7 +252,7 @@ impl Updater { let current_number = self.client.upgrade().map_or(0, |c| c.block_number(BlockId::Latest).unwrap_or(0)); - let mut capability = CapState::Unknown; + let mut capability = CapState::Unknown; let latest = self.collect_latest().ok(); if let Some(ref latest) = latest { trace!(target: "updater", "Latest release in our track is v{} it is {}critical ({} binary is {})", @@ -273,7 +275,7 @@ impl Updater { s.fetching = Some(latest.track.clone()); let weak_self = self.weak_self.lock().clone(); let f = move |r: Result| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) }; - self.fetcher.lock().as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f)).ok(); + self.fetcher.lock().as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f)); } } } @@ -281,7 +283,7 @@ impl Updater { if let Some(this_fork) = latest.this_fork { if this_fork < latest.fork { - // We're behind the latest fork. Now is the time to be upgrading; perhaps we're too late... + // We're behind the latest fork. Now is the time to be upgrading; perhaps we're too late... if let Some(c) = self.client.upgrade() { let current_number = c.block_number(BlockId::Latest).unwrap_or(0); if current_number >= latest.fork - 1 { @@ -368,4 +370,4 @@ impl Service for Updater { fn version_info(&self) -> VersionInfo { self.this.clone() } fn info(&self) -> Option { self.state.lock().latest.clone() } -} \ No newline at end of file +} diff --git a/util/fetch/Cargo.toml b/util/fetch/Cargo.toml index 6f014a27d..308816ed7 100644 --- a/util/fetch/Cargo.toml +++ b/util/fetch/Cargo.toml @@ -7,11 +7,12 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] +futures = "0.1" +futures-cpupool = "0.1" log = "0.3" -rand = "0.3" -hyper = { default-features = false, git = "https://github.com/ethcore/hyper" } -https-fetch = { path = "../https-fetch" } -clippy = { version = "0.0.90", optional = true } +reqwest = "0.2" +mime = "0.2" +clippy = { version = "0.0.90", optional = true} [features] default = [] diff --git a/util/fetch/src/client.rs b/util/fetch/src/client.rs index 7ee544252..20bbcee2f 100644 --- a/util/fetch/src/client.rs +++ b/util/fetch/src/client.rs @@ -16,131 +16,216 @@ //! Fetching -use std::{env, io}; -use std::sync::{mpsc, Arc}; -use std::sync::atomic::AtomicBool; -use std::path::PathBuf; +use std::{io, fmt}; +use std::sync::Arc; +use std::sync::atomic::{self, AtomicBool}; -use hyper; -use https_fetch as https; +use futures::{self, BoxFuture, Future}; +use futures_cpupool::{CpuPool, CpuFuture}; +use reqwest; +pub use mime::Mime; -use fetch_file::{FetchHandler, Error as HttpFetchError}; +#[derive(Default, Debug, Clone)] +pub struct Abort(Arc); -pub type FetchResult = Result; - -#[derive(Debug)] -pub enum FetchError { - InvalidUrl, - Http(HttpFetchError), - Https(https::FetchError), - Io(io::Error), - Other(String), -} - -impl From for FetchError { - fn from(e: HttpFetchError) -> Self { - FetchError::Http(e) +impl Abort { + pub fn is_aborted(&self) -> bool { + self.0.load(atomic::Ordering::SeqCst) } } -impl From for FetchError { - fn from(e: io::Error) -> Self { - FetchError::Io(e) +impl From> for Abort { + fn from(a: Arc) -> Self { + Abort(a) } } -pub trait Fetch: Default + Send { - /// Fetch URL and get the result in callback. - fn request_async(&mut self, url: &str, abort: Arc, on_done: Box) -> Result<(), FetchError>; +pub trait Fetch: Clone + Send + Sync + 'static { + type Result: Future + Send + 'static; - /// Fetch URL and get a result Receiver. You will be notified when receiver is ready by `on_done` callback. - fn request(&mut self, url: &str, abort: Arc, on_done: Box) -> Result, FetchError> { - let (tx, rx) = mpsc::channel(); - try!(self.request_async(url, abort, Box::new(move |result| { - let res = tx.send(result); - if let Err(_) = res { - warn!("Fetch finished, but no one was listening"); + /// Spawn the future in context of this `Fetch` thread pool. + /// Implementation is optional. + fn process(&self, f: F) -> BoxFuture<(), ()> where + F: Future + Send + 'static, + { + f.boxed() } - on_done(); - }))); - Ok(rx) + + /// Fetch URL and get a future for the result. + /// Supports aborting the request in the middle of execution. + fn fetch_with_abort(&self, url: &str, abort: Abort) -> Self::Result; + + /// Fetch URL and get a future for the result. + fn fetch(&self, url: &str) -> Self::Result { + self.fetch_with_abort(url, Default::default()) + } + + /// Fetch URL and get the result synchronously. + fn fetch_sync(&self, url: &str) -> Result { + self.fetch(url).wait() } /// Closes this client - fn close(self) {} - - /// Returns a random filename - fn random_filename() -> String { - use ::rand::Rng; - let mut rng = ::rand::OsRng::new().unwrap(); - rng.gen_ascii_chars().take(12).collect() - } + fn close(self) where Self: Sized {} } +#[derive(Clone)] pub struct Client { - http_client: hyper::Client, - https_client: https::Client, + client: Arc, + pool: CpuPool, limit: Option, } -impl Default for Client { - fn default() -> Self { - // Max 15MB will be downloaded. - Client::with_limit(Some(15*1024*1024)) - } -} - impl Client { - fn with_limit(limit: Option) -> Self { - Client { - http_client: hyper::Client::new().expect("Unable to initialize http client."), - https_client: https::Client::with_limit(limit).expect("Unable to initialize https client."), + pub fn new() -> Result { + // Max 15MB will be downloaded. + Self::with_limit(Some(15*1024*1024)) + } + + fn with_limit(limit: Option) -> Result { + let mut client = try!(reqwest::Client::new()); + client.redirect(reqwest::RedirectPolicy::limited(5)); + + Ok(Client { + client: Arc::new(client), + pool: CpuPool::new(4), limit: limit, - } - } - - fn convert_url(url: hyper::Url) -> Result { - let host = format!("{}", try!(url.host().ok_or(FetchError::InvalidUrl))); - let port = try!(url.port_or_known_default().ok_or(FetchError::InvalidUrl)); - https::Url::new(&host, port, url.path()).map_err(|_| FetchError::InvalidUrl) - } - - fn temp_path() -> PathBuf { - let mut dir = env::temp_dir(); - dir.push(Self::random_filename()); - dir + }) } } impl Fetch for Client { - fn close(self) { - self.http_client.close(); - self.https_client.close(); - } + type Result = CpuFuture; - fn request_async(&mut self, url: &str, abort: Arc, on_done: Box) -> Result<(), FetchError> { - let is_https = url.starts_with("https://"); - let url = try!(url.parse().map_err(|_| FetchError::InvalidUrl)); - let temp_path = Self::temp_path(); + fn process(&self, f: F) -> BoxFuture<(), ()> where + F: Future + Send + 'static, + { + self.pool.spawn(f).boxed() + } - trace!(target: "fetch", "Fetching from: {:?}", url); + fn fetch_with_abort(&self, url: &str, abort: Abort) -> Self::Result { + debug!(target: "fetch", "Fetching from: {:?}", url); - if is_https { - let url = try!(Self::convert_url(url)); - try!(self.https_client.fetch_to_file( - url, - temp_path.clone(), - abort, - move |result| on_done(result.map(|_| temp_path).map_err(FetchError::Https)), - ).map_err(|e| FetchError::Other(format!("{:?}", e)))); - } else { - try!(self.http_client.request( - url, - FetchHandler::new(temp_path, abort, Box::new(move |result| on_done(result)), self.limit.map(|v| v as u64).clone()), - ).map_err(|e| FetchError::Other(format!("{:?}", e)))); - } - - Ok(()) + self.pool.spawn(FetchTask { + url: url.into(), + client: self.client.clone(), + limit: self.limit, + abort: abort, + }) } } +struct FetchTask { + url: String, + client: Arc, + limit: Option, + abort: Abort, +} + +impl Future for FetchTask { + // TODO [ToDr] timeouts handling? + type Item = Response; + type Error = Error; + + fn poll(&mut self) -> futures::Poll { + if self.abort.is_aborted() { + trace!(target: "fetch", "Fetch of {:?} aborted.", self.url); + return Err(Error::Aborted); + } + + trace!(target: "fetch", "Starting fetch task: {:?}", self.url); + let result = try!(self.client.get(&self.url) + .header(reqwest::header::UserAgent("Parity Fetch".into())) + .send()); + + Ok(futures::Async::Ready(Response { + inner: ResponseInner::Response(result), + abort: self.abort.clone(), + limit: self.limit, + read: 0, + })) + } +} + +#[derive(Debug)] +pub enum Error { + Fetch(reqwest::Error), + Aborted, +} + +impl From for Error { + fn from(error: reqwest::Error) -> Self { + Error::Fetch(error) + } +} + +enum ResponseInner { + Response(reqwest::Response), + Reader(Box), +} + +impl fmt::Debug for ResponseInner { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ResponseInner::Response(ref response) => response.fmt(f), + ResponseInner::Reader(_) => write!(f, "io Reader"), + } + } +} + +#[derive(Debug)] +pub struct Response { + inner: ResponseInner, + abort: Abort, + limit: Option, + read: usize, +} + +impl Response { + pub fn from_reader(reader: R) -> Self { + Response { + inner: ResponseInner::Reader(Box::new(reader)), + abort: Abort::default(), + limit: None, + read: 0, + } + } + + pub fn content_type(&self) -> Option { + match self.inner { + ResponseInner::Response(ref r) => { + let content_type = r.headers().get::(); + content_type.map(|mime| mime.0.clone()) + }, + _ => None, + } + } +} + +impl io::Read for Response { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if self.abort.is_aborted() { + return Err(io::Error::new(io::ErrorKind::ConnectionAborted, "Fetch aborted.")); + } + + let res = match self.inner { + ResponseInner::Response(ref mut response) => response.read(buf), + ResponseInner::Reader(ref mut reader) => reader.read(buf), + }; + + // increase bytes read + if let Ok(read) = res { + self.read += read; + } + + // check limit + match self.limit { + Some(limit) if limit < self.read => { + return Err(io::Error::new(io::ErrorKind::PermissionDenied, "Size limit reached.")); + }, + _ => {}, + } + + res + } +} diff --git a/util/fetch/src/fetch_file.rs b/util/fetch/src/fetch_file.rs deleted file mode 100644 index 84b2270eb..000000000 --- a/util/fetch/src/fetch_file.rs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -//! Hyper Client Handler to Fetch File - -use std::{io, fs, fmt}; -use std::path::PathBuf; -use std::sync::Arc; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::time::Duration; - -use hyper::status::StatusCode; -use hyper::client::{Request, Response, DefaultTransport as HttpStream}; -use hyper::header::Connection; -use hyper::{self, Decoder, Encoder, Next}; - -use super::FetchError; - -#[derive(Debug)] -pub enum Error { - Aborted, - NotStarted, - SizeLimit, - UnexpectedStatus(StatusCode), - IoError(io::Error), - HyperError(hyper::Error), -} - -pub type FetchResult = Result; -pub type OnDone = Box; - -pub struct FetchHandler { - path: PathBuf, - abort: Arc, - file: Option, - result: Option, - on_done: Option, - size_limit: Option, -} - -impl fmt::Debug for FetchHandler { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "Fetch {{ path: {:?}, file: {:?}, result: {:?} }}", self.path, self.file, self.result) - } -} - -impl Drop for FetchHandler { - fn drop(&mut self) { - let res = self.result.take().unwrap_or(Err(Error::NotStarted.into())); - // Remove file if there was an error - if res.is_err() || self.is_aborted() { - if let Some(file) = self.file.take() { - drop(file); - // Remove file - let _ = fs::remove_file(&self.path); - } - } - // send result - if let Some(f) = self.on_done.take() { - f(res); - } - } -} - -impl FetchHandler { - pub fn new(path: PathBuf, abort: Arc, on_done: OnDone, size_limit: Option) -> Self { - FetchHandler { - path: path, - abort: abort, - file: None, - result: None, - on_done: Some(on_done), - size_limit: size_limit, - } - } - - fn is_aborted(&self) -> bool { - self.abort.load(Ordering::SeqCst) - } - - fn mark_aborted(&mut self) -> Next { - self.result = Some(Err(Error::Aborted.into())); - Next::end() - } -} - -impl hyper::client::Handler for FetchHandler { - fn on_request(&mut self, req: &mut Request) -> Next { - if self.is_aborted() { - return self.mark_aborted(); - } - req.headers_mut().set(Connection::close()); - read() - } - - fn on_request_writable(&mut self, _encoder: &mut Encoder) -> Next { - if self.is_aborted() { - return self.mark_aborted(); - } - read() - } - - fn on_response(&mut self, res: Response) -> Next { - if self.is_aborted() { - return self.mark_aborted(); - } - if *res.status() != StatusCode::Ok { - self.result = Some(Err(Error::UnexpectedStatus(*res.status()).into())); - return Next::end(); - } - - // Open file to write - match fs::File::create(&self.path) { - Ok(file) => { - self.file = Some(file); - self.result = Some(Ok(self.path.clone())); - read() - }, - Err(err) => { - self.result = Some(Err(Error::IoError(err).into())); - Next::end() - }, - } - } - - fn on_response_readable(&mut self, decoder: &mut Decoder) -> Next { - if self.is_aborted() { - return self.mark_aborted(); - } - match io::copy(decoder, self.file.as_mut().expect("File is there because on_response has created it.")) { - Ok(0) => Next::end(), - Ok(bytes_read) => match self.size_limit { - None => read(), - // Check limit - Some(limit) if limit > bytes_read => { - self.size_limit = Some(limit - bytes_read); - read() - }, - // Size limit reached - _ => { - self.result = Some(Err(Error::SizeLimit.into())); - Next::end() - }, - }, - Err(e) => match e.kind() { - io::ErrorKind::WouldBlock => Next::read(), - _ => { - self.result = Some(Err(Error::IoError(e).into())); - Next::end() - } - } - } - } - - fn on_error(&mut self, err: hyper::Error) -> Next { - self.result = Some(Err(Error::HyperError(err).into())); - Next::remove() - } -} - -fn read() -> Next { - Next::read().timeout(Duration::from_secs(15)) -} diff --git a/util/fetch/src/lib.rs b/util/fetch/src/lib.rs index bd117a6d2..2461abde1 100644 --- a/util/fetch/src/lib.rs +++ b/util/fetch/src/lib.rs @@ -18,12 +18,12 @@ #[macro_use] extern crate log; -extern crate hyper; -extern crate https_fetch; -extern crate rand; +extern crate futures; +extern crate futures_cpupool; +extern crate mime; +extern crate reqwest; pub mod client; -pub mod fetch_file; -pub use self::client::{Client, Fetch, FetchError, FetchResult}; +pub use self::client::{Client, Fetch, Error, Response, Mime, Abort}; diff --git a/util/https-fetch/examples/fetch.rs b/util/https-fetch/examples/fetch.rs deleted file mode 100644 index 39b8ca946..000000000 --- a/util/https-fetch/examples/fetch.rs +++ /dev/null @@ -1,15 +0,0 @@ -extern crate https_fetch; - -use std::io; -use std::sync::Arc; -use std::sync::atomic::AtomicBool; -use https_fetch::*; - -fn main() { - let client = Client::new().unwrap(); - let aborted = Arc::new(AtomicBool::new(false)); - - client.fetch(Url::new("github.com", 443, "/").unwrap(), Box::new(io::stdout()), aborted, |result| { - assert!(result.is_ok()); - }).unwrap(); -} diff --git a/util/https-fetch/src/ca-certificates.crt b/util/https-fetch/src/ca-certificates.crt deleted file mode 100644 index 964f838a9..000000000 --- a/util/https-fetch/src/ca-certificates.crt +++ /dev/null @@ -1,4496 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE -AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x -CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW -MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF -RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC -AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7 -09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7 -XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P -Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK -t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb -X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28 -MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU -fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI -2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH -K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae -ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP -BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ -MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw -RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv -bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm -fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3 -gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe -I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i -5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi -ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn -MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ -o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6 -zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN -GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt -r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK -Z05phkOTOPu220+DkdRgfks+KzgHVZhepA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx -CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp -ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa -QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw -NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft -ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu -QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG -qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL -fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ -Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4 -Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ -54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b -MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j -ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej -YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt -A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF -rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ -pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB -lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy -YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50 -7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs -YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6 -xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc -unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/ -Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp -ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42 -gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0 -jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+ -XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD -W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/ -RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r -MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk -BYn8eNZcLCZDqQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw -MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD -VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul -CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n -tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl -dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch -PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC -+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O -BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk -ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X -7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz -43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl -pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA -WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx -MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB -ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV -BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV -6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX -GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP -dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH -1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF -62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW -BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL -MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU -cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv -b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 -IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ -iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao -GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh -4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm -XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 -MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK -EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh -BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq -xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G -87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i -2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U -WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 -0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G -A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr -pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL -ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm -aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv -hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm -hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X -dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 -P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y -iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no -xqE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc -MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp -b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT -AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs -aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H -j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K -f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55 -IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw -FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht -QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm -/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ -k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ -MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC -seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ -hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+ -eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U -DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj -B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL -rosot4LKGAfmt1t06SAZf7IbiVQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg -Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL -MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD -VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0 -ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX -l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB -HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B -5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3 -WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD -AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP -gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+ -DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu -BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs -h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk -LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET -MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE -AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw -CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg -YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE -Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX -mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD -XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW -S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp -FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD -AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu -ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z -ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv -Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw -DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6 -yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq -EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB -EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN -PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy -MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk -D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o -OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A -fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe -IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n -oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK -/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj -rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD -3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE -7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC -yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd -qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI -hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR -xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA -SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo -HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB -emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC -AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb -7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x -DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk -F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF -a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT -Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD -TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2 -MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF -Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh -IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6 -dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO -V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC -GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN -v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB -AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB -Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO -76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK -OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH -ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi -yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL -buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj -2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn -MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL -ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg -b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa -MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB -ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw -IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B -AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb -unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d -BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq -7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 -0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX -roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG -A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j -aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p -26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA -BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud -EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN -BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz -aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB -AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd -p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi -1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc -XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 -eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu -tGWaIZDgqtCYvDi1czyL+Nw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn -MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL -ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo -YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 -MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy -NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G -A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA -A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 -Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s -QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV -eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 -B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh -z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T -AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i -ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w -TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH -MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD -VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE -VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh -bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B -AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM -bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi -ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG -VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c -ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ -AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV -BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X -DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ -BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 -QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny -gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw -zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q -130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 -JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw -ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT -AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj -AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG -9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h -bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc -fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu -HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w -t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET -MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk -BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 -Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl -cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 -aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY -F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N -8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe -rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K -/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu -7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC -28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 -lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E -nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB -0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 -5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj -WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN -jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ -KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s -ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM -OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q -619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn -2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj -o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v -nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG -5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq -pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb -dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 -BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw -PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz -cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 -MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz -IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ -ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR -VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL -kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd -EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas -H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 -HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud -DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 -QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu -Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ -AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 -yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR -FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA -ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB -kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM -MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD -QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM -MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD -QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E -jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo -ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI -ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu -Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg -AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 -HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA -uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa -TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg -xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q -CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x -O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs -6GAqm4VKQPNriiTsBhYscw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz -IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz -MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj -dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw -EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp -MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 -28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq -VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q -DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR -5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL -ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a -Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl -UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s -+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 -Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx -hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV -HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 -+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN -YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t -L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy -ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt -IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV -HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w -DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW -PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF -5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 -glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH -FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 -pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD -xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG -tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq -jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De -fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ -d0jQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC -Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g -Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0 -aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa -Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg -SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo -aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp -ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z -7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA// -DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx -zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8 -hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs -4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u -gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY -NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E -FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3 -j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG -52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB -echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws -ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI -zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy -wy39FCqQmbkHzJ8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 -MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG -EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT -CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK -8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 -98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb -2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC -ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi -Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB -o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl -ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD -AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL -AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd -foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M -cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq -8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp -hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk -Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U -AGegcQCCSA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp -ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow -fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV -BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM -cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S -HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 -CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk -3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz -6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV -HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud -EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv -Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw -Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww -DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 -5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj -Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI -gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ -aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl -izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 -aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla -MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO -BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD -VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW -fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt -TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL -fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW -1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 -kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G -A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v -ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo -dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu -Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ -HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 -pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS -jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ -xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn -dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG -A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh -bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE -ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS -b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 -7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS -J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y -HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP -t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz -FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY -XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw -hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js -MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA -A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj -Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx -XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o -omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc -A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx -ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w -MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD -VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx -FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu -ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7 -gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH -fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a -ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT -ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk -c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto -dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt -aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI -hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk -QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/ -h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq -nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR -rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 -9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O -rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq -OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b -xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw -7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD -aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG -SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 -ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr -AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz -R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 -JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo -Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc -MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj -IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB -IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE -RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl -U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 -IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU -ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC -QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr -rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S -NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc -QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH -txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP -BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp -tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa -IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl -6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ -xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV -BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt -ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4 -MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg -SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl -a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h -4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk -tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s -tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL -dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4 -c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um -TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z -+kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O -Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW -OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW -fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2 -l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB -/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw -FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+ -8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI -6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO -TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME -wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY -Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn -xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q -DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q -Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t -hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4 -7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7 -QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB -8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy -dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 -YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 -dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh -IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD -LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG -EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g -KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD -ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu -bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg -ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R -85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm -4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV -HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd -QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t -lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB -o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 -opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo -dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW -ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN -AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y -/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k -SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy -Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS -Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl -nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 -czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG -CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy -MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl -ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS -b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy -euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO -bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw -WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d -MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE -1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ -zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB -BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF -BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV -v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG -E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW -iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v -GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy -dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 -MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx -dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f -BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A -cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ -MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw -ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj -IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y -7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh -1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT -ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw -MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj -dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l -c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC -UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc -58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ -o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr -aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA -A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA -Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv -8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT -ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw -MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j -LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ -KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo -RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu -WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw -Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK -eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM -zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ -WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN -/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg -R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 -9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq -fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv -iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU -1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ -bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW -MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA -ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l -uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn -Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS -tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF -PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un -hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV -5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs -IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg -R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A -PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 -Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL -TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL -5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 -S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe -2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap -EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td -EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv -/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN -A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 -abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF -I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz -4iIprn2DQKi6bA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo -R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx -MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 -AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA -ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 -7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W -kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI -mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ -KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 -6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl -4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K -oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj -UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU -AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL -MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj -KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 -MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw -NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV -BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH -MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL -So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal -tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG -CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT -qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz -rD6ogRLQy7rQkgu2npaqBA+K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB -mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT -MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ -BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 -BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz -+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm -hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn -5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W -JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL -DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC -huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB -AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB -zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN -kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH -SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G -spki4cErx5z481+oghLrGREt ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy -c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 -IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV -VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 -cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT -QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh -F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v -c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w -mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd -VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX -teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ -f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe -Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ -nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB -/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY -MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG -9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX -IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn -ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z -uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN -Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja -QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW -koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 -ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt -DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm -bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy -c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD -VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 -c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 -WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG -FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq -XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL -se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb -KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd -IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 -y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt -hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc -QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 -Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV -HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ -KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ -L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr -Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo -ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY -T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz -GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m -1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV -OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH -6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX -QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx -MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed -KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 -G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 -zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 -ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG -HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 -Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V -yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e -beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r -6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog -zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW -BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr -ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp -ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk -cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt -YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC -CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI -hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ -UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz -X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x -fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz -a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd -Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd -SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O -AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso -M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge -v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT -AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ -TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG -9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw -MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM -BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO -MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2 -LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI -s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2 -xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4 -u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b -F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx -Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd -PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV -HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx -NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF -AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ -L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY -YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg -Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a -NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R -0982gaEbeC9xs/FZTEYYKKuF0mBWWg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 -MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 -ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD -VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j -b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq -scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO -xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H -LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX -uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD -yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ -JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q -rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN -BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L -hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB -QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ -HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu -Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg -QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB -BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA -A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb -laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 -awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo -JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw -LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT -VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk -LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb -UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ -QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ -naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls -QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN -AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp -dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw -MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw -CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ -MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB -SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz -ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH -LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP -PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL -2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w -ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC -MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk -AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0 -AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz -AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz -AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f -BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE -FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY -P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi -CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g -kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95 -HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS -na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q -qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z -TbvGRNs2yyqcjg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw -cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy -b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z -ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4 -NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN -TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p -Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u -uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+ -LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA -vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770 -Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx -62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB -AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw -LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP -BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB -AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov -MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5 -ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn -AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT -AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh -ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo -AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa -AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln -bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p -Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP -PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv -Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB -EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu -w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj -cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV -HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI -VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS -BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS -b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS -8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds -ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl -7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a -86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR -hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/ -MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx -ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 -b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD -EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05 -OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G -A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh -Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l -dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG -SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK -gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX -iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc -Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E -BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G -SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu -b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh -bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv -Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln -aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0 -IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh -c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph -biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo -ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP -UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj -YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo -dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA -bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06 -sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa -n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS -NitjrFgBazMpUIaD8QFI ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx -ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 -b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD -EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X -DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw -DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u -c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr -TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA -OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC -2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW -RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P -AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW -ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0 -YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz -b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO -ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB -IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs -b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs -ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s -YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg -a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g -SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0 -aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg -YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg -Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY -ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g -pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4 -Fp1hBWeAyNDYpQcCNJgEjTME1A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV -MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe -TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 -dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 -N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC -dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu -MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL -b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD -zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi -3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 -WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY -Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi -NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC -ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 -QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 -YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz -aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm -ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg -ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs -amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv -IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 -Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 -ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 -YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg -dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs -b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G -CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO -xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP -0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ -QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk -f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK -8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx -ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 -b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD -EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz -aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w -MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G -A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh -Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l -dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh -bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq -eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe -r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5 -3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd -vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l -mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC -wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg -hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0 -TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh -biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg -ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg -dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6 -b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl -c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0 -ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3 -dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu -ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh -bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo -ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3 -Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u -ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA -A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ -MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+ -NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR -VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY -83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3 -macqaJVmlaut74nLYKkGEsaUR+ko ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi -MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV -UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO -ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz -c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP -OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl -mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF -BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 -qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw -gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu -bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp -dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 -6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ -h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH -/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN -pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB -ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly -aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl -ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w -NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G -A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD -VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX -SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR -VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 -w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF -mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg -4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 -4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw -EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx -SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 -ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 -vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi -Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ -/L7fCg0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1 -dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s -YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz -dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0 -aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh -IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ -KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw -MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy -b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx -KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG -A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u -aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9 -7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74 -BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G -ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9 -JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0 -PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2 -0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH -0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/ -6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m -v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7 -K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev -bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw -MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w -MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD -gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0 -b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh -bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0 -cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp -ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg -ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq -hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD -AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w -MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag -RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t -UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl -cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v -Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG -AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN -AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS -1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB -3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv -Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh -HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm -pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz -sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE -qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb -mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9 -opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H -YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz -MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw -IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR -dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp -li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D -rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ -WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug -F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU -xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC -Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv -dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw -ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl -IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh -c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy -ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI -KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T -KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq -y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p -dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD -VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk -fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 -7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R -cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y -mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW -xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK -SnQ2+Q== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa -GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg -Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J -WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB -rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp -+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 -ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i -Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz -PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og -/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH -oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI -yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud -EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 -A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL -MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f -BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn -g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl -fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K -WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha -B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc -hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR -TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD -mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z -ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y -4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza -8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM -V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB -4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr -H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd -8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv -vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT -mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe -btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc -T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt -WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ -c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A -4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD -VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG -CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 -aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu -dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw -czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G -A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg -Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 -7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem -d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd -+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B -4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN -t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x -DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 -k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s -zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j -Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT -mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK -4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6 -MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp -dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX -BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy -MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp -eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg -/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl -wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh -AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2 -PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu -AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR -MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc -HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/ -Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+ -f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO -rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch -6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3 -7CAFYd4= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF -UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ -R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN -MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G -A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw -JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+ -WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj -SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl -u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy -A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk -Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7 -MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr -aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC -IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A -cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA -YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA -bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA -bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA -aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA -aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA -ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA -YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA -ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA -LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6 -Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y -eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw -CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G -A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu -Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn -lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt -b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg -9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF -ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC -IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCB -rjELMAkGA1UEBhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcp -MRIwEAYDVQQHEwlTdHV0dGdhcnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fz -c2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVTLVRSVVNUIEF1dGhlbnRpY2F0aW9u -IGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0wNTA2MjIwMDAwMDBa -Fw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4t -V3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMg -RGV1dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJV -U1QgQXV0aGVudGljYXRpb24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBO -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1 -toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob4QSwI7+Vio5bG0F/WsPo -TUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXLg3KSwlOy -ggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1 -XgqfeN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteF -hy+S8dF2g08LOlk3KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm -7QIDAQABo4GSMIGPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEG -MCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJvbmxpbmUxLTIwNDgtNTAdBgNV -HQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAUD8oeXHngovMp -ttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD -pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFo -LtU96G7m1R08P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersF -iXOMy6ZNwPv2AtawB6MDwidAnwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0y -h9WUUpY6RsZxlj33mA6ykaqP2vROJAA5VeitF7nTNCtKqUDMFypVZUF0Qn71wK/I -k63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8bHz2eBIPdltkdOpQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr -MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG -A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 -MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp -Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD -QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz -i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 -h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV -MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 -UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni -8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC -h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB -AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm -KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ -X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr -QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 -pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN -QSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz -MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N -IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11 -bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE -RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO -zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5 -bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF -MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1 -VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC -OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G -CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW -tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ -q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb -EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+ -Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O -VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP -MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx -MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV -BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG -29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk -oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk -3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL -qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN -nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw -DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG -MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX -ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H -DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO -TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv -kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w -zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP -MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx -MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV -BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o -Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt -5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s -3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej -vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu -8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw -DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG -MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil -zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ -3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD -FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 -Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 -ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO -TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy -MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk -ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn -ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 -9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO -hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U -tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o -BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh -SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww -OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv -cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA -7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k -/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm -eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 -u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy -7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX -DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 -qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp -uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU -Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE -pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp -5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M -UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN -GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy -5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv -6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK -eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 -B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ -BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov -L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG -SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS -CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen -5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 -IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK -gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL -+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL -vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm -bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk -N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC -Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z -ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j -ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js -LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM -BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy -dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh -cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh -YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg -dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp -bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ -YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT -TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ -9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 -jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW -FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz -ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 -ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L -EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu -L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC -O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V -um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh -NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul -F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC -ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w -ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk -aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 -YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg -c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 -d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG -CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF -wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS -Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst -0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc -pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl -CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF -P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK -1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm -KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ -8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm -fyWl8kgAwKQB2j8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 -OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG -A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ -JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD -vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo -D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ -Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW -RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK -HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN -nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM -0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i -UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 -Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg -TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL -BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K -2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX -UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl -6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK -9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ -HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI -wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY -XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l -IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo -hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr -so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln -biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF -MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT -d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 -76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ -bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c -6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE -emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd -MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt -MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y -MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y -FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi -aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM -gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB -qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 -lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn -8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 -45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO -UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 -O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC -bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv -GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a -77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC -hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 -92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp -Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w -ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt -Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu -IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw -WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD -ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y -IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn -IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ -6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob -jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw -izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl -+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY -zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP -pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF -KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW -ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB -AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 -ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW -IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA -A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 -uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ -FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 -jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ -u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D -YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 -puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa -icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG -DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x -kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z -Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu -IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow -RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY -U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv -Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br -YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF -nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH -6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt -eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ -c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ -MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH -HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf -jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 -5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB -rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c -wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB -AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp -WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 -xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ -2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ -IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 -aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X -em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR -dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ -OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ -hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy -tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk -MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 -YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg -Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT -AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp -Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 -m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih -FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ -TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F -EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco -kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu -HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF -vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo -19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC -L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW -bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX -JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw -FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j -BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc -K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf -ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik -Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB -sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e -3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR -ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip -mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH -b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf -rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms -hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y -zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 -MBr1mmz0DlP5OlvRHA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk -MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 -YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg -Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT -AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp -Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr -jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r -0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f -2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP -ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF -y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA -tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL -6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0 -uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL -acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh -k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q -VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw -FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O -BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh -b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R -fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv -/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI -REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx -srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv -aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT -woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n -Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W -t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N -8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2 -9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5 -wSsSnqaeG8XmDtkx2Q== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw -ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp -dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290 -IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD -VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy -dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg -MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx -UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD -1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH -oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR -HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/ -5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv -idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL -OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC -NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f -46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB -UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth -7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G -A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED -MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB -bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x -XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T -PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0 -Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70 -WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL -Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm -7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S -nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN -vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB -WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI -fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb -I+2ksx0WckNLIOFZfsLorSa/ovc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW -Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q -Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 -1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq -ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 -Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX -XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN -irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 -TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 -g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB -95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj -S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc -UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS -S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg -SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx -OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry -b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC -VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE -sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F -ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY -KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG -+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG -HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P -IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M -733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk -Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G -CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW -AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I -aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5 -mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa -XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ -qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ -MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow -PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR -IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q -gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy -yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts -F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 -jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx -ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC -VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK -YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH -EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN -Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud -DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE -MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK -UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf -qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK -ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE -JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 -hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 -EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm -nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX -udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz -ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe -LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl -pYYsfPQS ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS -MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp -bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw -VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy -YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy -dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2 -ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe -Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx -GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls -aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU -QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh -xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0 -aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr -IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h -gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK -O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO -fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw -lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL -hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID -AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP -NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t -wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM -7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh -gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n -oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs -yZyQ2uypQjyttgI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB -rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt -Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa -Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV -BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l -dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE -AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B -YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9 -hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l -L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm -SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM -1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws -6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw -Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50 -aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH -AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u -7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0 -xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ -rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim -eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk -USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG -A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe -MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v -d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh -cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn -0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ -M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a -MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd -oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI -DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy -oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 -dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy -bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF -BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli -CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE -CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t -3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS -KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp -U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg -SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln -biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm -GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve -fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ -aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj -aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW -kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC -4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga -FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 -nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex -t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz -SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG -BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ -rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ -NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH -BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv -MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE -p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y -5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK -WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ -4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N -hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB -vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W -ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX -MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 -IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y -IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh -bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF -9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH -H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H -LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN -/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT -rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw -WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs -exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 -sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ -seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz -4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ -BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR -lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 -7M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz -cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 -MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV -BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN -ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f -zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi -TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G -CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW -NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV -Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh -c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy -MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp -emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X -DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw -FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg -UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo -YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 -MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB -AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK -VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm -Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID -AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J -h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul -uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68 -DzFc6PLZ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 -nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO -8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV -ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb -PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 -6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr -n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a -qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 -wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 -ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs -pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 -E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns -YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH -MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y -aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe -Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX -MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj -IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx -KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM -HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw -DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC -AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji -nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX -rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn -jBJ7xUS0rg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy -aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s -IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp -Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV -BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp -Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu -Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g -Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt -IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU -J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO -JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY -wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o -koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN -qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E -Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe -xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u -7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU -sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI -sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP -cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz -cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 -MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV -BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN -ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE -BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is -I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G -CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do -lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc -AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh -c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy -MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp -emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X -DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw -FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg -UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo -YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 -MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB -AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 -pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 -13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID -AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk -U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i -F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY -oJ2daZH9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b -N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t -KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu -kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm -CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ -Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu -imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te -2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe -DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p -F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt -TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz -cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 -MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV -BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN -ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE -BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is -I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G -CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i -2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ -2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr -MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl -cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw -CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h -dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l -cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h -2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E -lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV -ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq -299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t -vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL -dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF -AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR -zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 -LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd -7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw -++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx -IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs -cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v -dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0 -MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl -bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD -DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r -WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU -Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs -HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj -z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf -SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl -AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG -KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P -AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j -BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC -VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX -ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB -ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd -/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB -A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn -k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9 -iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv -2G0xffX8oRAHh84vWdw+WNs= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT -AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD -QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP -MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do -0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ -UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d -RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ -OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv -JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C -AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O -BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ -LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY -MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ -44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I -Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw -i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN -9u6wWk5JRFRYX0KD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw -NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j -LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG -A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs -W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta -3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk -6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 -Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J -NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP -r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU -DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz -YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 -/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ -LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 -jVaMaA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp -IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi -BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw -MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig -YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v -dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ -BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 -papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K -DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 -KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox -XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB -rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV -BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa -Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl -LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u -MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm -gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 -YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf -b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 -9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S -zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk -OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA -2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW -oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c -KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM -m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu -MdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE -AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw -CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ -BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND -VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb -qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY -HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo -G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA -lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr -IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ -0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH -k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 -4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO -m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa -cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl -uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI -KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls -ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG -AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT -VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG -CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA -cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA -QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA -7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA -cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA -QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA -czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu -aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt -aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud -DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF -BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp -D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU -JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m -AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD -vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms -tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH -7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA -h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF -d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H -pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE -AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG -EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM -FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC -REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp -Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM -VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ -SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ -4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L -cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi -eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG -A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 -DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j -vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP -DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc -maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D -lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv -KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG -MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV -BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw -MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl -ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r -D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1 -9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf -v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk -UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L -NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb -+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V -qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K -yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G -AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK -J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC -AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4 -WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 -yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj -/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6 -jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2 -ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX -X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n -FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D -u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l -O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le -ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1 -2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV -MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV -BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw -MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX -b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN -rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U -fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc -f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2 -ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M -x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR -aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch -zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar -uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K -mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA -Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv -HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H -EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 -LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ -MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e -JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN -g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp -dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab -R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ -PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce -xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+ -J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl -OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT -ee5Ehr7XHuQe+w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQsw -CQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMT -EkNBIFdvU2lnbiBFQ0MgUm9vdDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4 -NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEb -MBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACID -YgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiUt5v8 -KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES -1ns2o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQUqv3VWqP2h4syhf3RMluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB -1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0Daupn75OcsqF1NnstTJFGG+rrQIwfcf3 -aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYua/GRspBl9JrmkO5K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBY -MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNV -BAMTJENlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDEx -MDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgxCzAJBgNVBAYTAkNOMRowGAYDVQQK -ExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPX -JYY1kBaiXW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgO -gHzKtB0TiGsOqCR3A9DuW/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg -5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg95k4ot+vElbGs/V6r+kHLXZ1L3PR8du9n -fwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BKv0mUYQs4kI9dJGwlezt5 -2eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJ -KoZIhvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8 -fHulwqZm46qwtyeYP0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G -3CE4Q3RM+zD4F3LBMvzIkRfEzFg3TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yy -SrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu+sif/a+RZQp4OBXllxcU3fng -LDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+7Q9LGOHSJDy7 -XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET -MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb -BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz -MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx -FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g -Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 -fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl -LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV -WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF -TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb -5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc -CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri -wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ -wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG -m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 -F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng -WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 -2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF -AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ -0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw -F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS -g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj -qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN -h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ -ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V -btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj -Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ -8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW -gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX -DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP -cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW -IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX -xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy -KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR -9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az -5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 -6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 -Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP -bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt -BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt -XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd -INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD -U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp -LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 -Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp -gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh -/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw -0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A -fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq -4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR -1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ -QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM -94B7IWcnMFk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2DCCAsCgAwIBAgIQYFbFSyNAW2TU7SXa2dYeHjANBgkqhkiG9w0BAQsFADCB -hTELMAkGA1UEBhMCREUxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZl -cmxhZyBHbWJIMScwJQYDVQQLEx5TLVRSVVNUIENlcnRpZmljYXRpb24gU2Vydmlj -ZXMxIjAgBgNVBAMTGVMtVFJVU1QgVW5pdmVyc2FsIFJvb3QgQ0EwHhcNMTMxMDIy -MDAwMDAwWhcNMzgxMDIxMjM1OTU5WjCBhTELMAkGA1UEBhMCREUxKTAnBgNVBAoT -IERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMScwJQYDVQQLEx5TLVRS -VVNUIENlcnRpZmljYXRpb24gU2VydmljZXMxIjAgBgNVBAMTGVMtVFJVU1QgVW5p -dmVyc2FsIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo -4wvfETeFgpq1bGZ8YT/ARxodRuOwVWTluII5KAd+F//0m4rwkYHqOD8heGxI7Gsv -otOKcrKn19nqf7TASWswJYmM67fVQGGY4tw8IJLNZUpynxqOjPolFb/zIYMoDYuv -WRGCQ1ybTSVRf1gYY2A7s7WKi1hjN0hIkETCQN1d90NpKZhcEmVeq5CSS2bf1XUS -U1QYpt6K1rtXAzlZmRgFDPn9FcaQZEYXgtfCSkE9/QC+V3IYlHcbU1qJAfYzcg6T -OtzoHv0FBda8c+CI3KtP7LUYhk95hA5IKmYq3TLIeGXIC51YAQVx7YH1aBduyw20 -S9ih7K446xxYL6FlAzQvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P -AQH/BAQDAgEGMB0GA1UdDgQWBBSafdfr639UmEUptCCrbQuWIxmkwjANBgkqhkiG -9w0BAQsFAAOCAQEATpYS2353XpInniEXGIJ22D+8pQkEZoiJrdtVszNqxmXEj03z -MjbceQSWqXcy0Zf1GGuMuu3OEdBEx5LxtESO7YhSSJ7V/Vn4ox5R+wFS5V/let2q -JE8ii912RvaloA812MoPmLkwXSBvwoEevb3A/hXTOCoJk5gnG5N70Cs0XmilFU/R -UsOgyqCDRR319bdZc11ZAY+qwkcvFHHVKeMQtUeTJcwjKdq3ctiR1OwbSIoi5MEq -9zpok59FGW5Dt8z+uJGaYRo2aWNkkijzb2GShROfyQcsi1fc65551cLeCNVUsldO -KjKNoeI60RAgIjl9NEVvcTvDHfz/sk+o4vYwHg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE -BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn -aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg -QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg -SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0 -MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD -VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 -dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom -/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR -Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3 -4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z -5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0 -hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID -AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX -SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l -VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq -URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf -peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF -Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW -+qtB4Uu2NQvAmxU= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQG -EwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdp -IMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBB -LsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBI -aXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5MDQxMFoXDTIzMTIx -NjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBLBgNV -BAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2 -ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVs -ZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdsGjW6L0UlqMACprx9MfMkU1x -eHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a2uqsxgbPJQ1BgfbBOCK9 -+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EEDwnS3/faA -z1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0p -u5FbHH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6p -lVxiSvgNZ1GpryHV+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMB -AAGjQjBAMB0GA1UdDgQWBBTdVRcT9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb1gNl0Oq -FlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3RfdCaqaXKGDsC -QC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy -o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKID -gI6tflEATseWhvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm -9ocJV612ph1jmv3XZch4gyt1O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsG -tAuYSyher4hYyw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- diff --git a/util/https-fetch/src/ca-github.crt b/util/https-fetch/src/ca-github.crt deleted file mode 100644 index ae298d829..000000000 --- a/util/https-fetch/src/ca-github.crt +++ /dev/null @@ -1,93 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW -YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY -uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ -LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy -/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh -cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k -8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB -Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF -BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp -Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy -dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 -MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j -b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW -gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh -hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg -4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa -2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs -1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 -oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn -8TUoE6smftX3eg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHeTCCBmGgAwIBAgIQC/20CQrXteZAwwsWyVKaJzANBgkqhkiG9w0BAQsFADB1 -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk -IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MDMxMDAwMDAwMFoXDTE4MDUxNzEy -MDAwMFowgf0xHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB -BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF -Ewc1MTU3NTUwMSQwIgYDVQQJExs4OCBDb2xpbiBQIEtlbGx5LCBKciBTdHJlZXQx -DjAMBgNVBBETBTk0MTA3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p -YTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMu -MRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA54hc8pZclxgcupjiA/F/OZGRwm/ZlucoQGTNTKmBEgNsrn/mxhngWmPw -bAvUaLP//T79Jc+1WXMpxMiz9PK6yZRRFuIo0d2bx423NA6hOL2RTtbnfs+y0PFS -/YTpQSelTuq+Fuwts5v6aAweNyMcYD0HBybkkdosFoDccBNzJ92Ac8I5EVDUc3Or -/4jSyZwzxu9kdmBlBzeHMvsqdH8SX9mNahXtXxRpwZnBiUjw36PgN+s9GLWGrafd -02T0ux9Yzd5ezkMxukqEAQ7AKIIijvaWPAJbK/52XLhIy2vpGNylyni/DQD18bBP -T+ZG1uv0QQP9LuY/joO+FKDOTler4wIDAQABo4IDejCCA3YwHwYDVR0jBBgwFoAU -PdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFIhcSGcZzKB2WS0RecO+oqyH -IidbMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0f -BG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2Vy -dmVyLWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt -ZXYtc2VydmVyLWcxLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsG -AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGI -BggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 -LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp -Z2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMB -Af8EAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgCkuQmQtBhYFIe7E6LM -Z3AKPDWYBPkb37jjd80OyA3cEAAAAVNhieoeAAAEAwBHMEUCIQCHHSEY/ROK2/sO -ljbKaNEcKWz6BxHJNPOtjSyuVnSn4QIgJ6RqvYbSX1vKLeX7vpnOfCAfS2Y8lB5R -NMwk6us2QiAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVNh -iennAAAEAwBHMEUCIQDZpd5S+3to8k7lcDeWBhiJASiYTk2rNAT26lVaM3xhWwIg -NUqrkIODZpRg+khhp8ag65B8mu0p4JUAmkRDbiYnRvYAdwBWFAaaL9fC7NP14b1E -sj7HRna5vJkRXMDvlJhV1onQ3QAAAVNhieqZAAAEAwBIMEYCIQDnm3WStlvE99GC -izSx+UGtGmQk2WTokoPgo1hfiv8zIAIhAPrYeXrBgseA9jUWWoB4IvmcZtshjXso -nT8MIG1u1zF8MA0GCSqGSIb3DQEBCwUAA4IBAQCLbNtkxuspqycq8h1EpbmAX0wM -5DoW7hM/FVdz4LJ3Kmftyk1yd8j/PSxRrAQN2Mr/frKeK8NE1cMji32mJbBqpWtK -/+wC+avPplBUbNpzP53cuTMF/QssxItPGNP5/OT9Aj1BxA/NofWZKh4ufV7cz3pY -RDS4BF+EEFQ4l5GY+yp4WJA/xSvYsTHWeWxRD1/nl62/Rd9FN2NkacRVozCxRVle -FrBHTFxqIP6kDnxiLElBrZngtY07ietaYZVLQN/ETyqLQftsf8TecwTklbjvm8NT -JqbaIVifYwqwNN+4lRxS3F5lNlA/il12IOgbRioLI62o8G0DaEUQgHNf8vSG ------END CERTIFICATE----- diff --git a/util/https-fetch/src/client.rs b/util/https-fetch/src/client.rs deleted file mode 100644 index e167ce31b..000000000 --- a/util/https-fetch/src/client.rs +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -use std::cell::RefCell; -use std::{fs, str, thread}; -use std::sync::Arc; -use std::sync::atomic::AtomicBool; -use std::path::PathBuf; -use std::io::{self, Write}; -use std::collections::HashMap; - -use mio; -use tlsclient::{TlsClient, TlsClientError}; - -use url::Url; - -#[derive(Debug)] -pub enum FetchError { - InvalidAddress, - ReadingCaCertificates, - UnexpectedStatus(String), - CaCertificates(io::Error), - Io(io::Error), - Notify(mio::NotifyError), - Client(TlsClientError), -} - -impl From for FetchError { - fn from(e: io::Error) -> Self { - FetchError::Io(e) - } -} - -impl From> for FetchError { - fn from(e: mio::NotifyError) -> Self { - FetchError::Notify(e) - } -} - -impl From for FetchError { - fn from(e: TlsClientError) -> Self { - FetchError::Client(e) - } -} - -pub type FetchResult = Result<(), FetchError>; - -pub enum ClientMessage { - Fetch(Url, Box, Arc, Box), - Shutdown, -} - -pub struct Client { - channel: mio::Sender, - thread: Option>, -} - -impl Drop for Client { - fn drop(&mut self) { - self.close_internal(); - if let Some(thread) = self.thread.take() { - thread.join().expect("Clean shutdown."); - } - } -} - -impl Client { - pub fn new() -> Result { - Self::with_limit(None) - } - - pub fn with_limit(size_limit: Option) -> Result { - let mut event_loop = try!(mio::EventLoop::new()); - let channel = event_loop.channel(); - - let thread = thread::spawn(move || { - let mut client = ClientLoop { - next_token: 0, - sessions: HashMap::new(), - size_limit: size_limit, - }; - event_loop.run(&mut client).unwrap(); - }); - - Ok(Client { - channel: channel, - thread: Some(thread), - }) - } - - pub fn fetch_to_file(&self, url: Url, path: PathBuf, abort: Arc, callback: F) -> Result<(), FetchError> { - let file = try!(fs::File::create(&path)); - self.fetch(url, Box::new(file), abort, move |result| { - if let Err(_) = result { - // remove temporary file - let _ = fs::remove_file(&path); - } - callback(result); - }) - } - - pub fn fetch(&self, url: Url, writer: Box, abort: Arc, callback: F) -> Result<(), FetchError> { - let cell = RefCell::new(Some(callback)); - try!(self.channel.send(ClientMessage::Fetch(url, writer, abort, Box::new(move |res| { - cell.borrow_mut().take().expect("Called only once.")(res); - })))); - Ok(()) - } - - pub fn close(mut self) { - self.close_internal() - } - - fn close_internal(&mut self) { - if let Err(e) = self.channel.send(ClientMessage::Shutdown) { - warn!("Error while closing client: {:?}. Already stopped?", e); - } - } -} - -pub struct ClientLoop { - next_token: usize, - sessions: HashMap, - size_limit: Option, -} - -impl mio::Handler for ClientLoop { - type Timeout = (); - type Message = ClientMessage; - - fn ready(&mut self, event_loop: &mut mio::EventLoop, token: mio::Token, events: mio::EventSet) { - let utoken = token.as_usize(); - let remove = if let Some(mut tlsclient) = self.sessions.get_mut(&utoken) { - tlsclient.ready(event_loop, token, events) - } else { - false - }; - - if remove { - self.sessions.remove(&utoken); - } - } - - fn notify(&mut self, event_loop: &mut mio::EventLoop, msg: Self::Message) { - match msg { - ClientMessage::Shutdown => event_loop.shutdown(), - ClientMessage::Fetch(url, writer, abort, callback) => { - let token = self.next_token; - self.next_token += 1; - - if let Ok(mut tlsclient) = TlsClient::new(mio::Token(token), &url, writer, abort, callback, self.size_limit.clone()) { - let httpreq = format!( - "GET {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nUser-Agent: {}/{}\r\nAccept-Encoding: identity\r\n\r\n", - url.path(), - url.hostname(), - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_VERSION") - ); - debug!("Requesting content: {}", httpreq); - let _ = tlsclient.write(httpreq.as_bytes()); - tlsclient.register(event_loop); - - self.sessions.insert(token, tlsclient); - } - } - } - } -} - -#[test] -fn should_successfuly_fetch_a_page() { - use std::io::{self, Cursor}; - use std::sync::{mpsc, Arc}; - use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering}; - - struct Writer { - wrote: Arc, - data: Cursor>, - } - - impl io::Write for Writer { - fn write(&mut self, buf: &[u8]) -> io::Result { - let res = self.data.write(buf); - if let Ok(count) = res { - self.wrote.fetch_add(count, Ordering::Relaxed); - } - res - } - fn flush(&mut self) -> io::Result<()> { Ok(()) } - } - - let client = Client::new().unwrap(); - - let wrote = Arc::new(AtomicUsize::new(0)); - let writer = Writer { - wrote: wrote.clone(), - data: Cursor::new(Vec::new()), - }; - let (tx, rx) = mpsc::channel(); - client.fetch(Url::new("github.com", 443, "/").unwrap(), Box::new(writer), Arc::new(AtomicBool::new(false)), move |result| { - assert!(result.is_ok()); - assert!(wrote.load(Ordering::Relaxed) > 0); - tx.send(result).unwrap(); - }).unwrap(); - let _ = rx.recv().unwrap(); -} - diff --git a/util/https-fetch/src/http.rs b/util/https-fetch/src/http.rs deleted file mode 100644 index cf743b546..000000000 --- a/util/https-fetch/src/http.rs +++ /dev/null @@ -1,399 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -//! HTTP format processor - -use std::io::{self, Cursor, Write}; -use std::cmp; - -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum State { - WaitingForStatus, - WaitingForHeaders, - WaitingForChunk, - WritingBody, - WritingChunk(usize), - Finished, -} - -pub struct HttpProcessor { - state: State, - buffer: Cursor>, - status: Option, - headers: Vec, - body_writer: io::BufWriter>, - size_limit: Option, -} - -const BREAK_LEN: usize = 2; - -impl HttpProcessor { - pub fn new(body_writer: Box, size_limit: Option) -> Self { - HttpProcessor { - state: State::WaitingForStatus, - buffer: Cursor::new(Vec::new()), - status: None, - headers: Vec::new(), - body_writer: io::BufWriter::new(body_writer), - size_limit: size_limit, - } - } - - pub fn status(&self) -> Option<&String> { - self.status.as_ref() - } - - pub fn status_is_ok(&self) -> bool { - self.status == Some("HTTP/1.1 200 OK".into()) - } - - #[cfg(test)] - pub fn headers(&self) -> &[String] { - &self.headers - } - - fn find_break_index(&mut self) -> Option { - let data = self.buffer.get_ref(); - let mut idx = 0; - let mut got_r = false; - // looks for \r\n in data - for b in data { - idx += 1; - if got_r && b == &10u8 { - return Some(idx); - } else if !got_r && b == &13u8 { - got_r = true; - } else { - got_r = false; - } - } - None - } - - // Consumes bytes from internal buffer - fn buffer_consume(&mut self, bytes: usize) { - let bytes = cmp::min(bytes, self.buffer.get_ref().len()); - // Drain data - self.buffer.get_mut().drain(0..bytes); - let len = self.buffer.position(); - self.buffer.set_position(len - bytes as u64); - } - - fn buffer_to_string(&mut self, bytes: usize) -> String { - let val = String::from_utf8_lossy(&self.buffer.get_ref()[0..bytes-BREAK_LEN]).into_owned(); - self.buffer_consume(bytes); - val - } - - fn is_chunked(&self) -> bool { - self.headers - .iter() - .find(|item| item.to_lowercase().contains("transfer-encoding: chunked")) - .is_some() - } - fn set_state(&mut self, state: State) { - self.state = state; - trace!("Changing state to {:?}", state); - } - - fn process_buffer(&mut self) -> io::Result<()> { - // consume data and perform state transitions - loop { - match self.state { - State::WaitingForStatus => { - if let Some(break_index) = self.find_break_index() { - let status = self.buffer_to_string(break_index); - debug!("Read status: {:?}", status); - self.status = Some(status); - self.set_state(State::WaitingForHeaders); - } else { - // wait for more data - return Ok(()); - } - }, - State::WaitingForHeaders => { - match self.find_break_index() { - // Last header - got empty line, body starts - Some(BREAK_LEN) => { - self.buffer_consume(BREAK_LEN); - let is_chunked = self.is_chunked(); - self.set_state(match is_chunked { - true => State::WaitingForChunk, - false => State::WritingBody, - }); - }, - Some(break_index) => { - let header = self.buffer_to_string(break_index); - debug!("Found header: {:?}", header); - self.headers.push(header); - }, - None => return Ok(()), - } - }, - State::WritingBody => { - let len = self.buffer.get_ref().len(); - match self.size_limit { - None => {}, - Some(limit) if limit > len => {}, - _ => { - warn!("Finishing file fetching because limit was reached."); - self.set_state(State::Finished); - continue; - } - } - try!(self.body_writer.write_all(self.buffer.get_ref())); - self.buffer_consume(len); - return self.body_writer.flush(); - }, - State::WaitingForChunk => { - match self.find_break_index() { - None => return Ok(()), - // last chunk - size 0 - Some(BREAK_LEN) => { - self.state = State::Finished; - }, - Some(break_index) => { - let chunk_size = self.buffer_to_string(break_index); - self.set_state(if let Ok(size) = usize::from_str_radix(&chunk_size, 16) { - State::WritingChunk(size) - } else { - warn!("Error parsing server chunked response. Invalid chunk size."); - State::Finished - }); - } - } - }, - State::WritingChunk(0) => { - self.set_state(State::Finished); - }, - // Buffers the data until we have a full chunk - State::WritingChunk(left) if self.buffer.get_ref().len() >= left => { - match self.size_limit { - None => {}, - Some(limit) if limit > left => { - self.size_limit = Some(limit - left); - }, - _ => { - warn!("Finishing file fetching because limit was reached."); - self.set_state(State::Finished); - continue; - } - } - { - let chunk = &self.buffer.get_ref()[0..left]; - trace!("Writing chunk: {:?}", String::from_utf8_lossy(chunk)); - try!(self.body_writer.write_all(chunk)); - } - self.buffer_consume(left + BREAK_LEN); - - self.set_state(State::WaitingForChunk); - }, - // Wait for more data - State::WritingChunk(_) => return Ok(()), - // Just consume buffer - State::Finished => { - let len = self.buffer.get_ref().len(); - self.buffer_consume(len); - return self.body_writer.flush(); - }, - } - } - } - - #[cfg(test)] - pub fn state(&self) -> State { - self.state - } -} - -impl io::Write for HttpProcessor { - fn write(&mut self, bytes: &[u8]) -> io::Result { - let result = self.buffer.write(bytes); - try!(self.process_buffer()); - result - } - - fn flush(&mut self) -> io::Result<()> { - self.buffer.flush().and_then(|_| { - self.body_writer.flush() - }) - } -} - -#[cfg(test)] -mod tests { - use std::rc::Rc; - use std::cell::RefCell; - use std::io::{self, Write, Cursor}; - use super::*; - - struct Writer { - data: Rc>>>, - } - - impl Writer { - fn new() -> (Self, Rc>>>) { - let data = Rc::new(RefCell::new(Cursor::new(Vec::new()))); - (Writer { data: data.clone() }, data) - } - } - - impl Write for Writer { - fn write(&mut self, buf: &[u8]) -> io::Result { self.data.borrow_mut().write(buf) } - fn flush(&mut self) -> io::Result<()> { self.data.borrow_mut().flush() } - } - - #[test] - fn should_be_able_to_process_status_line() { - // given - let mut http = HttpProcessor::new(Box::new(Cursor::new(Vec::new())), None); - - // when - let out = - "\ - HTTP/1.1 200 OK\r\n\ - Server: Pari - "; - http.write_all(out.as_bytes()).unwrap(); - http.flush().unwrap(); - - // then - assert_eq!(http.status().unwrap(), "HTTP/1.1 200 OK"); - assert_eq!(http.state(), State::WaitingForHeaders); - } - - #[test] - fn should_be_able_to_process_headers() { - // given - let mut http = HttpProcessor::new(Box::new(Cursor::new(Vec::new())), None); - - // when - let out = - "\ - HTTP/1.1 200 OK\r\n\ - Server: Parity/1.1.1\r\n\ - Connection: close\r\n\ - Content-Length: 2\r\n\ - Content-Type: application/json\r\n\ - \r\n\ - "; - http.write_all(out.as_bytes()).unwrap(); - http.flush().unwrap(); - - // then - assert_eq!(http.status().unwrap(), "HTTP/1.1 200 OK"); - assert_eq!(http.headers().len(), 4); - assert_eq!(http.state(), State::WritingBody); - } - - #[test] - fn should_be_able_to_consume_body() { - // given - let (writer, data) = Writer::new(); - let mut http = HttpProcessor::new(Box::new(writer), None); - - // when - let out = - "\ - HTTP/1.1 200 OK\r\n\ - Server: Parity/1.1.1\r\n\ - Connection: close\r\n\ - Content-Length: 2\r\n\ - Content-Type: application/json\r\n\ - \r\n\ - Some data\ - "; - http.write_all(out.as_bytes()).unwrap(); - http.flush().unwrap(); - - // then - assert_eq!(http.status().unwrap(), "HTTP/1.1 200 OK"); - assert_eq!(http.headers().len(), 4); - assert_eq!(http.state(), State::WritingBody); - assert_eq!(data.borrow().get_ref()[..], b"Some data"[..]); - } - - #[test] - fn should_correctly_handle_chunked_content() { - // given - let (writer, data) = Writer::new(); - let mut http = HttpProcessor::new(Box::new(writer), None); - - // when - let out = - "\ - HTTP/1.1 200 OK\r\n\ - Host: 127.0.0.1:8080\r\n\ - Transfer-Encoding: chunked\r\n\ - Connection: close\r\n\ - \r\n\ - 4\r\n\ - Pari\r\n\ - 3\r\n\ - ty \r\n\ - D\r\n\ - in\r\n\ - \r\n\ - chunks.\r\n\ - 0\r\n\ - \r\n\ - "; - http.write_all(out.as_bytes()).unwrap(); - http.flush().unwrap(); - - // then - assert_eq!(http.status().unwrap(), "HTTP/1.1 200 OK"); - assert_eq!(http.headers().len(), 3); - assert_eq!(data.borrow().get_ref()[..], b"Parity in\r\n\r\nchunks."[..]); - assert_eq!(http.state(), State::Finished); - } - - #[test] - fn should_stop_fetching_when_limit_is_reached() { - // given - let (writer, data) = Writer::new(); - let mut http = HttpProcessor::new(Box::new(writer), Some(5)); - - // when - let out = - "\ - HTTP/1.1 200 OK\r\n\ - Host: 127.0.0.1:8080\r\n\ - Transfer-Encoding: chunked\r\n\ - Connection: close\r\n\ - \r\n\ - 4\r\n\ - Pari\r\n\ - 3\r\n\ - ty \r\n\ - D\r\n\ - in\r\n\ - \r\n\ - chunks.\r\n\ - 0\r\n\ - \r\n\ - "; - http.write_all(out.as_bytes()).unwrap(); - http.flush().unwrap(); - - // then - assert_eq!(http.status().unwrap(), "HTTP/1.1 200 OK"); - assert_eq!(http.headers().len(), 3); - assert_eq!(data.borrow().get_ref()[..], b"Pari"[..]); - assert_eq!(http.state(), State::Finished); - } - -} diff --git a/util/https-fetch/src/lib.rs b/util/https-fetch/src/lib.rs deleted file mode 100644 index d941129a8..000000000 --- a/util/https-fetch/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -extern crate rustls; -extern crate mio; -#[macro_use] extern crate log; - -mod tlsclient; -mod client; -mod url; -mod http; - -pub use self::client::{Client, FetchError, FetchResult}; -pub use self::url::{Url, UrlError}; - diff --git a/util/https-fetch/src/tlsclient.rs b/util/https-fetch/src/tlsclient.rs deleted file mode 100644 index 5ac19ad15..000000000 --- a/util/https-fetch/src/tlsclient.rs +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -use std::str; -use std::sync::Arc; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::io::{self, Write, Read, Cursor, BufReader}; - -use mio; -use mio::tcp::TcpStream; -use rustls::{self, Session}; - -use url::Url; -use http::HttpProcessor; -use client::{FetchError, ClientLoop, FetchResult}; - -#[derive(Debug)] -pub enum TlsClientError { - Aborted, - Initialization, - UnexpectedEof, - Connection(io::Error), - Writer(io::Error), - Tls(rustls::TLSError), -} - -/// This encapsulates the TCP-level connection, some connection -/// state, and the underlying TLS-level session. -pub struct TlsClient { - abort: Arc, - token: mio::Token, - socket: TcpStream, - tls_session: rustls::ClientSession, - writer: HttpProcessor, - error: Option, - closing: bool, - callback: Box, -} - -impl io::Write for TlsClient { - fn write(&mut self, bytes: &[u8]) -> io::Result { - self.tls_session.write(bytes) - } - - fn flush(&mut self) -> io::Result<()> { - self.tls_session.flush() - } -} - -impl io::Read for TlsClient { - fn read(&mut self, bytes: &mut [u8]) -> io::Result { - self.tls_session.read(bytes) - } -} - -#[cfg(feature = "ca-github-only")] -static CA_CERTS: &'static [u8] = include_bytes!("./ca-github.crt"); -#[cfg(not(feature = "ca-github-only"))] -static CA_CERTS: &'static [u8] = include_bytes!("./ca-certificates.crt"); - -impl TlsClient { - pub fn make_config() -> Result, FetchError> { - let mut config = rustls::ClientConfig::new(); - let mut cursor = Cursor::new(CA_CERTS.to_vec()); - let mut reader = BufReader::new(&mut cursor); - try!(config.root_store.add_pem_file(&mut reader).map_err(|_| FetchError::ReadingCaCertificates)); - // TODO [ToDr] client certificate? - Ok(Arc::new(config)) - } - - pub fn new( - token: mio::Token, - url: &Url, - writer: Box, - abort: Arc, - mut callback: Box, - size_limit: Option, - ) -> Result { - let res = TlsClient::make_config().and_then(|cfg| { - TcpStream::connect(url.address()).map(|sock| { - (cfg, sock) - }).map_err(Into::into) - }); - - match res { - Ok((cfg, sock)) => Ok(TlsClient { - abort: abort, - token: token, - writer: HttpProcessor::new(writer, size_limit), - socket: sock, - closing: false, - error: None, - tls_session: rustls::ClientSession::new(&cfg, url.hostname()), - callback: callback, - }), - Err(e) => { - callback(Err(e)); - Err(FetchError::Client(TlsClientError::Initialization)) - } - } - } - - /// Called by mio each time events we register() for happen. - /// Return false if reregistering again. - pub fn ready(&mut self, event_loop: &mut mio::EventLoop, token: mio::Token, events: mio::EventSet) -> bool { - assert_eq!(token, self.token); - - let aborted = self.is_aborted(); - if aborted { - // do_write needs to be invoked after that - self.tls_session.send_close_notify(); - self.error = Some(TlsClientError::Aborted); - } - - if events.is_readable() { - self.do_read(); - } - - if events.is_writable() { - self.do_write(); - } - - if self.is_closed() || aborted { - trace!("Connection closed"); - let callback = &mut self.callback; - callback(match self.error.take() { - None if self.writer.status_is_ok() => Ok(()), - Some(err) => Err(err.into()), - None => { - Err(FetchError::UnexpectedStatus(format!("{:?}", self.writer.status()))) - }, - }); - - return true; - } - - self.reregister(event_loop); - false - } - - pub fn register(&mut self, event_loop: &mut mio::EventLoop) { - event_loop.register( - &self.socket, - self.token, - self.event_set(), - mio::PollOpt::level() | mio::PollOpt::oneshot() - ).unwrap_or_else(|e| self.error = Some(TlsClientError::Connection(e))); - } - - fn reregister(&mut self, event_loop: &mut mio::EventLoop) { - event_loop.reregister( - &self.socket, - self.token, - self.event_set(), - mio::PollOpt::level() | mio::PollOpt::oneshot() - ).unwrap_or_else(|e| self.error = Some(TlsClientError::Connection(e))); - } - - /// We're ready to do a read. - fn do_read(&mut self) { - // Read TLS data. This fails if the underlying TCP connection is broken. - let rc = self.tls_session.read_tls(&mut self.socket); - if let Err(e) = rc { - trace!("TLS read error: {:?}", e); - self.closing = true; - self.error = Some(TlsClientError::Connection(e)); - return; - } - - // If we're ready but there's no data: EOF. - if rc.unwrap() == 0 { - trace!("Unexpected EOF"); - self.error = Some(TlsClientError::UnexpectedEof); - self.closing = true; - return; - } - - // Reading some TLS data might have yielded new TLS messages to process. - // Errors from this indicate TLS protocol problems and are fatal. - let processed = self.tls_session.process_new_packets(); - if let Err(e) = processed { - trace!("TLS error: {:?}", e); - self.error = Some(TlsClientError::Tls(e)); - self.closing = true; - return; - } - - // Having read some TLS data, and processed any new messages, we might have new plaintext as a result. - // Read it and then write it to stdout. - let mut plaintext = Vec::new(); - let rc = self.tls_session.read_to_end(&mut plaintext); - if !plaintext.is_empty() { - self.writer.write(&plaintext).unwrap_or_else(|e| { - trace!("Write error: {:?}", e); - self.error = Some(TlsClientError::Writer(e)); - 0 - }); - } - - // If that fails, the peer might have started a clean TLS-level session closure. - if let Err(err) = rc { - if err.kind() != io::ErrorKind::ConnectionAborted { - self.error = Some(TlsClientError::Connection(err)); - } - self.closing = true; - } - } - - fn do_write(&mut self) { - self.tls_session.write_tls(&mut self.socket).unwrap_or_else(|e| { - warn!("TLS write error: {:?}", e); - 0 - }); - } - - // Use wants_read/wants_write to register for different mio-level IO readiness events. - fn event_set(&self) -> mio::EventSet { - let rd = self.tls_session.wants_read(); - let wr = self.tls_session.wants_write(); - - if rd && wr { - mio::EventSet::readable() | mio::EventSet::writable() - } else if wr { - mio::EventSet::writable() - } else { - mio::EventSet::readable() - } - } - - fn is_closed(&self) -> bool { - self.closing - } - - fn is_aborted(&self) -> bool { - self.abort.load(Ordering::Relaxed) - } -} - diff --git a/util/https-fetch/src/url.rs b/util/https-fetch/src/url.rs deleted file mode 100644 index d5df0788f..000000000 --- a/util/https-fetch/src/url.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity 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. - -// Parity 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 Parity. If not, see . - -use std::net::SocketAddr; - -#[derive(Debug)] -pub enum UrlError { - InvalidAddress -} - -/// Build a ClientConfig from our arguments -pub struct Url { - address: SocketAddr, - hostname: String, - port: u16, - path: String, -} - -impl Url { - pub fn new(hostname: &str, port: u16, path: &str) -> Result { - let addr = try!(Self::lookup_ipv4(hostname, port)); - Ok(Url { - address: addr, - hostname: hostname.into(), - port: port, - path: path.into(), - }) - } - - fn lookup_ipv4(host: &str, port: u16) -> Result { - use std::net::ToSocketAddrs; - - let addrs = try!((host, port).to_socket_addrs().map_err(|_| UrlError::InvalidAddress)); - for addr in addrs { - if let SocketAddr::V4(_) = addr { - return Ok(addr.clone()); - } - } - Err(UrlError::InvalidAddress) - } - - pub fn address(&self) -> &SocketAddr { - &self.address - } - - pub fn hostname(&self) -> &str { - &self.hostname - } - - pub fn port(&self) -> u16 { - self.port - } - - pub fn path(&self) -> &str { - &self.path - } -} - -#[cfg(test)] -#[test] -fn should_parse_url() { - // given - let url = Url::new("github.com", 443, "/").unwrap(); - - assert_eq!(url.hostname(), "github.com"); - assert_eq!(url.port(), 443); - assert_eq!(url.path(), "/"); -} diff --git a/util/reactor/Cargo.toml b/util/reactor/Cargo.toml new file mode 100644 index 000000000..820b188a0 --- /dev/null +++ b/util/reactor/Cargo.toml @@ -0,0 +1,11 @@ +[package] +description = "Parity Reactor" +homepage = "http://parity.io" +license = "GPL-3.0" +name = "parity-reactor" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +futures = "0.1" +tokio-core = "0.1" diff --git a/util/reactor/src/lib.rs b/util/reactor/src/lib.rs new file mode 100644 index 000000000..5a2c40794 --- /dev/null +++ b/util/reactor/src/lib.rs @@ -0,0 +1,142 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + + +//! Tokio Core Reactor wrapper. + +extern crate futures; +extern crate tokio_core; + +use std::thread; +use std::sync::mpsc; +use futures::{Future, IntoFuture}; +use self::tokio_core::reactor::Remote as TokioRemote; + +/// Event Loop for futures. +/// Wrapper around `tokio::reactor::Core`. +/// Runs in a separate thread. +pub struct EventLoop { + remote: Remote, + handle: EventLoopHandle, +} + +impl EventLoop { + /// Spawns a new thread with `EventLoop` with given handler. + pub fn spawn() -> Self { + let (stop, stopped) = futures::oneshot(); + let (tx, rx) = mpsc::channel(); + let handle = thread::spawn(move || { + let mut el = tokio_core::reactor::Core::new().expect("Creating an event loop should not fail."); + tx.send(el.remote()).expect("Rx is blocking upper thread."); + let _ = el.run(futures::empty().select(stopped)); + }); + let remote = rx.recv().expect("tx is transfered to a newly spawned thread."); + + EventLoop { + remote: Remote{ + inner: Mode::Tokio(remote), + }, + handle: EventLoopHandle { + close: Some(stop), + handle: Some(handle), + }, + } + } + + /// Returns event loop remote. + pub fn remote(&self) -> Remote { + self.remote.clone() + } +} + +#[derive(Clone)] +enum Mode { + Tokio(TokioRemote), + Sync, +} + +#[derive(Clone)] +pub struct Remote { + inner: Mode, +} + +impl Remote { + /// Synchronous remote, used mostly for tests. + pub fn new_sync() -> Self { + Remote { + inner: Mode::Sync, + } + } + + /// Spawn a future to this event loop + pub fn spawn(&self, r: R) where + R: IntoFuture + Send + 'static, + R::Future: 'static, + { + match self.inner { + Mode::Tokio(ref remote) => remote.spawn(move |_| r), + Mode::Sync => { + let _= r.into_future().wait(); + }, + } + } + + /// Spawn a new future returned by given closure. + pub fn spawn_fn(&self, f: F) where + F: FnOnce() -> R + Send + 'static, + R: IntoFuture, + R::Future: 'static, + { + match self.inner { + Mode::Tokio(ref remote) => remote.spawn(move |_| f()), + Mode::Sync => { + let _ = f().into_future().wait(); + }, + } + } +} + +/// A handle to running event loop. Dropping the handle will cause event loop to finish. +pub struct EventLoopHandle { + close: Option>, + handle: Option> +} + +impl From for EventLoopHandle { + fn from(el: EventLoop) -> Self { + el.handle + } +} + +impl Drop for EventLoopHandle { + fn drop(&mut self) { + self.close.take().map(|v| v.complete(())); + } +} + +impl EventLoopHandle { + /// Blocks current thread and waits until the event loop is finished. + pub fn wait(mut self) -> thread::Result<()> { + self.handle.take() + .expect("Handle is taken only in `wait`, `wait` is consuming; qed").join() + } + + /// Finishes this event loop. + pub fn close(mut self) { + self.close.take() + .expect("Close is taken only in `close` and `drop`. `close` is consuming; qed").complete(()) + } +} From 077069c4520b16689db7f2715cc70d6522964f0f Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 22 Dec 2016 18:30:59 +0100 Subject: [PATCH 27/29] Display 0x00..00 as null (#3950) * Display 0x00..00 as null (custom black icon) * rendering test for null --- js/src/ui/Form/InputAddress/inputAddress.js | 4 ++- js/src/ui/Icons/index.js | 2 ++ js/src/ui/IdentityIcon/identityIcon.js | 18 +++++++++++--- js/src/ui/IdentityName/identityName.js | 27 +++++++++++++-------- js/src/ui/IdentityName/identityName.spec.js | 7 +++++- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/js/src/ui/Form/InputAddress/inputAddress.js b/js/src/ui/Form/InputAddress/inputAddress.js index e2a0707d5..917a273d4 100644 --- a/js/src/ui/Form/InputAddress/inputAddress.js +++ b/js/src/ui/Form/InputAddress/inputAddress.js @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import BigNumber from 'bignumber.js'; import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; @@ -62,6 +63,7 @@ class InputAddress extends Component { classes.push(!icon ? styles.inputEmpty : styles.input); const containerClasses = [ styles.container ]; + const nullName = new BigNumber(value).eq(0) ? 'null' : null; if (small) { containerClasses.push(styles.small); @@ -82,7 +84,7 @@ class InputAddress extends Component { value={ text && account ? account.name - : value + : (nullName || value) } /> { icon }
diff --git a/js/src/ui/Icons/index.js b/js/src/ui/Icons/index.js index b9cf70ba0..d27af1554 100644 --- a/js/src/ui/Icons/index.js +++ b/js/src/ui/Icons/index.js @@ -16,6 +16,7 @@ import AddIcon from 'material-ui/svg-icons/content/add'; import CancelIcon from 'material-ui/svg-icons/content/clear'; +import ContractIcon from 'material-ui/svg-icons/action/code'; import DoneIcon from 'material-ui/svg-icons/action/done-all'; import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back'; import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward'; @@ -24,6 +25,7 @@ import SnoozeIcon from 'material-ui/svg-icons/av/snooze'; export { AddIcon, CancelIcon, + ContractIcon, DoneIcon, PrevIcon, NextIcon, diff --git a/js/src/ui/IdentityIcon/identityIcon.js b/js/src/ui/IdentityIcon/identityIcon.js index 55fc34afa..565c47a84 100644 --- a/js/src/ui/IdentityIcon/identityIcon.js +++ b/js/src/ui/IdentityIcon/identityIcon.js @@ -14,12 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import BigNumber from 'bignumber.js'; import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; -import ContractIcon from 'material-ui/svg-icons/action/code'; import { createIdentityImg } from '~/api/util/identity'; +import ContractIcon from '../Icons'; import styles from './identityIcon.css'; @@ -108,9 +109,20 @@ class IdentityIcon extends Component { + ); + } else if (new BigNumber(address).eq(0)) { + return ( +
); } diff --git a/js/src/ui/IdentityName/identityName.js b/js/src/ui/IdentityName/identityName.js index 0ad9075d6..85116425e 100644 --- a/js/src/ui/IdentityName/identityName.js +++ b/js/src/ui/IdentityName/identityName.js @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import BigNumber from 'bignumber.js'; import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; @@ -24,35 +25,41 @@ const defaultName = 'UNNAMED'; class IdentityName extends Component { static propTypes = { - className: PropTypes.string, - address: PropTypes.string, accountsInfo: PropTypes.object, - tokens: PropTypes.object, + address: PropTypes.string, + className: PropTypes.string, empty: PropTypes.bool, + name: PropTypes.string, shorten: PropTypes.bool, - unknown: PropTypes.bool, - name: PropTypes.string + tokens: PropTypes.object, + unknown: PropTypes.bool } render () { - const { address, accountsInfo, tokens, empty, name, shorten, unknown, className } = this.props; + const { address, accountsInfo, className, empty, name, shorten, tokens, unknown } = this.props; const account = accountsInfo[address] || tokens[address]; if (!account && empty) { return null; } - const addressFallback = shorten ? () : address; + const nullName = new BigNumber(address).eq(0) ? 'null' : null; + const addressFallback = nullName || (shorten ? () : address); const fallback = unknown ? defaultName : addressFallback; const isUuid = account && account.name === account.uuid; const displayName = (name && name.toUpperCase().trim()) || (account && !isUuid - ? account.name.toUpperCase().trim() - : fallback); + ? account.name.toUpperCase().trim() + : fallback + ); return ( - { displayName && displayName.length ? displayName : fallback } + { + displayName && displayName.length + ? displayName + : fallback + } ); } diff --git a/js/src/ui/IdentityName/identityName.spec.js b/js/src/ui/IdentityName/identityName.spec.js index 31bf3ee5f..bb0b55e46 100644 --- a/js/src/ui/IdentityName/identityName.spec.js +++ b/js/src/ui/IdentityName/identityName.spec.js @@ -23,6 +23,7 @@ import IdentityName from './identityName'; const ADDR_A = '0x123456789abcdef0123456789A'; const ADDR_B = '0x123456789abcdef0123456789B'; const ADDR_C = '0x123456789abcdef0123456789C'; +const ADDR_NULL = '0x0000000000000000000000000000000000000000'; const STORE = { dispatch: sinon.stub(), subscribe: sinon.stub(), @@ -52,7 +53,7 @@ function render (props) { describe('ui/IdentityName', () => { describe('rendering', () => { it('renders defaults', () => { - expect(render()).to.be.ok; + expect(render({ address: ADDR_A })).to.be.ok; }); describe('account not found', () => { @@ -71,6 +72,10 @@ describe('ui/IdentityName', () => { it('renders unknown with flag', () => { expect(render({ address: ADDR_C, unknown: true }).text()).to.equal('UNNAMED'); }); + + it('renders 0x000...000 as null', () => { + expect(render({ address: ADDR_NULL }).text()).to.equal('null'); + }); }); }); }); From 9a013c4f47514fe752ca79bbc7ad966ff4396c11 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 22 Dec 2016 17:40:57 +0000 Subject: [PATCH 28/29] [ci skip] js-precompiled 20161222-173736 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 864b146b6..f070fdfc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1489,7 +1489,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#be31a3bd84c692445148dc18d4ee292fd024a28b" +source = "git+https://github.com/ethcore/js-precompiled.git#49851558a42410d67583d067de1df5c217c82b4c" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index dbd08f6a1..0e0393f77 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.139", + "version": "0.2.140", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 4623f45686ed4d573b848be6d8196925ad03c9f7 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Fri, 23 Dec 2016 04:17:11 +0000 Subject: [PATCH 29/29] [ci skip] js-precompiled 20161223-041415 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f070fdfc2..22ea03889 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1489,7 +1489,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#49851558a42410d67583d067de1df5c217c82b4c" +source = "git+https://github.com/ethcore/js-precompiled.git#8d16476c138e94a643ad4624df9825f34b57e1b0" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 0e0393f77..29a4436a2 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.140", + "version": "0.2.141", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ",