From c8607afcc67bcc4afedbf0c2a9ff88e0fd50af3b Mon Sep 17 00:00:00 2001 From: Chen Kai <281165273grape@gmail.com> Date: Wed, 3 Jan 2024 20:08:31 +0800 Subject: [PATCH] feat:span batch txs/tx Signed-off-by: Chen Kai <281165273grape@gmail.com> --- hildr-node/build.gradle | 4 +- hildr-utilities/build.gradle | 13 +- .../utilities/derive/stages/RawSpanBatch.java | 6 +- .../utilities/derive/stages/SpanBatch.java | 2 +- .../stages/SpanBatchAccessListTxData.java | 89 +-- .../stages/SpanBatchDynamicFeeTxData.java | 95 ++-- .../derive/stages/SpanBatchLegacyTxData.java | 67 ++- .../derive/stages/SpanBatchPayload.java | 14 +- .../utilities/derive/stages/SpanBatchTx.java | 131 +++-- .../derive/stages/SpanBatchTxData.java | 4 +- .../utilities/derive/stages/SpanBatchTxs.java | 538 +++++++++++------- .../utilities/derive/stages/BatchTest.java | 312 +++++----- .../derive/stages/SingularBatchTest.java | 52 +- .../derive/stages/SpanBatchTxTest.java | 129 +++++ .../derive/stages/SpanBatchTxsTest.java | 376 +++++++----- .../src/test/resources/txgases.txt | 1 + .../src/test/resources/txnonces.txt | 1 + hildr-utilities/src/test/resources/txsigs.txt | 1 + hildr-utilities/src/test/resources/txtos.txt | 1 + 19 files changed, 1123 insertions(+), 713 deletions(-) create mode 100644 hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxTest.java create mode 100644 hildr-utilities/src/test/resources/txgases.txt create mode 100644 hildr-utilities/src/test/resources/txnonces.txt create mode 100644 hildr-utilities/src/test/resources/txsigs.txt create mode 100644 hildr-utilities/src/test/resources/txtos.txt diff --git a/hildr-node/build.gradle b/hildr-node/build.gradle index 4f8fe38d..2d303097 100644 --- a/hildr-node/build.gradle +++ b/hildr-node/build.gradle @@ -136,8 +136,8 @@ dependencies { implementation('tech.pegasys.teku.internal:serviceutils:23.10.0') implementation('tech.pegasys.teku.internal:unsigned:23.10.0') implementation('tech.pegasys.teku.internal:statetransition:23.10.0') - implementation('org.hyperledger.besu.internal:metrics-core:22.10.4') - implementation('org.hyperledger.besu:plugin-api:22.10.4') + implementation('org.hyperledger.besu.internal:metrics-core:23.10.2') + implementation('org.hyperledger.besu:plugin-api:23.10.2') implementation('io.libp2p:jvm-libp2p:1.0.1-RELEASE') implementation 'io.tmio:tuweni-units:2.4.2' implementation('io.tmio:tuweni-crypto:2.4.2'){ diff --git a/hildr-utilities/build.gradle b/hildr-utilities/build.gradle index c329a53c..78fceafa 100644 --- a/hildr-utilities/build.gradle +++ b/hildr-utilities/build.gradle @@ -59,7 +59,7 @@ dependencies { api("com.squareup.okhttp3:okhttp:5.0.0-alpha.2") api("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2") - api('org.web3j:core:4.9.8') { + api('org.web3j:core:4.10.3') { exclude group: 'org.bouncycastle', module: 'bcprov-jdk15on' exclude group: 'com.squareup.okhttp3', module: 'okhttp' exclude group: 'com.squareup.okhttp3', module: 'logging-interceptor' @@ -79,16 +79,21 @@ dependencies { implementation 'ch.qos.logback:logback-core:1.4.7' implementation 'ch.qos.logback:logback-classic:1.4.7' + + implementation 'com.google.protobuf:protobuf-java:3.25.1' + implementation 'io.tmio:tuweni-units:2.4.2' implementation 'io.tmio:tuweni-rlp:2.4.2' implementation 'org.bouncycastle:bcprov-jdk18on:1.76' implementation 'org.slf4j:slf4j-api:2.0.7' implementation 'io.libp2p:jvm-libp2p:1.0.1-RELEASE' + implementation('org.hyperledger.besu.internal:core:23.10.2') + implementation('org.hyperledger.besu.internal:algorithms:23.10.2') + implementation('org.hyperledger.besu.internal:rlp:23.10.2') + implementation('org.hyperledger.besu:besu-datatypes:23.10.2') + implementation('org.hyperledger.besu:plugin-api:23.10.2') testImplementation platform('org.junit:junit-bom:5.9.1') testImplementation 'org.junit.jupiter:junit-jupiter' - - testImplementation 'io.tmio:tuweni-ssz:2.4.2' - testImplementation 'io.tmio:tuweni-units:2.4.2' testImplementation('io.tmio:tuweni-crypto:2.4.2'){ exclude group: 'org.bouncycastle', module: 'bcprov-jdk15on' } diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/RawSpanBatch.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/RawSpanBatch.java index a8055c20..51eabae9 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/RawSpanBatch.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/RawSpanBatch.java @@ -1,3 +1,3 @@ -package io.optimism.utilities.derive.stages; - -public record RawSpanBatch(SpanBatchPrefix spanbatchPrefix, SpanBatchPayload spanbatchPayload) {} +// package io.optimism.utilities.derive.stages; +// +// public record RawSpanBatch(SpanBatchPrefix spanbatchPrefix, SpanBatchPayload spanbatchPayload) {} diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatch.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatch.java index 34a040bb..803e9560 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatch.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatch.java @@ -99,7 +99,7 @@ public int getBlockCount() { * @param singularBatch SingularBatch */ public void AppendSingularBatch(SingularBatch singularBatch) { - if (batches.size() == 0) { + if (batches.isEmpty()) { this.parentCheck = singularBatch.parentHash().substring(0, 20); } this.batches.add(SpanBatchElement.singularBatchToElement(singularBatch)); // add the batch to the list diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchAccessListTxData.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchAccessListTxData.java index 6a15f36a..4115ef49 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchAccessListTxData.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchAccessListTxData.java @@ -1,57 +1,68 @@ package io.optimism.utilities.derive.stages; -import java.math.BigInteger; -import java.util.ArrayList; +import static org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder.writeAccessList; + import java.util.List; -import java.util.stream.Collectors; -import org.web3j.crypto.AccessListObject; -import org.web3j.crypto.transaction.type.TransactionType; -import org.web3j.rlp.RlpEncoder; -import org.web3j.rlp.RlpList; -import org.web3j.rlp.RlpString; -import org.web3j.rlp.RlpType; +import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.AccessListEntry; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.rlp.RLPInput; /** - * EIP-2930. + * The type SpanBatchAccessListTxData. * + * @author grapebaba + * @since 0.2.4 */ -public record SpanBatchAccessListTxData( - BigInteger value, BigInteger gasPrice, String data, List accessList) +public record SpanBatchAccessListTxData(Wei value, Wei gasPrice, Bytes data, List accessList) implements SpanBatchTxData { @Override - public byte txType() { - return TransactionType.EIP2930.getRlpType(); + public TransactionType txType() { + return TransactionType.ACCESS_LIST; } + /** + * Encode byte [ ]. + * + * @return the byte [ ] + */ public byte[] encode() { - List rlpList = new ArrayList<>(); - for (AccessListObject access : accessList) { - rlpList.add(RlpString.create(access.getAddress())); - rlpList.add(new RlpList( - access.getStorageKeys().stream().map(RlpString::create).collect(Collectors.toList()))); - } - return RlpEncoder.encode(new RlpList( - RlpString.create(value()), - RlpString.create(gasPrice()), - RlpString.create(data()), - new RlpList(rlpList))); + BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.writeByte(txType().getEthSerializedType()); + out.startList(); + out.writeUInt256Scalar(value()); + out.writeUInt256Scalar(gasPrice()); + out.writeBytes(data()); + writeAccessList(out, Optional.ofNullable(accessList())); + out.endList(); + return out.encoded().toArrayUnsafe(); } - public static SpanBatchAccessListTxData decode(RlpList rlp) { - BigInteger value = ((RlpString) rlp.getValues().get(0)).asPositiveBigInteger(); - BigInteger gasPrice = ((RlpString) rlp.getValues().get(1)).asPositiveBigInteger(); - String data = ((RlpString) rlp.getValues().get(2)).asString(); - List accessObjList = new ArrayList<>(); - ((RlpList) rlp.getValues().get(3)).getValues().forEach(rlpType -> { - RlpList rlpList = (RlpList) rlpType; - String address = ((RlpString) rlpList.getValues().get(0)).asString(); - List storageKeys = ((RlpList) rlpList.getValues().get(1)) - .getValues().stream() - .map(stKey -> ((RlpString) stKey).asString()) - .collect(Collectors.toList()); - accessObjList.add(new AccessListObject(address, storageKeys)); + /** + * Decode span batch access list tx data. + * + * @param input the input + * @return the span batch access list tx data + */ + public static SpanBatchAccessListTxData decode(RLPInput input) { + input.enterList(); + Wei value = Wei.of(input.readUInt256Scalar()); + Wei gasPrice = Wei.of(input.readUInt256Scalar()); + Bytes data = input.readBytes(); + List accessList = input.readList(accessListEntryRLPInput -> { + accessListEntryRLPInput.enterList(); + final AccessListEntry accessListEntry = new AccessListEntry( + Address.wrap(accessListEntryRLPInput.readBytes()), + accessListEntryRLPInput.readList(RLPInput::readBytes32)); + accessListEntryRLPInput.leaveList(); + return accessListEntry; }); - return new SpanBatchAccessListTxData(value, gasPrice, data, accessObjList); + input.leaveList(); + return new SpanBatchAccessListTxData(value, gasPrice, data, accessList); } } diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchDynamicFeeTxData.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchDynamicFeeTxData.java index d5cc4b97..ee3b63a6 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchDynamicFeeTxData.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchDynamicFeeTxData.java @@ -1,54 +1,71 @@ package io.optimism.utilities.derive.stages; -import java.math.BigInteger; -import java.util.ArrayList; +import static org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder.writeAccessList; + import java.util.List; -import java.util.stream.Collectors; -import org.web3j.crypto.AccessListObject; -import org.web3j.crypto.transaction.type.TransactionType; -import org.web3j.rlp.RlpEncoder; -import org.web3j.rlp.RlpList; -import org.web3j.rlp.RlpString; -import org.web3j.rlp.RlpType; +import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.AccessListEntry; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.rlp.RLPInput; +/** + * The type SpanBatchDynamicFeeTxData. + * + * @author grapebaba + * @since 0.2.4 + */ public record SpanBatchDynamicFeeTxData( - BigInteger value, BigInteger gasTipCap, BigInteger gasFeeCap, String data, List accessList) + Wei value, Wei gasTipCap, Wei gasFeeCap, Bytes data, List accessList) implements SpanBatchTxData { @Override - public byte txType() { - return TransactionType.EIP1559.getRlpType(); + public TransactionType txType() { + return TransactionType.EIP1559; } + /** + * Encode byte [ ]. + * + * @return the byte [ ] + */ public byte[] encode() { - List rlpList = new ArrayList<>(); - for (AccessListObject access : accessList) { - rlpList.add(RlpString.create(access.getAddress())); - rlpList.add(new RlpList( - access.getStorageKeys().stream().map(RlpString::create).collect(Collectors.toList()))); - } - return RlpEncoder.encode(new RlpList( - RlpString.create(value()), - RlpString.create(gasTipCap()), - RlpString.create(gasFeeCap()), - RlpString.create(data()), - new RlpList(rlpList))); + BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.writeByte(txType().getEthSerializedType()); + out.startList(); + out.writeUInt256Scalar(value()); + out.writeUInt256Scalar(gasTipCap()); + out.writeUInt256Scalar(gasFeeCap()); + out.writeBytes(data()); + writeAccessList(out, Optional.ofNullable(accessList())); + out.endList(); + return out.encoded().toArrayUnsafe(); } - public static SpanBatchDynamicFeeTxData decode(RlpList rlp) { - BigInteger value = ((RlpString) rlp.getValues().get(0)).asPositiveBigInteger(); - BigInteger gasTipCap = ((RlpString) rlp.getValues().get(1)).asPositiveBigInteger(); - BigInteger gasFeeCap = ((RlpString) rlp.getValues().get(2)).asPositiveBigInteger(); - String data = ((RlpString) rlp.getValues().get(2)).asString(); - List accessObjList = new ArrayList<>(); - ((RlpList) rlp.getValues().get(3)).getValues().forEach(rlpType -> { - RlpList rlpList = (RlpList) rlpType; - String address = ((RlpString) rlpList.getValues().get(0)).asString(); - List storageKeys = ((RlpList) rlpList.getValues().get(1)) - .getValues().stream() - .map(stKey -> ((RlpString) stKey).asString()) - .collect(Collectors.toList()); - accessObjList.add(new AccessListObject(address, storageKeys)); + /** + * Decode span batch dynamic fee tx data. + * + * @param input the input + * @return the span batch dynamic fee tx data + */ + public static SpanBatchDynamicFeeTxData decode(RLPInput input) { + input.enterList(); + Wei value = Wei.of(input.readUInt256Scalar()); + Wei gasTipCap = Wei.of(input.readUInt256Scalar()); + Wei gasFeeCap = Wei.of(input.readUInt256Scalar()); + Bytes data = input.readBytes(); + List accessList = input.readList(accessListEntryRLPInput -> { + accessListEntryRLPInput.enterList(); + final AccessListEntry accessListEntry = new AccessListEntry( + Address.wrap(accessListEntryRLPInput.readBytes()), + accessListEntryRLPInput.readList(RLPInput::readBytes32)); + accessListEntryRLPInput.leaveList(); + return accessListEntry; }); - return new SpanBatchDynamicFeeTxData(value, gasTipCap, gasFeeCap, data, accessObjList); + + input.leaveList(); + return new SpanBatchDynamicFeeTxData(value, gasTipCap, gasFeeCap, data, accessList); } } diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchLegacyTxData.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchLegacyTxData.java index e7aba6f4..9ecc5fd2 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchLegacyTxData.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchLegacyTxData.java @@ -1,26 +1,67 @@ +/* + * Copyright 2023 q315xia@163.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + package io.optimism.utilities.derive.stages; -import java.math.BigInteger; -import org.web3j.rlp.RlpEncoder; -import org.web3j.rlp.RlpList; -import org.web3j.rlp.RlpString; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.rlp.RLPInput; -public record SpanBatchLegacyTxData(BigInteger value, BigInteger gasPrice, String data) implements SpanBatchTxData { +/** + * The type SpanBatchLegacyTxData. + * + * @author zhouop0 + * @since 0.2.4 + */ +public record SpanBatchLegacyTxData(Wei value, Wei gasPrice, Bytes data) implements SpanBatchTxData { @Override - public byte txType() { - return 0x00; + public TransactionType txType() { + return TransactionType.FRONTIER; } + /** + * Encode span batch legacy tx data. + * + * @return the span batch legacy tx data + */ public byte[] encode() { - return RlpEncoder.encode( - new RlpList(RlpString.create(value()), RlpString.create(gasPrice()), RlpString.create(data()))); + BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.startList(); + out.writeUInt256Scalar(value()); + out.writeUInt256Scalar(gasPrice()); + out.writeBytes(data()); + out.endList(); + return out.encoded().toArrayUnsafe(); } - public static SpanBatchLegacyTxData decode(RlpList rlp) { - BigInteger value = ((RlpString) rlp.getValues().get(0)).asPositiveBigInteger(); - BigInteger gasPrice = ((RlpString) rlp.getValues().get(1)).asPositiveBigInteger(); - String data = ((RlpString) rlp.getValues().get(2)).asString(); + /** + * Decode span batch legacy tx data. + * + * @param input the rlp + * @return the span batch legacy tx data + */ + public static SpanBatchLegacyTxData decode(RLPInput input) { + input.enterList(); + Wei value = Wei.of(input.readUInt256Scalar()); + Wei gasPrice = Wei.of(input.readUInt256Scalar()); + Bytes data = input.readBytes(); + input.leaveList(); return new SpanBatchLegacyTxData(value, gasPrice, data); } } diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchPayload.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchPayload.java index 896bf73f..66521afb 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchPayload.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchPayload.java @@ -1,7 +1,7 @@ -package io.optimism.utilities.derive.stages; - -import java.math.BigInteger; -import java.util.List; - -public record SpanBatchPayload( - BigInteger blockCount, BigInteger originBits, List blockTxCounts, SpanBatchTxs txs) {} +// package io.optimism.utilities.derive.stages; +// +// import java.math.BigInteger; +// import java.util.List; +// +// public record SpanBatchPayload( +// BigInteger blockCount, BigInteger originBits, List blockTxCounts, SpanBatchTxs txs) {} diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTx.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTx.java index f51827a4..7be07b8d 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTx.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTx.java @@ -1,85 +1,126 @@ +/* + * Copyright 2023 q315xia@163.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + package io.optimism.utilities.derive.stages; import java.util.ArrayList; import org.apache.commons.lang3.ArrayUtils; -import org.web3j.crypto.transaction.type.ITransaction; -import org.web3j.crypto.transaction.type.Transaction1559; -import org.web3j.crypto.transaction.type.Transaction2930; -import org.web3j.crypto.transaction.type.TransactionType; -import org.web3j.rlp.RlpDecoder; -import org.web3j.rlp.RlpList; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; +import org.hyperledger.besu.ethereum.rlp.RLPInput; +/** + * The type SpanBatchTx. + * + * @author zhouop0 + * @since 0.2.4 + */ public class SpanBatchTx { private final SpanBatchTxData spanBatchTxData; + /** + * Instantiates a new Span batch tx. + * + * @param spanBatchTxData the span batch tx data + */ protected SpanBatchTx(SpanBatchTxData spanBatchTxData) { this.spanBatchTxData = spanBatchTxData; } - public byte txType() { + /** + * Tx type byte. + * + * @return the byte + */ + public TransactionType txType() { return this.spanBatchTxData.txType(); } - public static SpanBatchTx newSpanBatchTx(ITransaction tx) { - SpanBatchTxData spanBatchTxData; - switch (tx.getType()) { - case LEGACY: - spanBatchTxData = new SpanBatchLegacyTxData(tx.getValue(), tx.getGasPrice(), tx.getData()); - break; - case EIP1559: - Transaction1559 transaction1559 = (Transaction1559) tx; - spanBatchTxData = new SpanBatchDynamicFeeTxData( - transaction1559.getValue(), - transaction1559.getMaxPriorityFeePerGas(), - transaction1559.getMaxFeePerGas(), - transaction1559.getData(), - new ArrayList<>()); - break; - case EIP2930: - Transaction2930 transaction2930 = (Transaction2930) tx; - spanBatchTxData = new SpanBatchAccessListTxData( - transaction2930.getValue(), - transaction2930.getGasPrice(), - transaction2930.getData(), - transaction2930.getAccessList()); - break; - default: - throw new RuntimeException("invalid tx type:" + tx.getType()); - } + /** + * New span batch tx span batch tx. + * + * @param tx the tx + * @return the span batch tx + */ + public static SpanBatchTx newSpanBatchTx(Transaction tx) { + SpanBatchTxData spanBatchTxData = + switch (tx.getType()) { + case FRONTIER -> new SpanBatchLegacyTxData( + tx.getValue(), tx.getGasPrice().orElseThrow(), tx.getPayload()); + case EIP1559 -> new SpanBatchDynamicFeeTxData( + tx.getValue(), + tx.getMaxPriorityFeePerGas().orElseThrow(), + tx.getMaxFeePerGas().orElseThrow(), + tx.getPayload(), + tx.getAccessList().orElse(new ArrayList<>())); + case ACCESS_LIST -> new SpanBatchAccessListTxData( + tx.getValue(), + tx.getGasPrice().orElseThrow(), + tx.getPayload(), + tx.getAccessList().orElse(new ArrayList<>())); + case BLOB -> throw new RuntimeException("blob tx not supported"); + }; return new SpanBatchTx(spanBatchTxData); } + /** + * Marshal spanBatch tx. + * + * @return the span batch tx data + */ public byte[] marshalBinary() { - if (spanBatchTxData.txType() == 0) { + if (spanBatchTxData.txType() == TransactionType.FRONTIER) { SpanBatchLegacyTxData spanBatchLegacyTxData = (SpanBatchLegacyTxData) this.spanBatchTxData; return spanBatchLegacyTxData.encode(); } - if (TransactionType.EIP1559.getRlpType() == spanBatchTxData.txType()) { + if (TransactionType.EIP1559 == spanBatchTxData.txType()) { SpanBatchDynamicFeeTxData spanBatchDynamicFeeTxData = (SpanBatchDynamicFeeTxData) this.spanBatchTxData; return spanBatchDynamicFeeTxData.encode(); } - if (TransactionType.EIP2930.getRlpType() == spanBatchTxData.txType()) { + if (TransactionType.ACCESS_LIST == spanBatchTxData.txType()) { SpanBatchAccessListTxData spanBatchAccessListTxData = (SpanBatchAccessListTxData) this.spanBatchTxData; return spanBatchAccessListTxData.encode(); } return null; } - public SpanBatchTxData unMarshalBinary(byte[] b) { + /** + * Unmarshal binary span batch tx data. + * + * @param b the b + * @return the span batch tx data + */ + public static SpanBatchTxData unmarshalBinary(byte[] b) { if (b.length <= 1) { throw new RuntimeException("typed transaction too short"); } - byte[] spanBatchData = ArrayUtils.subarray(b, 1, b.length); - RlpList rlpBatchData = - (RlpList) RlpDecoder.decode(spanBatchData).getValues().get(0); if ((b[0] & 0xFF) > 0x7F) { - return SpanBatchLegacyTxData.decode(rlpBatchData); + RLPInput input = new BytesValueRLPInput(Bytes.wrap(b), false); + return SpanBatchLegacyTxData.decode(input); } - if (TransactionType.EIP2930.getRlpType() == b[0]) { - return SpanBatchAccessListTxData.decode(rlpBatchData); + + byte[] spanBatchData = ArrayUtils.subarray(b, 1, b.length); + RLPInput input = new BytesValueRLPInput(Bytes.wrap(spanBatchData), false); + if (TransactionType.ACCESS_LIST.getEthSerializedType() == b[0]) { + return SpanBatchAccessListTxData.decode(input); } - if (TransactionType.EIP1559.getRlpType() == b[0]) { - return SpanBatchDynamicFeeTxData.decode(rlpBatchData); + if (TransactionType.EIP1559.getEthSerializedType() == b[0]) { + return SpanBatchDynamicFeeTxData.decode(input); } return null; } diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxData.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxData.java index 1d53d9dc..35f8402a 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxData.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxData.java @@ -1,6 +1,8 @@ package io.optimism.utilities.derive.stages; +import org.hyperledger.besu.datatypes.TransactionType; + public interface SpanBatchTxData { - byte txType(); + TransactionType txType(); } diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxs.java b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxs.java index b36a8e4b..2525ad22 100644 --- a/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxs.java +++ b/hildr-utilities/src/main/java/io/optimism/utilities/derive/stages/SpanBatchTxs.java @@ -1,31 +1,28 @@ package io.optimism.utilities.derive.stages; -import static org.web3j.crypto.transaction.type.TransactionType.EIP1559; -import static org.web3j.crypto.transaction.type.TransactionType.EIP2930; -import static org.web3j.crypto.transaction.type.TransactionType.LEGACY; +import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_PROTECTED_V_BASE; +import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE; -import io.libp2p.etc.types.ByteBufExtKt; +import com.google.common.primitives.Longs; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.Unpooled; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import org.apache.tuweni.bytes.Bytes; -import org.web3j.crypto.Keys; -import org.web3j.crypto.Sign; -import org.web3j.crypto.SignedRawTransaction; -import org.web3j.crypto.TransactionDecoder; -import org.web3j.crypto.transaction.type.ITransaction; -import org.web3j.crypto.transaction.type.Transaction1559; -import org.web3j.crypto.transaction.type.Transaction2930; -import org.web3j.crypto.transaction.type.TransactionType; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.core.encoding.EncodingContext; +import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder; +import org.jetbrains.annotations.NotNull; import org.web3j.utils.Numeric; public class SpanBatchTxs { - private Long totalBlockTxCount; + private static final long MaxSpanBatchSize = 10000000L; + private long totalBlockTxCount; private BigInteger contractCreationBits; private BigInteger yParityBits; private List txSigs; @@ -33,7 +30,11 @@ public class SpanBatchTxs { private List txGases; private List txTos; private List txDatas; - private List txTypes; + private List txTypes; + + private long totalLegacyTxCount; + + private BigInteger protectedBits; public SpanBatchTxs() {} @@ -46,7 +47,9 @@ public SpanBatchTxs( List txGases, List txTos, List txDatas, - List txTypes) { + List txTypes, + long totalLegacyTxCount, + BigInteger protectedBits) { this.totalBlockTxCount = totalBlockTxCount; this.contractCreationBits = contractCreationBits; this.yParityBits = yParityBits; @@ -56,28 +59,17 @@ public SpanBatchTxs( this.txTos = txTos; this.txDatas = txDatas; this.txTypes = txTypes; + this.totalLegacyTxCount = totalLegacyTxCount; + this.protectedBits = protectedBits; } + /** + * contractCreationBits is bitlist right-padded to a multiple of 8 bits. + * + * @return encoded contract creation bits. + */ public byte[] encodeContractCreationBits() { - Long contractCreationBitBufferLen = this.totalBlockTxCount / 8; - if (this.totalBlockTxCount % 8 != 0) { - contractCreationBitBufferLen = contractCreationBitBufferLen + 1; - } - byte[] contractCreationBitBuffer = new byte[contractCreationBitBufferLen.intValue()]; - for (int i = 0; i < this.totalBlockTxCount; i += 8) { - int end = i + 8; - if (end < this.totalBlockTxCount.intValue()) { - end = this.totalBlockTxCount.intValue(); - } - int bits = 0; - for (int j = i; j < end; j++) { - if (this.contractCreationBits.testBit(j)) { - bits |= 1 << (j - i); - } - } - contractCreationBitBuffer[i / 8] = (byte) bits; - } - return contractCreationBitBuffer; + return encodeSpanBatchBits((int) this.totalBlockTxCount, this.contractCreationBits); } /** @@ -86,30 +78,26 @@ public byte[] encodeContractCreationBits() { * @param contractCreationBit encoded contract creation bits. */ public void decodeContractCreationBits(byte[] contractCreationBit) { - Long contractCreationBitBufferLen = this.totalBlockTxCount / 8; - if (this.totalBlockTxCount % 8 != 0) { - contractCreationBitBufferLen = contractCreationBitBufferLen + 1; - } - if (contractCreationBitBufferLen > 10000000) { - throw new RuntimeException("span batch size limit reached"); - } - byte[] contractCreationBitBuffer = new byte[contractCreationBitBufferLen.intValue()]; - System.arraycopy(contractCreationBit, 0, contractCreationBitBuffer, 0, contractCreationBit.length); - BigInteger contractCreationbits = BigInteger.ZERO; - for (int i = 0; i < this.totalBlockTxCount; i += 8) { - int end = i + 8; - if (end < this.totalBlockTxCount.intValue()) { - end = this.totalBlockTxCount.intValue(); - } - byte bits = contractCreationBitBuffer[i / 8]; - for (int j = i; j < end; j++) { - int bit = (bits >> (j - i)) & 1; - if (bit != 0) { - contractCreationbits = contractCreationbits.setBit(j); - } - } - } - this.contractCreationBits = contractCreationbits; + this.contractCreationBits = + decodeSpanBatchBits(Unpooled.wrappedBuffer(contractCreationBit), (int) this.totalBlockTxCount); + } + + /** + * protectedBits is bitlist right-padded to a multiple of 8 bits. + * + * @return encoded protected bits. + */ + public byte[] encodeProtectedBits() { + return encodeSpanBatchBits((int) this.totalLegacyTxCount, this.protectedBits); + } + + /** + * protectedBits is bitlist right-padded to a multiple of 8 bits. + * + * @param protectedBit encoded protected bits. + */ + public void decodeProtectedBits(byte[] protectedBit) { + this.protectedBits = decodeSpanBatchBits(Unpooled.wrappedBuffer(protectedBit), (int) this.totalLegacyTxCount); } /** @@ -117,11 +105,11 @@ public void decodeContractCreationBits(byte[] contractCreationBit) { * * @return the number of contract creations in the batch. */ - public Long contractCreationCount() { + public long contractCreationCount() { if (contractCreationBits == null) { throw new RuntimeException("dev error: contract creation bits not set"); } - Long result = 0L; + long result = 0L; for (int i = 0; i < this.totalBlockTxCount; i++) { if (contractCreationBits.testBit(i)) { result++; @@ -130,134 +118,116 @@ public Long contractCreationCount() { return result; } + /** + * yParityBits is bitlist right-padded to a multiple of 8 bits. + * + * @return encoded y parity bits. + */ public byte[] encodeYParityBits() { - Long yParityBitBufferLen = this.totalBlockTxCount / 8; - if (this.totalBlockTxCount % 8 != 0) { - yParityBitBufferLen++; - } - byte[] yParityBitBuffer = new byte[yParityBitBufferLen.intValue()]; - for (int i = 0; i < this.totalBlockTxCount; i += 8) { - int end = i + 8; - if (end < this.totalBlockTxCount.intValue()) { - end = this.totalBlockTxCount.intValue(); - } - int bits = 0; - for (int j = i; j < end; j++) { - if (yParityBits.testBit(j)) { - bits |= 1 << (j - i); - } - } - yParityBitBuffer[i / 8] = (byte) bits; - } - return yParityBitBuffer; + return encodeSpanBatchBits((int) this.totalBlockTxCount, this.yParityBits); } + /** + * yParityBits is bitlist right-padded to a multiple of 8 bits. + * + * @param yParityBit encoded y parity bits. + */ public void decodeYParityBits(byte[] yParityBit) { - Long yParityBitBufferLen = this.totalBlockTxCount / 8; - if (this.totalBlockTxCount % 8 != 0) { - yParityBitBufferLen++; - } - if (yParityBitBufferLen > 10000000L) { - throw new RuntimeException("span batch size limit reached"); - } - - BigInteger yParityBits = BigInteger.ZERO; - for (int i = 0; i < this.totalBlockTxCount; i += 8) { - int end = i + 8; - if (end < this.totalBlockTxCount.intValue()) { - end = this.totalBlockTxCount.intValue(); - } - byte bits = yParityBit[i / 8]; - for (int j = i; j < end; j++) { - int bit = (bits >> (j - i)) & 1; - if (bit != 0) { - yParityBits = yParityBits.setBit(j); - } - } - } - this.yParityBits = yParityBits; + this.yParityBits = decodeSpanBatchBits(Unpooled.wrappedBuffer(yParityBit), (int) this.totalBlockTxCount); } public byte[] encodeTxSigsRS() { - ByteBuffer result = ByteBuffer.allocate(64 * this.totalBlockTxCount.intValue()); - for (SpanBatchSignature signature : txSigs) { - byte[] rBytes = Numeric.toBytesPadded(signature.r(), 32); - result.put(rBytes); - byte[] sBytes = Numeric.toBytesPadded(signature.s(), 32); - result.put(sBytes); + ByteBuf result = PooledByteBufAllocator.DEFAULT.buffer(64 * txSigs.size()); + for (SpanBatchSignature txSig : txSigs) { + byte[] rBytes = Numeric.toBytesPadded(txSig.r(), 32); + byte[] sBytes = Numeric.toBytesPadded(txSig.s(), 32); + result.writeBytes(rBytes); + result.writeBytes(sBytes); } - return result.array(); + return ByteBufUtil.getBytes(result); } public void decodeTxSigsRS(byte[] txSigsBuffer) { + this.txSigs = decodeSpanBatchTxSigsRS(txSigsBuffer); + } + + public static List decodeSpanBatchTxSigsRS(byte[] txSigsBuffer) { List txSigs = new ArrayList<>(); - for (int i = 0; i < this.totalBlockTxCount.intValue(); i++) { - byte[] r = new byte[32]; - System.arraycopy(txSigsBuffer, i * 64, r, 0, 32); - byte[] s = new byte[32]; - System.arraycopy(txSigsBuffer, 32 + i * 64, s, 0, 32); + ByteBuf buffer = Unpooled.wrappedBuffer(txSigsBuffer); + while (buffer.readableBytes() > 0) { + var r = ByteBufUtil.getBytes(buffer.readBytes(32)); + var s = ByteBufUtil.getBytes(buffer.readBytes(32)); BigInteger rInt = Numeric.toBigInt(r); BigInteger sInt = Numeric.toBigInt(s); txSigs.add(new SpanBatchSignature(BigInteger.ZERO, rInt, sInt)); } - this.txSigs = txSigs; + return txSigs; } - public Bytes encodeTxNonces() { - ByteBuf buffer = Unpooled.buffer(10); + public byte[] encodeTxNonces() { + ByteBuf buffer = Unpooled.buffer((int) (10 * totalBlockTxCount)); for (BigInteger txNonce : txNonces) { - ByteBufExtKt.writeUvarint(buffer, txNonce.longValue()); + putVarLong(txNonce.longValue(), buffer); } - return Bytes.wrap(ByteBufUtil.getBytes(buffer)); + return ByteBufUtil.getBytes(buffer); } - public void decodeTxNonces(Bytes bytes) { - List txNonces = new ArrayList<>(); - ByteBuf buffer = Unpooled.wrappedBuffer(bytes.toArrayUnsafe()); - for (int i = 0; i < this.totalBlockTxCount.intValue(); i++) { - BigInteger txNonce = BigInteger.valueOf(ByteBufExtKt.readUvarint(buffer)); - txNonces.add(txNonce); - } - this.txNonces = txNonces; + public void decodeTxNonces(byte[] txNoncesBuffer) { + this.txNonces = decodeSpanBatchTxNonces(txNoncesBuffer); } - public Bytes encodeTxGases() { - ByteBuf buffer = Unpooled.buffer(10); + public static List decodeSpanBatchTxNonces(byte[] nonces) { + return getBigIntegers(nonces); + } + + public byte[] encodeTxGases() { + ByteBuf buffer = Unpooled.buffer(10 * txGases.size()); for (BigInteger txGas : txGases) { - ByteBufExtKt.writeUvarint(buffer, txGas.longValue()); + putVarLong(txGas.longValue(), buffer); } - return Bytes.wrap(ByteBufUtil.getBytes(buffer)); + return ByteBufUtil.getBytes(buffer); } public void decodeTxGases(Bytes bytes) { - List txGases = new ArrayList<>(); - ByteBuf buffer = Unpooled.wrappedBuffer(bytes.toArrayUnsafe()); - for (int i = 0; i < this.totalBlockTxCount.intValue(); i++) { - BigInteger txNonce = BigInteger.valueOf(ByteBufExtKt.readUvarint(buffer)); - txGases.add(txNonce); - } - this.txGases = txGases; + this.txGases = decodeSpanBatchTxGases(bytes.toArray()); + } + + public static List decodeSpanBatchTxGases(byte[] gases) { + return getBigIntegers(gases); } public byte[] encodeTxTos() { - ByteBuffer result = ByteBuffer.allocate(20 * this.totalBlockTxCount.intValue()); + ByteBuf result = PooledByteBufAllocator.DEFAULT.buffer(20 * txTos.size()); for (String txTo : txTos) { - byte[] addressBytes = Numeric.hexStringToByteArray(txTo.substring(2)); - result.put(addressBytes); + byte[] addressBytes = Numeric.hexStringToByteArray(txTo); + result.writeBytes(addressBytes); } - return result.array(); + return ByteBufUtil.getBytes(result); } public void decodeTxTos(byte[] txTosBuffer) { + this.txTos = decodeSpanBatchTxTos(txTosBuffer); + } + + public static List decodeSpanBatchTxTos(byte[] txTosBuffer) { List txTos = new ArrayList<>(); - for (int i = 0; i < this.totalBlockTxCount.intValue(); i++) { - byte[] addBytes = new byte[20]; - System.arraycopy(txTosBuffer, i * 20, addBytes, 0, 20); - String address = Keys.toChecksumAddress(Numeric.toHexStringNoPrefix(addBytes)) - .toLowerCase(); - txTos.add(address); + ByteBuf buffer = Unpooled.wrappedBuffer(txTosBuffer); + while (buffer.readableBytes() > 0) { + ByteBuf addressBuf = buffer.readBytes(20); + txTos.add(Numeric.toHexString(ByteBufUtil.getBytes(addressBuf))); } - this.txTos = txTos; + return txTos; + } + + public static List decodeSpanBatchTxDatas(byte[] txDatasBuffer) { + TransactionDecoder.decodeOpaqueBytes(Bytes.wrap(txDatasBuffer), EncodingContext.BLOCK_BODY); + List txTos = new ArrayList<>(); + ByteBuf buffer = Unpooled.wrappedBuffer(txDatasBuffer); + while (buffer.readableBytes() > 0) { + ByteBuf addressBuf = buffer.readBytes(20); + txTos.add(Numeric.toHexString(ByteBufUtil.getBytes(addressBuf))); + } + return txTos; } // No Test @@ -267,83 +237,81 @@ public void recoverV(BigInteger chainId) { } for (int i = 0; i < this.txTypes.size(); i++) { BigInteger bit = this.yParityBits.testBit(i) ? BigInteger.ONE : BigInteger.ZERO; - BigInteger v; - int type = this.txTypes.get(i); - switch (type) { - case 0: - v = chainId.multiply(new BigInteger("2")) - .add(BigInteger.valueOf(35)) - .add(bit); - break; - case 1, 2: - v = bit; - break; - default: - throw new RuntimeException("invalid tx type:" + this.txTypes.get(i)); - } - SpanBatchSignature old = this.txSigs.get(i); - SpanBatchSignature newTxSig = new SpanBatchSignature(v, old.r(), old.s()); + SpanBatchSignature newTxSig = getSpanBatchSignature(chainId, i, bit); this.txSigs.set(i, newTxSig); } } - public static SpanBatchTxs newSpanBatchTxs(List txs, int chainId) { - Long totalBlockTxCount = Long.valueOf(txs.size()); + @NotNull private SpanBatchSignature getSpanBatchSignature(BigInteger chainId, int i, BigInteger bit) { + BigInteger v; + int type = this.txTypes.get(i); + v = switch (type) { + case 0 -> chainId.multiply(new BigInteger("2")) + .add(BigInteger.valueOf(35)) + .add(bit); + case 1, 2 -> bit; + default -> throw new RuntimeException("invalid tx type:%d".formatted(this.txTypes.get(i)));}; + SpanBatchSignature old = this.txSigs.get(i); + return new SpanBatchSignature(v, old.r(), old.s()); + } + + public static SpanBatchTxs newSpanBatchTxs(List txs, BigInteger chainId) { + long totalBlockTxCount = txs.size(); BigInteger contractCreationBits = BigInteger.ZERO; BigInteger yParityBits = BigInteger.ZERO; + BigInteger protectedBits = BigInteger.ZERO; List txSigs = new ArrayList<>(); List txTos = new ArrayList<>(); List txNonces = new ArrayList<>(); List txGases = new ArrayList<>(); List txDatas = new ArrayList<>(); - List txTypes = new ArrayList<>(); - for (int idx = 0; idx < totalBlockTxCount.intValue(); idx++) { + List txTypes = new ArrayList<>(); + long totalLegacyTxCount = 0; + for (int idx = 0; idx < totalBlockTxCount; idx++) { String tx = txs.get(idx); - SignedRawTransaction rawTransaction = (SignedRawTransaction) TransactionDecoder.decode(tx); - ITransaction transaction = rawTransaction.getTransaction(); - if (EIP1559.equals(rawTransaction.getType())) { - Transaction1559 transaction1559 = (Transaction1559) transaction; - if (transaction1559.getChainId() != chainId) { - throw new RuntimeException("chainId mismatch. tx has chain ID:" + transaction1559.getChainId() - + ", expected:" + chainId + ", but expected chain ID:" + chainId); + Bytes txnBytes = Bytes.fromHexString(tx); + Transaction rawTransaction = TransactionDecoder.decodeOpaqueBytes(txnBytes, EncodingContext.BLOCK_BODY); + if (rawTransaction.getType() == TransactionType.FRONTIER) { + if (rawTransaction.getChainId().isPresent()) { + protectedBits = protectedBits.setBit((int) totalLegacyTxCount); + } else { + protectedBits = protectedBits.clearBit((int) totalLegacyTxCount); } + totalLegacyTxCount++; } - if (EIP2930.equals(rawTransaction.getType())) { - Transaction2930 transaction2930 = (Transaction2930) transaction; - if (transaction2930.getChainId() != chainId) { - throw new RuntimeException("chainId mismatch. tx has chain ID:" + transaction2930.getChainId() - + ", expected:" + chainId + ", but expected chain ID:" + chainId); - } + if (rawTransaction.getChainId().isPresent() + && rawTransaction.getChainId().get().compareTo(chainId) != 0) { + throw new RuntimeException("chainId mismatch. tx has chain ID:%d, expected:%d, but expected chain ID:%d" + .formatted(rawTransaction.getChainId().get(), chainId, chainId)); } - Sign.SignatureData signatureData = rawTransaction.getSignatureData(); - BigInteger v = new BigInteger(1, signatureData.getV()); - BigInteger r = new BigInteger(1, signatureData.getR()); - BigInteger s = new BigInteger(1, signatureData.getS()); - - SpanBatchSignature txSig = new SpanBatchSignature(v, r, s); + SpanBatchSignature txSig = new SpanBatchSignature( + rawTransaction.getType() == TransactionType.FRONTIER + ? rawTransaction.getV() + : rawTransaction.getYParity(), + rawTransaction.getR(), + rawTransaction.getS()); txSigs.add(txSig); - BigInteger contractCreationBit = BigInteger.ONE; - if (transaction.getTo() != null) { - txTos.add(transaction.getTo()); + if (rawTransaction.getTo().isPresent()) { + txTos.add(rawTransaction.getTo().get().toHexString()); + contractCreationBits = contractCreationBits.clearBit(idx); } else { - contractCreationBit = contractCreationBit.setBit(idx); + contractCreationBits = contractCreationBits.setBit(idx); } - BigInteger yParityBit = convertVToYParity(txSig.v(), transaction.getType()); - if (yParityBit.testBit(idx)) { - yParityBit = yParityBit.setBit(idx); + BigInteger yParityBit = convertVToYParity(rawTransaction); + if (yParityBit.equals(BigInteger.ONE)) { + yParityBits = yParityBits.setBit(idx); + } else if (yParityBit.equals(BigInteger.ZERO)) { + yParityBits = yParityBits.clearBit(idx); + } else { + throw new RuntimeException("invalid y parity bit:%d".formatted(yParityBit)); } - txNonces.add(transaction.getNonce()); - txGases.add(transaction.getGasLimit()); - SpanBatchTx stx = SpanBatchTx.newSpanBatchTx(transaction); + txNonces.add(Numeric.toBigInt(Longs.toByteArray(rawTransaction.getNonce()))); + txGases.add(Numeric.toBigInt(Longs.toByteArray(rawTransaction.getGasLimit()))); + SpanBatchTx stx = SpanBatchTx.newSpanBatchTx(rawTransaction); byte[] stxByte = stx.marshalBinary(); txDatas.add(Numeric.toHexString(stxByte)); - if (transaction.getType() == null || transaction.getType().getRlpType() == null) { - txTypes.add(0); - } else { - String hex = Integer.toHexString(transaction.getType().getRlpType() & 0xFF); - txTypes.add(Integer.parseInt(hex, 10)); - } + txTypes.add(rawTransaction.getType().getEthSerializedType()); } return new SpanBatchTxs( totalBlockTxCount, @@ -354,18 +322,9 @@ public static SpanBatchTxs newSpanBatchTxs(List txs, int chainId) { txGases, txTos, txDatas, - txTypes); - } - - public static BigInteger convertVToYParity(BigInteger v, TransactionType txType) { - if (EIP1559 == txType || EIP2930 == txType) { - return v; - } - if (LEGACY == txType) { - int res = (v.intValue() - 35) & 1; - return BigInteger.valueOf(res); - } - return null; + txTypes, + totalLegacyTxCount, + protectedBits); } public Long getTotalBlockTxCount() { @@ -432,11 +391,152 @@ public void setTxDatas(List txDatas) { this.txDatas = txDatas; } - public List getTxTypes() { + public List getTxTypes() { return txTypes; } - public void setTxTypes(List txTypes) { + public void setTxTypes(List txTypes) { this.txTypes = txTypes; } + + public static BigInteger convertVToYParity(Transaction transaction) { + switch (transaction.getType()) { + case FRONTIER -> { + if (transaction.getChainId().isPresent()) { + return transaction.getV().subtract(REPLAY_PROTECTED_V_BASE).and(BigInteger.ONE); + } else { + return transaction.getV().subtract(REPLAY_UNPROTECTED_V_BASE); + } + } + case EIP1559, ACCESS_LIST -> { + return transaction.getYParity(); + } + default -> throw new RuntimeException("invalid tx type:%s".formatted(transaction.getType())); + } + } + + public static BigInteger decodeSpanBatchBits(ByteBuf source, int bitLength) { + var bufLen = bitLength / 8; + if (bitLength % 8 != 0) { + bufLen++; + } + if (bufLen > MaxSpanBatchSize) { + throw new RuntimeException("span batch size limit reached"); + } + byte[] buf = new byte[(int) bufLen]; + try { + source.readBytes(buf); + } catch (Exception e) { + throw new RuntimeException("read error"); + } + var res = Numeric.toBigInt(buf); + if (res.bitLength() > bitLength) { + throw new RuntimeException("invalid bit length"); + } + return res; + } + + public static byte[] encodeSpanBatchBits(int bitLength, BigInteger bits) { + if (bits.bitLength() > bitLength) { + throw new RuntimeException( + "bitfield is larger than bitLength: %d > %d".formatted(bits.bitLength(), bitLength)); + } + + var bufLen = bitLength / 8; + if (bitLength % 8 != 0) { + bufLen++; + } + if (bufLen > MaxSpanBatchSize) { + throw new RuntimeException("span batch size limit reached"); + } + return Numeric.toBytesPadded(bits, bufLen); + } + + private static List getBigIntegers(byte[] gases) { + List txNonces = new ArrayList<>(); + ByteBuf buffer = Unpooled.wrappedBuffer(gases); + while (buffer.readableBytes() > 0) { + txNonces.add(Numeric.toBigInt(Longs.toByteArray(getVarLong(buffer)))); + } + return txNonces; + } + + /** + * Reads an up to 64 bit long varint from the current position of the + * given ByteBuffer and returns the decoded value as long. + * + *

The position of the buffer is advanced to the first byte after the + * decoded varint. + * + * @param src the ByteBuffer to get the var int from + * @return The integer value of the decoded long varint + */ + public static long getVarLong(ByteBuf src) { + long tmp; + if ((tmp = src.readByte()) >= 0) { + return tmp; + } + long result = tmp & 0x7f; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 7; + } else { + result |= (tmp & 0x7f) << 7; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 14; + } else { + result |= (tmp & 0x7f) << 14; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 21; + } else { + result |= (tmp & 0x7f) << 21; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 28; + } else { + result |= (tmp & 0x7f) << 28; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 35; + } else { + result |= (tmp & 0x7f) << 35; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 42; + } else { + result |= (tmp & 0x7f) << 42; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 49; + } else { + result |= (tmp & 0x7f) << 49; + if ((tmp = src.readByte()) >= 0) { + result |= tmp << 56; + } else { + result |= (tmp & 0x7f) << 56; + result |= ((long) src.readByte()) << 63; + } + } + } + } + } + } + } + } + return result; + } + + /** + * Encodes a long integer in a variable-length encoding, 7 bits per byte, to a + * ByteBuffer sink. + * + * @param v the value to encode + * @param sink the ByteBuffer to add the encoded value + */ + public static void putVarLong(long v, ByteBuf sink) { + while (true) { + int bits = ((int) v) & 0x7f; + v >>>= 7; + if (v == 0) { + sink.writeByte((byte) bits); + return; + } + sink.writeByte((byte) (bits | 0x80)); + } + } } diff --git a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/BatchTest.java b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/BatchTest.java index f5c00c14..15a8f841 100644 --- a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/BatchTest.java +++ b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/BatchTest.java @@ -1,156 +1,156 @@ -package io.optimism.utilities.derive.stages; - -import java.math.BigInteger; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import org.apache.tuweni.units.bigints.UInt64; -import org.web3j.crypto.Credentials; -import org.web3j.crypto.ECKeyPair; -import org.web3j.crypto.Keys; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; -import org.web3j.crypto.transaction.type.LegacyTransaction; -import org.web3j.utils.Numeric; - -public class BatchTest { - - public static RawSpanBatch randomRawSpanBatch(int chainId) - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - BigInteger originBits = BigInteger.ZERO; - long blockCountLong = 1 + (random.nextInt() & 0xFFL); - BigInteger blockCount = BigInteger.valueOf(blockCountLong); - List blockTxCounts = new ArrayList<>(); - BigInteger totalBlockTxCounts = BigInteger.ZERO; - for (int i = 0; i < blockCount.intValue(); i++) { - BigInteger blockTxCount = BigInteger.valueOf(random.nextInt(16)); - blockTxCounts.add(blockTxCount); - totalBlockTxCounts = totalBlockTxCounts.add(blockTxCount); - } - ECKeyPair ecKeyPair = Keys.createEcKeyPair(); - Credentials credentials = Credentials.create(ecKeyPair); - List txs = new ArrayList<>(); - for (int i = 0; i < totalBlockTxCounts.intValue(); i++) { - String tx = randomTransaction(credentials, chainId, UInt64.random().toBigInteger()); - txs.add(tx); - } - SpanBatchTxs spanBatchTxs = SpanBatchTxs.newSpanBatchTxs(txs, chainId); - - SpanBatchPrefix spanBatchPrefix = new SpanBatchPrefix( - UInt64.random().toBigInteger(), - UInt64.random().toBigInteger(), - Numeric.toHexString(generateRandomData(20)), - Numeric.toHexString(generateRandomData(20))); - SpanBatchPayload spanBatchPayload = new SpanBatchPayload(blockCount, originBits, blockTxCounts, spanBatchTxs); - - return new RawSpanBatch(spanBatchPrefix, spanBatchPayload); - } - - public static SingularBatch randomSingularBatch(int txCount, int chainId) - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - ECKeyPair ecKeyPair = Keys.createEcKeyPair(); - Credentials credentials = Credentials.create(ecKeyPair); - Random rng = new Random(); - BigInteger maxLimit = new BigInteger("300000000000"); - BigInteger randomBigInteger = new BigInteger(maxLimit.bitLength(), rng); - while (randomBigInteger.compareTo(maxLimit) >= 0) { - randomBigInteger = new BigInteger(maxLimit.bitLength(), rng); - } - List txsEncoded = new ArrayList<>(); - for (int i = 0; i < txCount; i++) { - String txEncode = randomTransaction(credentials, chainId, randomBigInteger); - txsEncoded.add(txEncode); - } - return new SingularBatch( - RandomUtils.randomHex(), - UInt64.random().toBigInteger(), - RandomUtils.randomHex(), - UInt64.random().toBigInteger(), - txsEncoded); - } - - public static String randomTransaction(Credentials credentials, int chainId, BigInteger baseFee) - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - List list = Arrays.asList(0, 1, 2); - int index = new Random().nextInt(list.size()); - return switch (list.get(index)) { - case 0 -> randomLegacyTx(credentials); - case 1 -> randomAccessListTx(credentials, chainId); - case 2 -> randomDynamicFeeTxWithBaseFee(credentials, chainId, baseFee); - default -> throw new RuntimeException("invalid tx type"); - }; - } - - public static String randomLegacyTx(Credentials credentials) - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - LegacyTransaction lt = buildTransaction(); - RawTransaction rawTransaction = RawTransaction.createTransaction( - lt.getNonce(), lt.getGasPrice(), lt.getGasLimit(), lt.getTo(), lt.getValue(), lt.getData()); - TransactionEncoder.signMessage(rawTransaction, credentials); - byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); - return Numeric.toHexString(signedMessage); - } - - public static String randomAccessListTx(Credentials credentials, int chainId) - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - LegacyTransaction lt = buildTransaction(); - // 2930 - RawTransaction rawTransaction = RawTransaction.createTransaction( - chainId, - lt.getNonce(), - lt.getGasPrice(), - lt.getGasLimit(), - lt.getTo(), - lt.getValue(), - lt.getData(), - new ArrayList<>()); - TransactionEncoder.signMessage(rawTransaction, credentials); - byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); - return Numeric.toHexString(signedMessage); - } - - public static String randomDynamicFeeTxWithBaseFee(Credentials credentials, int chainId, BigInteger baseFee) - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - LegacyTransaction lt = buildTransaction(); - Random random = new Random(); - BigInteger tip = BigInteger.valueOf(random.nextInt(10)).multiply(BigInteger.TEN.pow(9)); - BigInteger fee = baseFee.add(tip); - // 1559 - RawTransaction rawTransaction = RawTransaction.createTransaction( - chainId, lt.getNonce(), lt.getGasLimit(), lt.getTo(), lt.getValue(), lt.getData(), tip, fee); - TransactionEncoder.signMessage(rawTransaction, credentials); - byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); - return Numeric.toHexString(signedMessage); - } - - public static LegacyTransaction buildTransaction() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - BigInteger nonce = BigInteger.valueOf(random.nextInt(10000)); - BigInteger gasPrice = BigInteger.valueOf(random.nextInt(10000)); - BigInteger gas = BigInteger.valueOf(random.nextInt(1999999)).add(new BigInteger("21000")); - String to = randomAddress(); - BigInteger value = BigInteger.valueOf(random.nextInt(10)).multiply(BigInteger.TEN.pow(18)); - byte[] data = generateRandomData(10); - return new LegacyTransaction(nonce, gasPrice, gas, to, value, Numeric.toHexString(data)); - } - - public static String randomAddress() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - ECKeyPair ecKeyPair = Keys.createEcKeyPair(); - Credentials credentials = Credentials.create(ecKeyPair); - return credentials.getAddress(); - } - - public static byte[] generateRandomData(int size) { - Random rng = new Random(); - byte[] out = new byte[size]; - rng.nextBytes(out); - return out; - } -} +// package io.optimism.utilities.derive.stages; +// +// import java.math.BigInteger; +// import java.security.InvalidAlgorithmParameterException; +// import java.security.NoSuchAlgorithmException; +// import java.security.NoSuchProviderException; +// import java.util.ArrayList; +// import java.util.Arrays; +// import java.util.List; +// import java.util.Random; +// import org.apache.tuweni.units.bigints.UInt64; +// import org.web3j.crypto.Credentials; +// import org.web3j.crypto.ECKeyPair; +// import org.web3j.crypto.Keys; +// import org.web3j.crypto.RawTransaction; +// import org.web3j.crypto.TransactionEncoder; +// import org.web3j.crypto.transaction.type.LegacyTransaction; +// import org.web3j.utils.Numeric; +// +// public class BatchTest { +// +// public static RawSpanBatch randomRawSpanBatch(int chainId) +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// Random random = new Random(); +// BigInteger originBits = BigInteger.ZERO; +// long blockCountLong = 1 + (random.nextInt() & 0xFFL); +// BigInteger blockCount = BigInteger.valueOf(blockCountLong); +// List blockTxCounts = new ArrayList<>(); +// BigInteger totalBlockTxCounts = BigInteger.ZERO; +// for (int i = 0; i < blockCount.intValue(); i++) { +// BigInteger blockTxCount = BigInteger.valueOf(random.nextInt(16)); +// blockTxCounts.add(blockTxCount); +// totalBlockTxCounts = totalBlockTxCounts.add(blockTxCount); +// } +// ECKeyPair ecKeyPair = Keys.createEcKeyPair(); +// Credentials credentials = Credentials.create(ecKeyPair); +// List txs = new ArrayList<>(); +// for (int i = 0; i < totalBlockTxCounts.intValue(); i++) { +// String tx = randomTransaction(credentials, chainId, UInt64.random().toBigInteger()); +// txs.add(tx); +// } +// SpanBatchTxs spanBatchTxs = SpanBatchTxs.newSpanBatchTxs(txs, chainId); +// +// SpanBatchPrefix spanBatchPrefix = new SpanBatchPrefix( +// UInt64.random().toBigInteger(), +// UInt64.random().toBigInteger(), +// Numeric.toHexString(generateRandomData(20)), +// Numeric.toHexString(generateRandomData(20))); +// SpanBatchPayload spanBatchPayload = new SpanBatchPayload(blockCount, originBits, blockTxCounts, spanBatchTxs); +// +// return new RawSpanBatch(spanBatchPrefix, spanBatchPayload); +// } +// +// public static SingularBatch randomSingularBatch(int txCount, int chainId) +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// ECKeyPair ecKeyPair = Keys.createEcKeyPair(); +// Credentials credentials = Credentials.create(ecKeyPair); +// Random rng = new Random(); +// BigInteger maxLimit = new BigInteger("300000000000"); +// BigInteger randomBigInteger = new BigInteger(maxLimit.bitLength(), rng); +// while (randomBigInteger.compareTo(maxLimit) >= 0) { +// randomBigInteger = new BigInteger(maxLimit.bitLength(), rng); +// } +// List txsEncoded = new ArrayList<>(); +// for (int i = 0; i < txCount; i++) { +// String txEncode = randomTransaction(credentials, chainId, randomBigInteger); +// txsEncoded.add(txEncode); +// } +// return new SingularBatch( +// RandomUtils.randomHex(), +// UInt64.random().toBigInteger(), +// RandomUtils.randomHex(), +// UInt64.random().toBigInteger(), +// txsEncoded); +// } +// +// public static String randomTransaction(Credentials credentials, int chainId, BigInteger baseFee) +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// List list = Arrays.asList(0, 1, 2); +// int index = new Random().nextInt(list.size()); +// return switch (list.get(index)) { +// case 0 -> randomLegacyTx(credentials); +// case 1 -> randomAccessListTx(credentials, chainId); +// case 2 -> randomDynamicFeeTxWithBaseFee(credentials, chainId, baseFee); +// default -> throw new RuntimeException("invalid tx type"); +// }; +// } +// +// public static String randomLegacyTx(Credentials credentials) +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// LegacyTransaction lt = buildTransaction(); +// RawTransaction rawTransaction = RawTransaction.createTransaction( +// lt.getNonce(), lt.getGasPrice(), lt.getGasLimit(), lt.getTo(), lt.getValue(), lt.getData()); +// TransactionEncoder.signMessage(rawTransaction, credentials); +// byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); +// return Numeric.toHexString(signedMessage); +// } +// +// public static String randomAccessListTx(Credentials credentials, int chainId) +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// LegacyTransaction lt = buildTransaction(); +// // 2930 +// RawTransaction rawTransaction = RawTransaction.createTransaction( +// chainId, +// lt.getNonce(), +// lt.getGasPrice(), +// lt.getGasLimit(), +// lt.getTo(), +// lt.getValue(), +// lt.getData(), +// new ArrayList<>()); +// TransactionEncoder.signMessage(rawTransaction, credentials); +// byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); +// return Numeric.toHexString(signedMessage); +// } +// +// public static String randomDynamicFeeTxWithBaseFee(Credentials credentials, int chainId, BigInteger baseFee) +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// LegacyTransaction lt = buildTransaction(); +// Random random = new Random(); +// BigInteger tip = BigInteger.valueOf(random.nextInt(10)).multiply(BigInteger.TEN.pow(9)); +// BigInteger fee = baseFee.add(tip); +// // 1559 +// RawTransaction rawTransaction = RawTransaction.createTransaction( +// chainId, lt.getNonce(), lt.getGasLimit(), lt.getTo(), lt.getValue(), lt.getData(), tip, fee); +// TransactionEncoder.signMessage(rawTransaction, credentials); +// byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); +// return Numeric.toHexString(signedMessage); +// } +// +// public static LegacyTransaction buildTransaction() +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// Random random = new Random(); +// BigInteger nonce = BigInteger.valueOf(random.nextInt(10000)); +// BigInteger gasPrice = BigInteger.valueOf(random.nextInt(10000)); +// BigInteger gas = BigInteger.valueOf(random.nextInt(1999999)).add(new BigInteger("21000")); +// String to = randomAddress(); +// BigInteger value = BigInteger.valueOf(random.nextInt(10)).multiply(BigInteger.TEN.pow(18)); +// byte[] data = generateRandomData(10); +// return new LegacyTransaction(nonce, gasPrice, gas, to, value, Numeric.toHexString(data)); +// } +// +// public static String randomAddress() +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// ECKeyPair ecKeyPair = Keys.createEcKeyPair(); +// Credentials credentials = Credentials.create(ecKeyPair); +// return credentials.getAddress(); +// } +// +// public static byte[] generateRandomData(int size) { +// Random rng = new Random(); +// byte[] out = new byte[size]; +// rng.nextBytes(out); +// return out; +// } +// } diff --git a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SingularBatchTest.java b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SingularBatchTest.java index 8e10f7d5..48def05d 100644 --- a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SingularBatchTest.java +++ b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SingularBatchTest.java @@ -1,26 +1,26 @@ -package io.optimism.utilities.derive.stages; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.util.Random; -import org.junit.jupiter.api.Test; - -public class SingularBatchTest { - - @Test - public void TestSingularBatchForBatchInterface() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int txCount = 1 + random.nextInt(8); - int chainId = random.nextInt(1000); - - SingularBatch singularBatch = BatchTest.randomSingularBatch(txCount, chainId); - - assertEquals(singularBatch.getBatchType(), BatchType.SINGULAR_BATCH_TYPE.getCode()); - assertEquals(singularBatch.getTimestamp(), singularBatch.timestamp()); - assertEquals(singularBatch.epochNum(), singularBatch.getEpochNum()); - } -} +// package io.optimism.utilities.derive.stages; +// +// import static org.junit.jupiter.api.Assertions.assertEquals; +// +// import java.security.InvalidAlgorithmParameterException; +// import java.security.NoSuchAlgorithmException; +// import java.security.NoSuchProviderException; +// import java.util.Random; +// import org.junit.jupiter.api.Test; +// +// public class SingularBatchTest { +// +// @Test +// public void TestSingularBatchForBatchInterface() +// throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { +// Random random = new Random(); +// int txCount = 1 + random.nextInt(8); +// int chainId = random.nextInt(1000); +// +// SingularBatch singularBatch = BatchTest.randomSingularBatch(txCount, chainId); +// +// assertEquals(singularBatch.getBatchType(), BatchType.SINGULAR_BATCH_TYPE.getCode()); +// assertEquals(singularBatch.getTimestamp(), singularBatch.timestamp()); +// assertEquals(singularBatch.epochNum(), singularBatch.getEpochNum()); +// } +// } diff --git a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxTest.java b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxTest.java new file mode 100644 index 00000000..3b776522 --- /dev/null +++ b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxTest.java @@ -0,0 +1,129 @@ +package io.optimism.utilities.derive.stages; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.math.BigInteger; +import java.util.List; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.datatypes.AccessListEntry; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.junit.jupiter.api.Test; +import org.web3j.utils.Numeric; + +/** + * The type SpanBatchTxTest. + * + * @author grapebaba + * @since 0.2.4 + */ +class SpanBatchTxTest { + + /** + * Marshal binary. + */ + @Test + void marshalBinaryInterOp() { + Transaction.Builder builder = Transaction.builder(); + Transaction tx = builder.type(TransactionType.FRONTIER) + .nonce(10000000000L) + .gasPrice(Wei.of(new BigInteger("10000000000"))) + .gasLimit(311245L) + .to(Address.fromHexString("0xf1d2f39c58427bE48c5ECDa1E0cC7a930Ae1Ca50")) + .value(Wei.of(new BigInteger("6000000000000000000"))) + .payload(Bytes.fromHexString("0xba457aba24bbd63f5670")) + .build(); + + SpanBatchTx spanBatchTx = SpanBatchTx.newSpanBatchTx(tx); + byte[] bytes = spanBatchTx.marshalBinary(); + assertArrayEquals( + bytes, Numeric.hexStringToByteArray("0xda8853444835ec5800008502540be4008aba457aba24bbd63f5670")); + + Transaction accTx = Transaction.builder() + .type(TransactionType.ACCESS_LIST) + .gasPrice(Wei.of(new BigInteger("10000000000"))) + .value(Wei.of(new BigInteger("6000000000000000000"))) + .payload(Bytes.fromHexString("0xba457aba24bbd63f5670")) + .chainId(BigInteger.valueOf(1)) + .accessList(List.of(new AccessListEntry( + Address.fromHexString("0xf1d2f39c58427bE48c5ECDa1E0cC7a930Ae1Ca50"), + List.of(Hash.wrap(Bytes32.fromHexString("0x01")))))) + .build(); + + SpanBatchTx spanBatchTx2 = SpanBatchTx.newSpanBatchTx(accTx); + byte[] bytes2 = spanBatchTx2.marshalBinary(); + assertArrayEquals( + bytes2, + Numeric.hexStringToByteArray( + "0x01f8548853444835ec5800008502540be4008aba457aba24bbd63f5670f838f794f1d2f39c58427be48c5ecda1e0cc7a930ae1ca50e1a00000000000000000000000000000000000000000000000000000000000000001")); + + Transaction dynTx = Transaction.builder() + .type(TransactionType.EIP1559) + .maxPriorityFeePerGas(Wei.of(new BigInteger("10000000000"))) + .maxFeePerGas(Wei.of(new BigInteger("10000000000"))) + .value(Wei.of(new BigInteger("6000000000000000000"))) + .payload(Bytes.fromHexString("0xba457aba24bbd63f5670")) + .accessList(List.of(new AccessListEntry( + Address.fromHexString("0xf1d2f39c58427bE48c5ECDa1E0cC7a930Ae1Ca50"), + List.of(Hash.wrap(Bytes32.fromHexString("0x01")))))) + .chainId(BigInteger.valueOf(1)) + .build(); + + SpanBatchTx spanBatchTx3 = SpanBatchTx.newSpanBatchTx(dynTx); + byte[] bytes3 = spanBatchTx3.marshalBinary(); + assertArrayEquals( + bytes3, + Numeric.hexStringToByteArray( + "0x02f85a8853444835ec5800008502540be4008502540be4008aba457aba24bbd63f5670f838f794f1d2f39c58427be48c5ecda1e0cc7a930ae1ca50e1a00000000000000000000000000000000000000000000000000000000000000001")); + } + + /** + * Unmarshal binary. + */ + @Test + void unmarshalBinaryInterOp() { + SpanBatchTxData txData = SpanBatchTx.unmarshalBinary( + Numeric.hexStringToByteArray("0xda8853444835ec5800008502540be4008aba457aba24bbd63f5670")); + + assertNotNull(txData); + assertEquals(TransactionType.FRONTIER, txData.txType()); + assertEquals(Wei.of(new BigInteger("6000000000000000000")), ((SpanBatchLegacyTxData) txData).value()); + assertEquals(Wei.of(new BigInteger("10000000000")), ((SpanBatchLegacyTxData) txData).gasPrice()); + assertEquals(Bytes.fromHexString("0xba457aba24bbd63f5670"), ((SpanBatchLegacyTxData) txData).data()); + + SpanBatchTxData txData1 = SpanBatchTx.unmarshalBinary( + Numeric.hexStringToByteArray( + "0x01f8548853444835ec5800008502540be4008aba457aba24bbd63f5670f838f794f1d2f39c58427be48c5ecda1e0cc7a930ae1ca50e1a00000000000000000000000000000000000000000000000000000000000000001")); + assertNotNull(txData1); + assertEquals(TransactionType.ACCESS_LIST, txData1.txType()); + assertEquals(Wei.of(new BigInteger("6000000000000000000")), ((SpanBatchAccessListTxData) txData1).value()); + assertEquals(Wei.of(new BigInteger("10000000000")), ((SpanBatchAccessListTxData) txData1).gasPrice()); + assertEquals(Bytes.fromHexString("0xba457aba24bbd63f5670"), ((SpanBatchAccessListTxData) txData1).data()); + assertEquals( + List.of(new AccessListEntry( + Address.fromHexString("0xf1d2f39c58427bE48c5ECDa1E0cC7a930Ae1Ca50"), + List.of(Hash.wrap(Bytes32.fromHexString("0x01"))))), + ((SpanBatchAccessListTxData) txData1).accessList()); + + SpanBatchTxData txData2 = SpanBatchTx.unmarshalBinary( + Numeric.hexStringToByteArray( + "0x02f85a8853444835ec5800008502540be4008502540be4008aba457aba24bbd63f5670f838f794f1d2f39c58427be48c5ecda1e0cc7a930ae1ca50e1a00000000000000000000000000000000000000000000000000000000000000001")); + assertNotNull(txData2); + assertEquals(TransactionType.EIP1559, txData2.txType()); + assertEquals(Wei.of(new BigInteger("6000000000000000000")), ((SpanBatchDynamicFeeTxData) txData2).value()); + assertEquals(Wei.of(new BigInteger("10000000000")), ((SpanBatchDynamicFeeTxData) txData2).gasTipCap()); + assertEquals(Wei.of(new BigInteger("10000000000")), ((SpanBatchDynamicFeeTxData) txData2).gasFeeCap()); + assertEquals(Bytes.fromHexString("0xba457aba24bbd63f5670"), ((SpanBatchDynamicFeeTxData) txData2).data()); + assertEquals( + List.of(new AccessListEntry( + Address.fromHexString("0xf1d2f39c58427bE48c5ECDa1E0cC7a930Ae1Ca50"), + List.of(Hash.wrap(Bytes32.fromHexString("0x01"))))), + ((SpanBatchDynamicFeeTxData) txData2).accessList()); + } +} diff --git a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxsTest.java b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxsTest.java index 172f7bf1..40a315a4 100644 --- a/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxsTest.java +++ b/hildr-utilities/src/test/java/io/optimism/utilities/derive/stages/SpanBatchTxsTest.java @@ -1,183 +1,243 @@ package io.optimism.utilities.derive.stages; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import io.netty.buffer.Unpooled; +import java.io.IOException; import java.math.BigInteger; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; +import java.net.URL; import java.util.List; -import java.util.Random; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; +import org.web3j.utils.Numeric; public class SpanBatchTxsTest { - @Test - void TestSpanBatchTxsContractCreationBits() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - BigInteger contractCreationBits = rawSpanBatch.spanbatchPayload().txs().getContractCreationBits(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setContractCreationBits(contractCreationBits); - sbt.setTotalBlockTxCount(totalBlockTxCount); - - byte[] contractCreationBitsBuffer = sbt.encodeContractCreationBits(); - - Long contractCreationBitBufferLen = totalBlockTxCount / 8; - if (totalBlockTxCount % 8 != 0) { - contractCreationBitBufferLen++; - } - assertEquals(contractCreationBitBufferLen, contractCreationBitsBuffer.length); - - sbt.decodeContractCreationBits(contractCreationBitsBuffer); - - assertEquals(contractCreationBits, sbt.getContractCreationBits()); + void decodeAndEncodeSpanBatchBits() { + String test = + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + BigInteger res = SpanBatchTxs.decodeSpanBatchBits( + Unpooled.wrappedBuffer(Bytes.fromHexString(test).toArray()), 544); + var res1 = SpanBatchTxs.encodeSpanBatchBits(544, res); + assertArrayEquals(Numeric.hexStringToByteArray(test), res1); } @Test - public void TestSpanBatchTxsContractCreationCount() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - BigInteger contractCreationBits = rawSpanBatch.spanbatchPayload().txs().getContractCreationBits(); - Long contractCreationCount = rawSpanBatch.spanbatchPayload().txs().contractCreationCount(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setContractCreationBits(contractCreationBits); - sbt.setTotalBlockTxCount(totalBlockTxCount); - - byte[] contractCreationBitsBuffer = sbt.encodeContractCreationBits(); - sbt.setContractCreationBits(null); - sbt.decodeContractCreationBits(contractCreationBitsBuffer); - - Long contractCreationCount2 = sbt.contractCreationCount(); - assertEquals(contractCreationCount, contractCreationCount2); + void decodeAndEncodeTxSigs() throws IOException { + URL url = Resources.getResource("txsigs.txt"); + String test = Resources.toString(url, Charsets.UTF_8); + + List txSigs = SpanBatchTxs.decodeSpanBatchTxSigsRS(Numeric.hexStringToByteArray(test)); + SpanBatchTxs txs = new SpanBatchTxs(); + txs.setTxSigs(txSigs); + var res = txs.encodeTxSigsRS(); + assertArrayEquals(Numeric.hexStringToByteArray(test), res); } @Test - public void TestSpanBatchTxsYParityBits() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - BigInteger yParityBits = rawSpanBatch.spanbatchPayload().txs().getyParityBits(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setyParityBits(yParityBits); - sbt.setTotalBlockTxCount(totalBlockTxCount); - - byte[] yParityBitsBuffer = sbt.encodeYParityBits(); - Long yParityBitBufferLen = totalBlockTxCount / 8; - if (totalBlockTxCount % 8 != 0) { - yParityBitBufferLen++; - } - assertEquals(yParityBitBufferLen, yParityBitsBuffer.length); - - sbt.setyParityBits(null); - sbt.decodeYParityBits(yParityBitsBuffer); - assertEquals(yParityBits, sbt.getyParityBits()); + void decodeAndEncodeTxNonces() throws IOException { + URL url = Resources.getResource("txnonces.txt"); + String test = Resources.toString(url, Charsets.UTF_8); + + List txNonces = SpanBatchTxs.decodeSpanBatchTxNonces(Numeric.hexStringToByteArray(test)); + SpanBatchTxs txs = new SpanBatchTxs(); + txs.setTxNonces(txNonces); + var res = txs.encodeTxNonces(); + assertArrayEquals(Numeric.hexStringToByteArray(test), res); } @Test - public void TestSpanBatchTxsTxSigs() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - List txSigs = rawSpanBatch.spanbatchPayload().txs().getTxSigs(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setTotalBlockTxCount(totalBlockTxCount); - - sbt.setTxSigs(txSigs); - - byte[] txSigsBuffer = sbt.encodeTxSigsRS(); - - assertEquals(totalBlockTxCount * 64, txSigsBuffer.length); - - sbt.setTxSigs(null); - - sbt.decodeTxSigsRS(txSigsBuffer); - - for (int i = 0; i < totalBlockTxCount; i++) { - assertEquals(txSigs.get(i).r(), sbt.getTxSigs().get(i).r()); - assertEquals(txSigs.get(i).s(), sbt.getTxSigs().get(i).s()); - } - } - - @Test - public void TestSpanBatchTxsTxNonces() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - List txNonces = rawSpanBatch.spanbatchPayload().txs().getTxNonces(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setTotalBlockTxCount(totalBlockTxCount); - sbt.setTxNonces(txNonces); - - Bytes txNoncesBuffer = sbt.encodeTxNonces(); - sbt.setTxNonces(null); - sbt.decodeTxNonces(txNoncesBuffer); - - assertEquals(txNonces, sbt.getTxNonces()); + void decodeAndEncodeTxGases() throws IOException { + URL url = Resources.getResource("txgases.txt"); + String test = Resources.toString(url, Charsets.UTF_8); + + List txGases = SpanBatchTxs.decodeSpanBatchTxGases(Numeric.hexStringToByteArray(test)); + SpanBatchTxs txs = new SpanBatchTxs(); + txs.setTxGases(txGases); + var res = txs.encodeTxGases(); + assertArrayEquals(Numeric.hexStringToByteArray(test), res); } @Test - public void TestSpanBatchTxsTxGases() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - List txGases = rawSpanBatch.spanbatchPayload().txs().getTxGases(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setTotalBlockTxCount(totalBlockTxCount); - sbt.setTxGases(txGases); - Bytes txGasesBuffer = sbt.encodeTxGases(); - sbt.setTxGases(null); - sbt.decodeTxGases(txGasesBuffer); - assertEquals(txGases, sbt.getTxGases()); + void decodeAndEncodeTxTos() throws IOException { + URL url = Resources.getResource("txtos.txt"); + String test = Resources.toString(url, Charsets.UTF_8); + + List txTos = SpanBatchTxs.decodeSpanBatchTxTos(Numeric.hexStringToByteArray(test)); + SpanBatchTxs txs = new SpanBatchTxs(); + txs.setTxTos(txTos); + var res = txs.encodeTxTos(); + assertArrayEquals(Numeric.hexStringToByteArray(test), res); } - @Test - public void TestSpanBatchTxsTxTos() - throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { - Random random = new Random(); - int chainId = random.nextInt(1000); - - RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); - List txTos = rawSpanBatch.spanbatchPayload().txs().getTxTos(); - Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); - BigInteger contractCreationBits = rawSpanBatch.spanbatchPayload().txs().getContractCreationBits(); - - SpanBatchTxs sbt = new SpanBatchTxs(); - sbt.setTxTos(txTos); - sbt.setContractCreationBits(contractCreationBits); - sbt.setTotalBlockTxCount(totalBlockTxCount); - - byte[] txTosBuffer = sbt.encodeTxTos(); - assertEquals(totalBlockTxCount * 20, txTosBuffer.length); - - sbt.setTxTos(null); - - sbt.decodeTxTos(txTosBuffer); - assertEquals(txTos, sbt.getTxTos()); - } + // + // @Test + // void TestSpanBatchTxsContractCreationBits() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // BigInteger contractCreationBits = rawSpanBatch.spanbatchPayload().txs().getContractCreationBits(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setContractCreationBits(contractCreationBits); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // + // byte[] contractCreationBitsBuffer = sbt.encodeContractCreationBits(); + // + // Long contractCreationBitBufferLen = totalBlockTxCount / 8; + // if (totalBlockTxCount % 8 != 0) { + // contractCreationBitBufferLen++; + // } + // assertEquals(contractCreationBitBufferLen, contractCreationBitsBuffer.length); + // + // sbt.decodeContractCreationBits(contractCreationBitsBuffer); + // + // assertEquals(contractCreationBits, sbt.getContractCreationBits()); + // } + // + // @Test + // public void TestSpanBatchTxsContractCreationCount() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // BigInteger contractCreationBits = rawSpanBatch.spanbatchPayload().txs().getContractCreationBits(); + // Long contractCreationCount = rawSpanBatch.spanbatchPayload().txs().contractCreationCount(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setContractCreationBits(contractCreationBits); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // + // byte[] contractCreationBitsBuffer = sbt.encodeContractCreationBits(); + // sbt.setContractCreationBits(null); + // sbt.decodeContractCreationBits(contractCreationBitsBuffer); + // + // Long contractCreationCount2 = sbt.contractCreationCount(); + // assertEquals(contractCreationCount, contractCreationCount2); + // } + // + // @Test + // public void TestSpanBatchTxsYParityBits() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // BigInteger yParityBits = rawSpanBatch.spanbatchPayload().txs().getyParityBits(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setyParityBits(yParityBits); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // + // byte[] yParityBitsBuffer = sbt.encodeYParityBits(); + // Long yParityBitBufferLen = totalBlockTxCount / 8; + // if (totalBlockTxCount % 8 != 0) { + // yParityBitBufferLen++; + // } + // assertEquals(yParityBitBufferLen, yParityBitsBuffer.length); + // + // sbt.setyParityBits(null); + // sbt.decodeYParityBits(yParityBitsBuffer); + // assertEquals(yParityBits, sbt.getyParityBits()); + // } + // + // @Test + // public void TestSpanBatchTxsTxSigs() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // List txSigs = rawSpanBatch.spanbatchPayload().txs().getTxSigs(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // + // sbt.setTxSigs(txSigs); + // + // byte[] txSigsBuffer = sbt.encodeTxSigsRS(); + // + // assertEquals(totalBlockTxCount * 64, txSigsBuffer.length); + // + // sbt.setTxSigs(null); + // + // sbt.decodeTxSigsRS(txSigsBuffer); + // + // for (int i = 0; i < totalBlockTxCount; i++) { + // assertEquals(txSigs.get(i).r(), sbt.getTxSigs().get(i).r()); + // assertEquals(txSigs.get(i).s(), sbt.getTxSigs().get(i).s()); + // } + // } + // + // @Test + // public void TestSpanBatchTxsTxNonces() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // List txNonces = rawSpanBatch.spanbatchPayload().txs().getTxNonces(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // sbt.setTxNonces(txNonces); + // + // Bytes txNoncesBuffer = sbt.encodeTxNonces(); + // sbt.setTxNonces(null); + // sbt.decodeTxNonces(txNoncesBuffer); + // + // assertEquals(txNonces, sbt.getTxNonces()); + // } + // + // @Test + // public void TestSpanBatchTxsTxGases() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // List txGases = rawSpanBatch.spanbatchPayload().txs().getTxGases(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // sbt.setTxGases(txGases); + // Bytes txGasesBuffer = sbt.encodeTxGases(); + // sbt.setTxGases(null); + // sbt.decodeTxGases(txGasesBuffer); + // assertEquals(txGases, sbt.getTxGases()); + // } + // + // @Test + // public void TestSpanBatchTxsTxTos() + // throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + // Random random = new Random(); + // int chainId = random.nextInt(1000); + // + // RawSpanBatch rawSpanBatch = BatchTest.randomRawSpanBatch(chainId); + // List txTos = rawSpanBatch.spanbatchPayload().txs().getTxTos(); + // Long totalBlockTxCount = rawSpanBatch.spanbatchPayload().txs().getTotalBlockTxCount(); + // BigInteger contractCreationBits = rawSpanBatch.spanbatchPayload().txs().getContractCreationBits(); + // + // SpanBatchTxs sbt = new SpanBatchTxs(); + // sbt.setTxTos(txTos); + // sbt.setContractCreationBits(contractCreationBits); + // sbt.setTotalBlockTxCount(totalBlockTxCount); + // + // byte[] txTosBuffer = sbt.encodeTxTos(); + // assertEquals(totalBlockTxCount * 20, txTosBuffer.length); + // + // sbt.setTxTos(null); + // + // sbt.decodeTxTos(txTosBuffer); + // assertEquals(txTos, sbt.getTxTos()); + // } } diff --git a/hildr-utilities/src/test/resources/txgases.txt b/hildr-utilities/src/test/resources/txgases.txt new file mode 100644 index 00000000..b9ad28e6 --- /dev/null +++ b/hildr-utilities/src/test/resources/txgases.txt @@ -0,0 +1 @@ +0xd1996cc5b201cc954d8b8b0db38a718ce05bf5c263d7d06ac2aa4d889e5b978a6f8eb10fe29131aab243efc6679df93dbd9860bf85269cd938bfbd49d2f871c5c518b0f14ccdc459bdcb22ef832c8294788bb53cf8db43ebdd74cc8579b18d7b9bc23d87d216fee60f9ea87786f017badf2fd89d1a9da44eb497389aa368bbbd4598ca1f9afb74e5d12bb18705e78926a4b12f92b34ebff42bbe862687b827d4f74baefc1cdcac10ceea60cbce6e84f72581fd18a2ea68f2d321e5e7079ee756fcd95192d965eef72cfa8605ec9160b4943fb3be60c7960780f257b5a033c1fa06fcc606a3d768c4c1629fe861dd8c238ff56194ff1aadcc43eae70dfacf01c1c75ee7851389ed09a9ef0e819d61b3996488be30d68c0fa8aa31c5a843daf867e1c54cf6a577a6981ec99f428ded4b84c955cea716a7b778f49123fce325aebd4baaf137b1c95490b063d69839d4b303c5f84cafd93de6e407d9ab38bb8c45f7ff66a2d51890dc0de9fd28d9fc3eb3e642febf67c5a677d0f978d9f006ac861eae970ad3fc74a2960a9bbe3095d538b1fb4db2d144f5c62caeea5ac3dd31a0f85d88e15b989370cbaa03ebd077c48872b4f159f4a51afeef6aa5f86eefc229 \ No newline at end of file diff --git a/hildr-utilities/src/test/resources/txnonces.txt b/hildr-utilities/src/test/resources/txnonces.txt new file mode 100644 index 00000000..859bcfd4 --- /dev/null +++ b/hildr-utilities/src/test/resources/txnonces.txt @@ -0,0 +1 @@ +0xd0bc9d89a8c2b7bdbf01d7b097d3a9d8e4b816e199ff858e9dccb60ce9c0f3b594d09ab6b501f9ec93b2cfe284ff09bbb4c99c98b0aad466bfa7b8a092c5d9e32faccffee18680d2caf701ad85ead5d9dcfbb88501a5e29ad7b6c88f92af01b2a3909da9ebb88a24f1dcee8ce787b69650b1f6f9dffc9dfac058849da5c1c1e2f5818201dfa4b1d7bea082b9e601dee6c090cceee0dc9301f8dbc8ad84c19687fa01bf8def83a9b8c4c945c7d6cca9fb8dc8abd101a4889bd7d2cb93fdf6018adc959dd982baade1019fbe8deeabc79ffd5bd1e0fb96c781c1ef18abed99d9a6c0db94ce01b289f0a3a7f289ae2d90d8bddd93f493c37cc3a2d9a9caffa1e70fe3e7a0dec3b3a39d0aa99fbeb2fd9699f9fc01b4aa96e880c085f6e301f2fbd898e283aa8607eaeba4cbe9ddb0c37497e2dac9cdc0f9f35bb6d8d0f6e698d0a520b99ec8dc91d4a4b5fe01a1acd982d69d8ec080018bf1ae8b9295a6a69501ee839887dbfaa2e28101f0bba0bb8698dbe7ed01f98aa8b587c7bca76bddadf185ab8e9bff4b9fabbec4f68481ae9901f4b1caf192cdf39d5eb7c3b0848aa3d2b5478680e7dab5fbb3933ee9b6d4d1a0cef8eea201edd795a59de5bff1ed0190d8caeaeba28cf6bf01b2c8e7d1abc6e6b19701ea86f0cd8ac6e9d9f50185a2ab9ebd93c2b59b01b4fef485fcc5a1975da7b29fff9fa4b3d12598e6c7c284e1c1fb4795b0f9c18795a1dc8b019ee1c2b09191a18cd101f4e1b7dcfaafe185d601b889d4d1e7e780f14af6bfb3c0ccf29ddb75eb8ae9e3aaacc0c1e30195dc9cced1a494e2b20182a9b4c0cac389ddac0187a988b892ef8aab9001a6bef0efbbb9f5d404c192f298f9adb5c2d301faeb8da9b2a1afa5fc0194bfa5ddb0adc8d8eb01e788ddc5f3e992b10681fa95dab584e7bb4fddfdc5c4f083b0865586aa8caaf582ccf954b5bbf18781f3dde046febcfed0b9bf8893970188efc1c9fdbcdfc230f786c2b7c8eee7dc6decf2ceeee9d6b6972ab2efa886af9f86bd810188ec80b3a69eb0e6df01c3d6a187ddcfa8eb6bcef9a0c1b4f7a88ce301bcd5eeb0e4f3cdcc9101b791aed2d1f2a4b871adc6dae7f7c8ff90eb019af491e1aae8a9851ea6fbe8f3a0fbe79ec401b7a6fff9f3fbb1aaa6019fd8bf9ecdfae594b9019888cbf1c5eea38202f5cc94fda5dbbacbec01a1ffaae1bae7cfeb0ab5fb899aaed1e3ae30c5d285bfefe9fda3d70190fcc2ffc7dfd0998501e894f283c1a4d2863ce1efbdc8aefbbacb79bf98e2f2a2a382d462afad88d6facec5d3d001b3be8099f9d5d0c055f3b29c99ea8ea3cb29efba9ed1d0bf8d9b78a0bed4d992bcc7ad7691efa8cfa2dfd6f1a001aaa581f9c19dc4f6cd01c1cbd9bffd9bd0cde401efd085e8e5a2ffdc2089e5ec9fddb4dfb7cc01fd9b85b0f4d3a4f7d101a8eee8bef687aed06186bbe6bc93ccb7fef001d8b18e81d399afff29d9cbebe2cdf6aee6a601c7e7d4c6b8bccdc8d701bbfac3e3ffbd8aa38101deb9a9adc8aad7f90297b1d289e8f791bbd90185efccc8acb7dcffab01f4feb9a6d3ca9990bd0184bac6dbedf1fbc76cbbc2d0f897edc2bdcb0189d190c39f93b595a501cfa7a992f88d84d05a8cce99a09ecf99accc01b8eba1e3e7b48ab27ba3eceeffed968d9429e6d5b3e6acb9d0a83ab9959d899399a0bbb90193d289e3d7d591c9db01acace0f4d1d688b7b701a1aeb9bcb58aa69f07fdcef7a4c4dae7ae51d7ecbafef699c9f1a4019982cfdab4daecfe50ada68bb6b38580d328d6d3a29bb8dec5a3ab01a48d8fc0b0dadfe354fbefe28df89dadc1cb01fd96ca9f948fd0fd4be9d28dfb85ffc4d3e3019486a28d8ef6cbfee9019af9f49d9be0eab8be018488e8edc2e7e7cd8b01b897ebb283dd89add201f2e18d89c186c38501d5afa791a99ed4ed78b3eb80cebfa6ec817fdfdde9b48387bec207b2a6dd8bd4c2afd78801f29fefe8918dcf9524bab6eaeffbb3d3fc6d95b3b2bafec5d6e703a6bed0a0f0aeef9f9a019ae191f3b4f8f798e7019cd9b2fc9a8ad1dab701f4b2dcd8e5838091cd01e0c69eb9eff887cacf01bfaf87e6d0c9e4b3c001c7f0e8aff8a9e29947cacca7b7d0d0b9c2ad01e999d0ffaaf8dab98d019dd0eb92fac1cbadab01a685b7c4d9bcc08ab401cc97d4e7d1ead59202c1f1e2cdd583c69565ee9cf4f6d597a89b0ac7e1b3e3ece4d6c89501faa3cbdbd9e9d4ef8601c6e9a4a9adc6fcb946c6efbbbb80ab9a8368e1c98487f3d3c687e601ddfcc6f385f7dcdfd401ea83c387e3aae4e546eba18ed1ffc7d9d5b301f89bd6dbf08ea2e0fc01b8f6a2f9e2c08b9a0da8f6c89ba1b3a5a5e201dbf1b480ceb6f4c3ee01d5a689f4b1d3ded20fc9d1f6e0f399ff95f801b086a6b2c4b08f9201ffabf4d589a7e8ebf501aa8ac1f5f6ad9ff9e301a5fd9cfa8ed9f8c99401a08fb680d5edf6a82dd0e7cbd88ac5cfd262ae8494b0a1f78fdc5b83c5bff1d3e3f4c411ecb9c996f383b98a5ef4eff1f8da9c87caa501ada4dcd6d5f1c0f2b201ffc48dbdff91d6919101c694edabc1dce3fdbf01dde6cdf4efefa5b2c701e289a3aca4f3f1a025bfcbdf8f82f3a7ae659fc093a9d5e8defbdd01c1b3f19adcd7aabe5c8dfbe6dbbbd78bb8c701baeafa849fceacf8489bf4e9fecfc2bec7a301c8a5f1f2cf8192bc990192b2bcced2b9edf5d901e18ae5ccbfb3deb38401c88db2f5bcfe97de45d3b7a78bc598d6aef301f5e3d8deecb4c2b7f101a0acc4e9f6dda79554ae95d8c097d5e3d630b18283f78fefa0fdcc01ad83a4d48289dada75d7cfd5cb8cb982e92ff4fcfae8aeefd5e972aa8e87d698f186bf0faaaebdc5888a949048ffbcf2cfa8f68cbcb101dfb5fba8e7f7c6f0ac01aec0a3b5d9ff8fa1ce0199bb98cdf29783c010ba8aa2b8918989d146a3b4f28f99d190dd10bbc38bbfcfeffec269a6bec6f9d287c3f6be01dfbca2f2cb80ecd27ab6fdf4b0b6fbdbca7581c490dbedcee49aca018e95adb8bb8d8db85bd0e6b9ddd197c2ef32a2e8e49896c6c4d117f4dad79febe6b88481018ac2ef859daeb2ff6eb9d1b2ebc1e1f1ba9501a1e6d095a2a0a2b0f401e382e6e8ee93809404899ea5cfb08a84c611819bd3a79fd880ce2080db8fed83f3e7e95e8fd1bd9df9ee85c6e801d38cfe8fa6a1bd8cc001b9eba2dbdbb786fd35c3a1ccf8fc83dfc8b501b1e789c7eeb4e9e518ab8befe4cae283ec3dc8e9e489958bad84dd018ca8ae80c88bace3a201b59ae6f6c2d1b99ad4019acfb9e7b3a3bffcac01b9d6c88cc4e5e0e77df382bc8bf18b8ac2cc018bba8e85dafe97acf701d7fdf38b83d2e191850192b9b8dcdde7e3fc9f0187eaf8d3fff5b2f1cd01d3fb83dae4e4c4e978e2aa82fb89b699d86dffb2bdedffbcd4a97ca798f4a3ec85b5db06b892ae81af97a4cbbf0193d3a290e6d7a8f4b401ff8edcc8c7f495fa14a9a39a8da0b38af9cf01fafdf49ff9d6b3ffd00185f4ceb4fff29cf6668587af999799dddc2998f987ffc59a8fa25e8b9cd9b9f79fe6b81eecef97db81ccd7f59401d9f3f1d3f69bc09735ddd68b8afb869dd34f9cd7f9dffca1bdf1a0018af6b590e69887a5b001adbbb187f0efd28967cbc7a3f88ea5c58533f8b6cbdfd1eec8cdfa01def3eadd91a2b5e4dc0191b8afabebe5c6f029fb80ad90f9b2cefe7eb698d2e3ded8c39874a1b9fcf9c6d99a948e01b49d9684d8abc995a701bc898eece7e486e1df01cf9dd3ebdb88f6d9c1019fe2ee929192ea848001e8e4d798acfeb8bfeb01988df39bb7f5edf6a40189ca9cb6eed9bf94990180cae9cce3fdd0ef8401cdf2e1ffb38ca3eb2ef9e7d198e8d5dac129e2f5be8693c38c8c9f01bbe7fdc188a2a2fe30fbc4d3e9d7eeb7a6e10194d69ffcc3d9d3bd9c01c8abaf89f3e5cac18501d5c7aecc8cd3fe8eb201c8a099cfc9b6acc577a9b0d293fae9d8b98701b496f8e4de9789ede501fac593f3e780e68b0adc9c9984a9f1f4a141fd909ec6faf795c4d801d7a9dbd4ecadaaa83290f7ff97b4abafa629cfb1f29ab5a8b19c6d85daa0f5fdd0f1df75fdd7d5aadec8f79335de8bd5cea4d1f5dbdf01e9a1b4a0d8dec9da8501fafabb8e8fa48de315b2fcc48df6f389cab7018aa2adf58bedafe511ded3b98ddd92aec02f80a0cf96d28e81af618af1dfe4929eb8a475a9f4daebd99ad391b301d4d1d4b089f086b182019aeb86cee9de9ca89c0185c7e89bcd91aef3a401edebf2ef8ffbc1fc9b01edd7ebacb3bcf9b263adb7ecaed8c388efe401cedcf6bfc1e7f0a041b0d98dd5e39defe1a901f0889480a88cb1d32185d5efb7f49681f5d401afd5d1a68eb095ef31a1d7b3a8bb9ffbbb0bc699c189b1b3f8839e01c6f0ea839094ca8af001cdd9f9c3eee592a5c001e8f2e6e7e2e0ffbe2dccd8f6d985aeaac1ad019df2a4deb0f8febe48fda3acc492c3f19c6ac9d497f1cbf1f7d1d501e2e7e69cff8187a0ca01f6c9efe4da85acac9e01f1e9b7a8b4d6fee47ff9cec0f4c6e38898e001ecdcb4cbd7ebe0d7c501cff187dba19a859b850185ce86e6c3a9c7d6aa01c9cfe4f18afed0b14feb9daeb2c8b284be7fc0c6fb86d3cbb5c4fd01ecf68c9ec1f0eaacc201c2b497df8cc3818a52c184f88386b19b947296ecb6d7a0dffac3b101da898ece9c86d2b9c701fcba9bbfeaf0dc88fa01ca9b8d9fc5b3f5ced601a09994d69491b1dbfc01e89d83f5c087abb2e601ddfea29ed1b7b8e6d001d29a8599b3a2a69573bcb4b4fee9d4fe8536b3b0e1bab4818ffc8f01d4888be7b3cfd8932ebfb7d3c1f4d4f4844de4f68bf1de87c4dad101c3aba2e4e4daf3eba4019bfef4b1b2c2ed8e43a0a4dda28ea8859358a2bcdbd8c68c9bae5beae7d9e7d8f8e3dc29d19e98e8b2f4a6c928e698bda9dea483cf03e880b493c193bec598019ee3a99ce4b58db2fe018edbc7c6eeb989885aaaee87dfaacec8ba65bdc2d9df90ebbfe5fe01a5bdbbabceb39cd9dc01ddf0bceec2bef7bd4790cc9feae8b0aabb9d01ffbb90eac4b8caa46dce9499a6d49796e4a501ffa0cdedad85e2bacb01ddfefea3d593ab859601c8b5c2b5a0f089da2fe5ab92e6c28db6a3e101c8d1e3d984b8ada39501e18087ffe5f9bfd77d8382c2e1eb8ccc8e8501f5a1d7be8f85d1cf19e589d298d2bfd2f0840199c3d69a8ab88d99a20199b8dd95b7acb0ecde01e9acf6edeaecb9a4da01e2b2eec0b3d685bae20186e9c5d3f488f69334c1fff9ebb3f2c29fad0193b3b1888eb8bcd387019290a4d7c6decfd566a09f8ee9a4a8eea66a9ac090d48fb9f1bb27a4b2f1bae8efcd8a7d88bcaf8cc2a3b39ebc01a993f5cf8ab3a1b9ba019ab8b5d698cf88a71cf7ffd9cdd099b7ff149b98e78781e0afa6d5019fd287c3c2e9e2de63ef8486b7c9bacaa611abc2d1e4d7e4a793b701a8f6b187afc1ca9b920189c3addda083a48009a0b7c1f5c180acadc001d59eaceaa68fb1e50483c898dcb0cba18a8f01d790f58daca8bcf746c982a6d4a5fcdbf2a6019adfada7d9fcf188c401bdc191d2ca91d6b0e101d7d5f7cdddf3f7b01bd4d7e4d6e0c484f0f901fca9e1e1f6a5deb54390add6b2bc8f83db8a01e096eb9fccad8cf779a5e6928ec5e7d9a531e7edb8fca4ebc192bb01ef81a0bbb2b9ca80a3018fd3b295b3efb8978f01fef7e0ca93f4df95fb01e8d5a4e78cd2f08e3492bce8b599fb8d8732b8aaa8eaf99dcca1cd01fedea1d0a9b2a2efb801f49e9fa5aafddc9609cebaee989fecd7bdc801d99390a599f29fa111e1f3998f93d3cac2cc01dcc8d0e8fc93b59210fc8ae193aba4cbc78001d887bcb1aff7f3f145f0c58fa8cb87ece9ba018ed2acc9e48dabad45dcf6e6c9e683c2e99901809c82a9a1b8b789b801e9abd49190c1fdf19a01d6f7aae39baafbe5e00190c5aaf6bebfe6f8ee01ac8eeed5e1dfedd2a801c387f5c7dcbe8aea64e7cea2e2abd2efdda30195cddae4eea5d1f83c9d9088f6c3fd95b3c001a58d84f888e9cfde16a1ccef809bcf8ef03a9ff9b7d3facbc6c7a001908589ac8fa7bab37bb8fdbfd08ff7ff898e01b0f7d9b48afaae9008cdd080d38c9b86861ee9f985f9fdcbde81f801c5c6c0e4c499e9e79601c19f8cc88edba4899901fae2e1d6c0da87e8e101958cfee6868ba6edd801afdbf6d9f9dceacafc0193df90e5f0c88183bc019fffccc0bae2fbcf018487a5e0c3b1edbd02d0cc88edd7809fa4d10191cde3d3abe9d4a432e3ecab95be8ec8fdc501a3edf5d2c3a59cb05ad9e7dbdba0ba9dc7c201ebe4a8f2bc9baeedad01f0ccfcebb49b8cc8e901cbf7f6bdd6feb5d41bc8f6a0d2f8cd8e9e4df7f8ddf4e8cdf281268c82b1dcc3f188a7da01aebdb786fab6edc1e4018fc08dbdad90cbc9cd018be09fb98c9282a111a3b2edafd0ccf6d7ae01ffe4e9a3f3b6f2b64ceaa7e383e3a1cbf7ac0198ba8adcaadfb7f213e89be6edd4a3a39fdb01f798b1dc81e3e7fd8101cebcc7a0839eb982ec01fdf387ce948be8d8eb01bbfef88afe9c86caea01fdbface1dbd896beb801c1e9b4f3d3b994b0e601ee9b94c699e5b48fa701f2aad6a5c3c99c90bf01e989c88adaadc7a10985c2a9ece4dce99847db80b5dbb8aadadaba019398b5cef994b8fc8801b8eec8a3d6f2b1cac3019dbda9d3d39aa0cf3bd9a6f2fef1f29882e5019af6be85def5a5dc4688d1dbe7c9f6d5e9a001fc9ec2c0ad88afc62bc1ddfbb2d4a9b2d201e5c285e5d2a1dcbb57acfedbf4d3dfafce6ee7afbfa7eaad93a01ce5b9c4d7e59682e9fc01a49e8cafaec4bdc51fedb9b4ddffcaa7b50890f6c1add998a6e98301b99defc7d0ce9e9792019686abeb9d9bb29cd101d7f3a3c2bdc188d8d30181ebf19080b7f5cdb801d681a7acc8e497a80a979493cb82b6fff822f8b18ac3ede1e4a0890187edee95bbbdb986ee01a0aab9e4c3afb5a9ff0199a5fbc294b6e3b445be80bff1eee5c2ab8201cc949998e2a8ff85c301ecd4e2eff6a2ddbfd501db8f83fccad0fffaea01a4ddffdbebe4b5b330f1b790839dc896fa46e8d9a490ff93938928edf4f6faa0de8cd562aaa9c1a4b198c1815f8ec0a59be8d49bdcbd01af83c4ac91dae9d3eb01dca1b0818cc2cdb0be01abed98f2a5a1ccb9cd01e68ce7fa88b2deebce01cbe7cdfbf3f681995da2ea88a6a3f2dae8e501f288abeabecdc2e26aa0c6f0d988c6a3afc701ff83e98499e79bbd4bf5f3f78fb1acb886a701b380d7f79bd5a2acc0019df2a2c98583aeaaa201d49baad7e9b8a3d418d2e9c0addaf3e5bed20181e793c1b3edcfd173a7efba889cd3c7be9d01f6fba4cd8cc78e9fec01b596d0f7fcd2e8ceca01efa29dedabffa3c39e01ebc78e84f9d8a2829a01a1eef381c9f0f383738c97b09897d1e8acef019dff85dfbcaa82a3ab01fe85fff1e197bb89c0019be1b7fa89c8b2bdfb01ddd993cdf9a7cb8d309bedb59cb7fcf98548e8bd88a288eac1f9f40185e4f0f08df69fddc601e4b590c78ed59792f201c4daaacdffc4ecfe950192bfbed9bb9bbdccf501f0cae1becf8de5ce06c5a094dcd3fb96f83aa0e8f5bf889bb190bd01fef2d9cffdc0cfe51cd1e3a9c3d0c0acc1cf01bbd7bbd1e9f486ae61ff9daaf2cff0a8c2199681c8f58c8e87a00d8ec0bbe2f381cbdd1b8de0e0ddf89ea9f7ea01e6d6b2afb1979cbfb7018ea3b1eaede0f09d1b9bbce6f789f2f6cbef0192f4c0f1c69fb0f14cee9d9c8d9fdbb2d21c85aa98d484b5edbcec01eda1868cb9b386f34a80c2cbf9c98ab3ccfa0181b3d0cfa9b1d1dc0cc6a7c7ee93e5ecfc52acdddac6ff9cc6aab4018cda8991bb8efda4eb01f5f095afa8d3bcd7fc0192ebd8e6bfcff098970195b9c1e5f28ab49cde01a2e4b383b9ced68df501c7cfc181f5b2e2913bc7eff7edcc99a1cbf801ee84bcf1fae0e9a751ced0bdc4a295a4d4f101c3c3e0f0b9e8f5b958988ae0fad3fb92ecf401a1dbc4ca87c380a1fe018bbdbec6b8d68a902d97f3e3aaabaaecd38201a3e5fcd7dbf8f0c3fa01e4abfb84db9bbcd55aa7c89784c4aec3c9179987d88780e1c3c578e0b1dfc1a7f1e8dd0cd3b7c2bffe8adcaff501b6ccffa0c2c08496bb01edf0bdbff0d4fa830ee98bfb8fc5b698f513ab8f8b9efabaafcec301b5a9a3c698e7fddae70199ddec97cd9add8f67b9b6f3859ad8aac238d2d388e8d6c5cc9ac001c1c9d8f0b0bea6af26c3969280dcf0f0c88301ebcdeb98c2c0a8ff9001c98495d398e8f2d2cf01afc0e0d686cf848836e5ea8dbe8ec1bbd58c01e69a94a496eebac653d6fcb391a4f8bdac51db8dc3beccfd8eb30498e9a086fcd5c4982ea6b194e0ddea8d94b9019fc8e0a4eabea7c2b4018ebecd8bbdb2daead201f2cf9cc9d5a3b0f310fae2c1c288f4ccf611c0a7d6f5c1e3f99426ebf0fdb38d9f8ec37e84a5f8edc8e491af900193fccbcc98f4c7c5d601dceaf59de7c9b0fd2bde8ed693fba681a3e4018bf1afd0e9e391842ba5caa7929597c99edf01eff1d2eabcfdaba7db01fed5e8c49d9eafafca01fa9bca96dbaaf5d023f9b2ccdcde9c91b4c301add9e3abb0809cd9a301b7d084d0c8d5c4ee1d96e582c4f8c5f4afa901b5caca9c90a786de77c1a0f884c888dfcb3be9d4c3d49c8bcbaeb30199e2a8eae988f0c79a01cbcad5d0a6d1daf9d701ebe8d1b3b89cd9a58201f08aa0b9bf9fbd8c3cb282ae8bb2b0c0a565ec89cdfca0fbea9b0b9cc48cd5f4f59d9bb301e08da89c90dce384af01bfe79bb0f289abc74ee6d0e782dcaca7d117e499f586b0a892d7c90193e4fffaacc0beb303deb9b5d1a1a9a4c324998ddbcf8fb0f9e561b0cbe5e4f491aaadf601a0b9aefa96dbf0c2eb0193bfbba1e5f3caa9f901b2f9829ceedb9cf139faa2aff3b0efcde88901cae79ca3a8d88aead201dee6ccfbb281bdda24fed2d2a5e6a5d0d3f101c5b5a0dcdbcdf4e2b201b1abc7bdce9086b6588bd6a6acbee0ed906bd7fec0bead8fb4b236949d95b1b7dd8f9543b0f08db48ce8f0b2c701e2c6d4ecd6a084f38f01c086bcfece8a82871afbeac799d5a1efc68d01ccffc4dbd0b7ed9e428394c9ede28ed4cf9e01c3c8aefec1e8a9a3708cf0d2c5cbdcdfc4329ff9939edce7d49ba401bd96c6dc98f2f0e0028189c0dcc6a89681e201beb0a7b28a80e2ba9901cd82e4cab8eac0a44e9197a1808e89c2d6a301f8a7e7b4ba90b1ea66b9a492d2f482e0930587a4b5f8a99abdba2dceeaacb6eca38dbb31b4acf9baf6c8da813d9ff9c68a8da8b19e6bce99a8dfaebfdfa2fb0195b8bf83b2d5ab954babebdea3c78aa08e7289d4d385ebd4e9af11e6f2e9b7a0dbe1c3ee01f8edb0bb988e92a0e201dc9aabc6c0d8e6d523e2899dc8dcfd829c178b85bdf2b8a6c1cb7292c39bd68ed596c97cc0a895f5ecdd87f9d40193cf8eebddeee5a3c601a2dfa9d0e2e08eabfe01b8d7ead7b8fa8feb8b018fee939997c995a51fb7b8bbbbb8dba1ed428af2b080a8faadc06db1a7fed8e3a48b9504fbcaccd3ac9da59199018cedc6958db39cfea901dae99dc8dcfcfdf90cb7edcd9dbef7a39b0cfb89abcfebcee5b94aef8fa299e2aaf483bc019bdbe4f5a294cdffd801b9b3c0b789ecb4ae5aab8080adb1ebe9e10af5b4afc8cfb1c9e07dcba290fcacc28fbc2df4d283cce5edb19a6dc18a9b8f93b5a2b251aa81fbed97f6adcf9e01ee95c3a1a9baa8df60e3a4cd81889cb0f65cdee7e4f8cbabacf7e501d2eed7fee8de94b3d801dfeab4d0b89799d4be01fbdbb384ad97cef7db01ecc8cfae88c390b360c28cc48ac6afb3fbdf0181f089d4b884bee7bd01988eddc6b1ca9ad42ab1948bf4c0cfa3a6d1018991a4ccc6fedeb162ffefdc93a1e686ae159af4ed9e94a8bbf7a001a7e18fc7b1a39e94dc01fadae099c5ecb8f03ea7ffb3b8e5c3d2aefc01b9f0b4d8acdde9f32ecdeeb7b9f7d789dc7ef0dea494d1b3ccbd1dcdc3e388cf9dccae04a5b8d7e6bd97a78822d599eeeed4aecf89ca0180adc4a9a480d6f9f5019dc9d9d2c2d38f815990f9e1808d9584d1b8019ee1e790f3c4bc98d301b2c9e3b0f7afc2eb70ff8cfbded2e49fd99701caa6eff79390e8b176fe84b1d8b5fcd7c2c501d498edf2dc97baca9801f5bbee86e48fdcaa538be187cb9981d3c440cdedf5b0a5a3e6c151a4a2b5faa7dac5c6a8019a90a3c39af4f5aa8801b087bea7b4b081bf6b8ebeb1d0b4bfb58725d6fa98f1c2a4c498b901fdb9b68bfcf9ab960facf7aa86b1d494a89e01d29399fec4cccedee901c8b8bfa5a7dcb98b7a96d7db9fe1f3bfbc68d398b8958ad4baf92dc39ec1f3b1acc3a0fe01b0ecdbcd878487ed8f01acda8acdd4ebe5b3d301eb9de8c78b87f2de9401a184fbf0b399c0b310cecea7b39aa8c3bfe301ffde8db5f3dcd10fc2a1e7babbf0ffec49cacde9edf6d5e685970184d5dbb4ab8791f6c101efa1e29ebc98c0d5da018495aae9f7f4a5d012bf99e796ea97cdb1c901f0c7848fbac2fd849901b3cdf7a0aaddf8c734b0c8bae7c981e7e0bd01c8baa6a1b2dd8291ee0197cf95acb3cfb8b5c201d085faddcdafcaf61c9fc8b097eeb0bcf3fd01a986b4a7caa8df90fd0196c6fb8dc79d9fcf65ca85fa93c1fecddb4afcf6d1e5c597bba672b3d5d7fbee91d3d6d401bfcc9bffae8c97bc1fc8cca4dfebf6fd9a2dbafee48aacfbafed37ddfca7c388b2d6cafb01e0a0d1968ddcb1a29a01da8bf0a694dbaea765f1a5e5939fd598fb2dc1c7e8ab94fdc0f7ec01bbe7cf8bc5ff9097fa01f993dada9c86c48dc601eff6e1a9bbcdd4d3cc01dfae96a7a595e3ef9501f4b78980bc80e5a15fd2f8deebf38ba6fe03c398a4c6b6e89bc3358ef0e0e0fff9f4c04cb983c8cb9185a5a5ef01db8ca4aaf3f7b5e6b601f5a7c7f7f8e0e1e40a85d693b5dec3cebef20197b2d8ffa09dddb4d20180cba0d08c80a3d1fe01a7c19880a5b7fe9c7ce7aca0e6e39f8797ce01f99eda97a0d6f4801cc792dbe3e9e0cdd7fe01dc99cdf8dca7adee3af4cc928dc1c4b8b227a8cc8197fed0a2888401d1a2b689b3f384883dfeebe4b2c0aabcb410ab9dc5e1b2c0bf9efa01cad1a9f5dbf7f1f7840198f5f7aef5dcfc862d8fd4f8b4c0a2a0a83093c5c3d4d58bebc0b801ec9dfebdb9ac84b6cb01e8c5b4daa0858de95bfee492c1b4df97cf2fa6cdbfaa80edb0ec0690809fe6d1c096fbe40189f99dc08bbfd18e64ead7b2f6f5d6f283eb01a39afbfccdbe8790e301dcf5c59493ddb0f7900184959e98a0fdf1dfd4018e86d0dde6c985f28b01b0daf484c4bde6e7b60197ece7e2f0eebbac4acdbfd48cf1c1bbd57ec4f08b9a9bedceced601f79b9d98b093a2c92befd9f7b099f088c3d10194a9aff59bdbf48c39ebe0b0c3d2fb95b99801e6d098d4c3f0abd343a3c9a381fde9c1ea05c6dc8c8ed5dde0f49901b4eead80a0b798a06991ccdad496eabd8175c7e5a2a1c4bab0fce401baa0cdbfc1c2e0b4c101b7cccfd5ebe8f3ea508ae7e3c2b0e5b5c926b3faee8794eb90f878cbb4deb0d9a6fddeca01f0e584eea6edd4bef90191b6a780bc83c996ed0191d4b4a1a0fcd396d501f4ab9bf6d788fdacb501eca5e8ec89bbcac753fcfedbda91d785a4ea01d48ac1c5f6d38695b10188b88cfceafff4e452ad8ecde68c92e4f62498aac093a4f3eff9aa0197b6adc1ec84ca983a9381d2dbe4a3d8b8b7019bb1d79bea9abf94ef01cb95cf89899ac5963da895aeb4dbcef28ce001ffd7c7bc95b098ebcc0192e6ead29ca5b2faf301e59fefa9e88086f0ab01fda4ab9ed1cab4d20994edf3f1ddcaf4e14bb1f5c785e9c2a6ec038cdc88cfdfaafc919a01e4bda4bedfb7eeedd001c1ee8ee0ccf1c4a349d8e4888eb2b8ac9ced01c6b8f1e095d4eed1bd01f8a5beaaa1bbfec2db01a8f492f2a0acf8ec4185df93e6bad5f6bea301cea8f1c8a0e4d4eb9501d882eee8a0c7c7ee2ab597fddba7f68f95429fb4e3fa9bbae8f4aa0188caa7dfed9cf3a9ec018ebdb8d5c4f5c3d4cf01c08ae9babfbda5f98401f6aabe9984b19df3b701d2e2ab84a4f1d38805b49e94ccc2b4e19f7f98adb2b2b3b0b3d340dc8ec8bba3f08f9b65c19da981a3ebf89f42bab8acfdb4d5b4bfe301c0c7ce9aa7f19ab3da01f8f4cd85d5cbf98f78a1d7f3a499e3d2e9b501f3fab6d5e6deedd8cd01f1d1f1eda4ed8c918001fadbb0e8bcc6d9d809cbbbeae8f5ce8da5c301e28ed9dab7eeeb887ccc81c7e5d69d8bdb4694d3c0d7b5a484b80fe799e69bbfdf87efc201f6958690c8d9ff8703dda4a7c6c49cfadf6ee6a1c4bdc38a99fdfe01e087e0a8a4e1c2db9801deabb98bb0d6e8a6c701e4b99ecbd1b1b4ced8018ad293b2cdda83a05183aae7f9fbb88582639bdbefc99ee39da8bf01ecb6aab385f9e9e174a8d89f89adabddf0fa01e4dea5f5cfa7b3a0f201a19fec8aab93e0bf7bd9e884f3c4d0af90b601b7a5b3e3ffb2aec73596f2ef988ee09bcc29ad90d7dd8dbfbcacd301de86b0fe989debe8db01e1e8b28fbfe6dbf7c40193abd585a9cdc5ac55bdd2a8dcb883fef6a501a4b5eae9ffc999e314edbe9db1f9c6e9fa0498c981acc6d9e8906a879aa0defef4bc8af501cef9bfddccc395c4d1018dfe9296e6a8fdc1b00187f1b5ea9b9aa9ffb70186ddf8d9a19ce6fc2dbcbbdec3b9fdc5f72ee2aed6a5cae8fac212dcab8cd2d8fd89fa7ce6ddc58585cad3fdd001f9d59adcbae0b8c8dd01b1d798eddcadb8bcfe01d1a9c58bf290a9eca701d3f58bbdacfaa39473c4d3d0f282e392f9ee01a8c1bd85a39b918447ac85d9fbe99ce0c5e501f58fd38cd3efa5f8269981b1c097caf6ff6ebca29492e4ea96aae301b3d7deb7b3a581a69c01d68ccc8bc98ab3a5e901ca8f8cc1d0e2ccacd801b394a8c2f7b69e88e601cac2cf9ff9eddfed69f3f392fb97beab94e70188fe9db0b096c8c2d6018ae0c088a8cde6da6be4a8a78fe2a3bcbeaa019dddaadde1a591ad53ecd3bb8b9595b48ac90186faaea2fc8788bc33dca49bdd968ad68c8d01caa7e7e1a7d0e8e05ea0c793cfc98692c848b081d698d9de9dfe4ec89f82dce1d6b1f3e101e7aaaeb892f6e0dd54d4f6dfd58b84a992dc0182b6a682c0bfb6ca8c01afe2e49a94b2e1e66b989dfdb297f7fea957fbdc8287a7d3bdfbf501aed3bfcbb88fa781a001f8f8a2fca6aad2bea401e5ba8cafcb989bd1a101a0be93f8c1dfbb826ef4a4b09e96dda8d33586a8d4ac94ef818d2da086b6f9989efaaf718ce2cafc88b99ac24de5cbd4f6f2a3a4f1ad01d6e98bfe9783f8918a01cdebddf8aafc84b649e8b7bfeafae4b3e72798b2e59d86f4f7b3e701a9b3cb94f68f97cea001f882dfa0ccc58c90a401d3d8edc2c8d4f8d3c001ba9eaca8c6a3e2a769e5a2a1c6c0f0bf9d2ffacb8e99e692b0e548b6f4ffa4eedbccfb39dc8dc0b4febcc2a9f701c3a0a596c7d3f093df01d5e4d58fae8ba09ae401d58996ade49081d0a701b1a186c5e8e5a7eaa40186fdb8f2fdcaf0d139f9dde1a4b7d58d902e9faefc98f6f9d0f390019c97d681fd84b4d87febc0cef2eac3c2e96ef9a5a2c9bab4efd575cedfa9e282dc94dc5dd9d0a5cda49bea9601d9adafb0add7afdbd401a3dcfef1b7f38afd73bb9594b18c9b82b89f01a6a9b8b4bfb5fbc158b5ef979db5dc83eaf30196d6d389eaf5eeb58301a6b6ada2d6abccc8cc0194d5f59090acf1b13caeb8d8c4cff0c0e177b7d1d0d98483e6d5be018edaf7bcf697fbfcf901c78bd7f4d6d7dab2c701f9b9bc84fa97e084ee0196d7bf889daca0d728b3fbead6abdb86efe30183ceaff5e1c9ebda5e8ae89df4c5c3e8a963a8ae93b3a69bd79322ebc0e2a4bdcea8e58e01e2e4b0d990f1b4cb3bd298dac9bef5c6a81d9ce9f2ec8ee2b3877bad95ebefd797aeb7de0190e3bae3d0c797b669f9dfd7fbdc9480f2e001e39482feb4cd96ca0beedadfd392e599fdb001d4d9b98b9df88699058fe8f78fcabadecee201b38bdb83e4d9a7e635aea5dcdab890889d9601d2adb89eaefd9ec6e00180aad0baf7f0efd87791a5e2a7a6b2eeaa9501cba18ddfbce4d9f0e40192b0c4e5b7a68e909301f6dfc29a96ebcde1d301f68ef3ff8cedf4dccb018d91a3d0ebe5c0982fc8b2ece0d9cbe9ad7d99dd96e683a09fe5db01dfa6c5d6f1a1ce845ed5ec958fc7f1c9ace301979bf084ecd8d4a74ccc80c8fbf199bcd7cd0182e9a6fe819c9c9040eb8cabc0b491b2b770ffeae2a6e9b087830ca589a4d0b2b8dec167c2bcedd997b9ecf4a00189cac095a3f7dcdc6b97a3e7bdb891f7a38201b4ce8cf6c9cbdf999201b08ae19aa0a7dacaaf0180e3d2a0be839a87ba01bdfec79090fbb8c21dfee083cfefc3e2dbe101c0e3c2c4f2cea0b6c301fdb5bcdba6a0c58f9e0184bde487e8f3a5838c01f3faff9bbabf8e8984019efe8ce781e0decd14baccae8ca9dda7e151f9a0f381aed1eaa5f801b1eec296dec892c426f2dda9defc92b1e1d001ca80cc8e85f79faae501bdd4ced1ec89fbd2b701d6f0d587d69694aefa01878ceea6aefdf3b40bd59ba280e0c6a2bff201fd8bcb99b890ffcffb01fd90e2e691d7f3f137e4b3d684b096d8dfac019cd08ed9edfcf2d7588be4859be398ffd8d501e4dcf1f898b8b9cf2d9bc497898e87cd8dbb01e0b89aeffed1e8efa601eba1b6aa9edea4908a019fe6bb938cadf8f2fa01b0ad9898f9bf94e28501e6efd8f6ffb1a8fa0bba909398ea8bf2d52babc7c2abfb9fbbb51f93a7ccd3cbaad5f99f01eed4c9cef5d6e3dc33b0b2a6d5cfa7adf4ec01d8a8ffaaa091e99fb801a4de90beb6b4c89015a7d8b3a4bf81c1a49c01bdbda192b2a7bfe0e6018de9bab09ddbd8ed7dafc181e0ed8fcc8d9a01f7af82d7ecf3c9d361c7b384d59f879cad33cd8ea284cec8b2ce4d9abb87d0f188f08acc01dfc091abe3d1bab8f601cfccdcf5fbe4d381f301acc28dc9edfaf4d646d9c1e5ffc99a9fc1b101ac949affcce19086f6018ef5ba99f8bab2a49501888ae2c2c4bcb68559fbab96a7f3ebc0a88701d2a9a0cbc2e1d4d77eafa7a681a6a7e297f501e6f281f1d79bb19ae601becd9af7d3fed99562b8ce88d7deb194bb5cb8f1d298bfabbfb41df8c9c2a28df2f8933090f399f49adaa8ef39f8aae6aa9debea85e701f1ebbde9899ae0d921d9e3be82a0e0bcea12dc89a3889a89fdb652edb6a8bed7c4d4fd9b01aa83a09395c2c9f6aa01b09cb1bebbcec2ef32e6ceafd6ab98efc90ae590acf78792a79777efc18cbebeb6d5c51bce81fc9e85c2abf16f8395ddaab7d3a6cd348ab8b8f88baaa6b2bc01e7accde78be5c68cdc01e5a9e5faf3fdc7dff401bda096b0a685d6b3f60187a9adfe85858b9e66c5cd9b8aedf4cbbd5cc8ea88aefbbeeef178ddbe8085d7b5d3fb0dc3d1999bbcd493dba401f4f5c682b3f2dabf5086f6f7c8c9c0b0ff7bf2a7aec0cfde8e90a201f8bcb1b982f8ab9e8501ff95b0e6ebdc9ba7b601ceef81d481b8dfb830ccf4e4afebdae5fcbf01f1b583a6e9dcd3cd45affad5e9a8faa4e72997d9a281c8e6b8e63aa7a0e7f2dcfe8e9c5aa489f4eb99d7abe2ba019bb2ccf5b6e4f5e1c701f39ea1d6d6dbf0d2668e8ab8e988a596c5d90197f09b8af59ce0a28401f5abb9daf7ef97c72b81b5d3c8d3d8d7840ce7fd8ca1dbb3bba71a8af886a499b9af92178182e8f9bacffe981edd81ff8ba9cda88611e389b78ccba3c9b5208ea192ae80bafe8ef801979cc78dd987d5e0268ea0d082d2a5d88f9401e4fd8f95ad8fbd90ff01b0c3c8fd94faeec602a7f99df3d287c2ad628ce6ded1ce80a9819301f0f9c7ababe6a5e8b801c6d9b3dda19ea8a3f001ecc5f09dd4d3eedabc019dfd8deca3a8f288da0184e7ecd5c6e49cbc8401a9ebb68299a4f49f18d981f6d2c9d5f18c1e8cc7a58d808fcdcc689b8f868a8da79df7068b93e38f9e9efb85df0194a893ecbdf3a4c2fa01d0cbf9ccafc2c4d4900187beaae7e7939aa6f601ceaeaab8e2aabdaa53f2da96f1f1f8f5818e01d28cfcb89dead0b9e501978da9b2c2d4e7faa601e4e5df89f3a4efcb768dddbbc2caced8cdfc0196a9d3e68aeeaabb5ed6c6d3dc8ce2c6e7d30186ce9dd9e386e7aec501fb9ebfebb6fccebfb001b8a5cacfe1f39ce4a50194e5869591c9b981119ba6e2c6d2fe86cf6efb8393b9bd8ca8882c81fefbb39b949ceec801c5f2c891f1a9ffc41dab93ca98b9aea6aefc01f3aecec989def1d90b928c82a084f9e7e2b90196e48c96eab6e5a852bea7e9cf86c3cf908b018db499c0c28bb6e94485e683a4c081e19ae201bea7a291f3f6f5ffad01a695c3e6d0d1a6a0f201d1a8dd84b5ccd48b16a0dc8c87fea8b1f7b101c6e69db896a2c68bbd01a9c4b3c8cdc6a6a944ecc894f0e596c7f75ae1a3f3d7dbaa93c99601a987959fb6ebc7b1a101acfda7aa9eeeb3be9b01dbb2f6c984abffb01090eab096d695ddbe9f01f6f2e5a0de99b3beeb018593fdd6a78efad2f101c0d5a58c86c0d6f001dfd9e3ea88f28e8208a299b883e4d9d9b37e9cc5e2a9fe8a8f9f8801b0c4a1a5e59582cd4cb0e6b7b193bfe3e58001e898b2cd889399cced01dc98ddaf90d4a59ff601cbe2d1bd8cc7aac1d601d7bd97d28cdbb2a58801d1b8c2d59bbba3bc03a9a8aed0aab598c828d7bd92d6f1efed8d26f9aae9cbe4c8f3af16b5ab9feed890c4a166ec9eeaabe8dacdc97bb0fc9a90cae9dbdd59a184c0e0c9e9cfb9b701e8fae7d9d6e9d4b91d8aa2c7c69084bda6c601e483d0a59492acf95af4b0d3a9c2a1eea201cea7f08d93d1ca82b301dbe3a2cca9beda9bf601bde18fbbcfcbf1ff6aeee6bdc5f9918ce04f99e1eeb2e583b78d5da0dbafdaae9dc9fbda01a5949dcd98fd9eb8a70194d0ef88ada4e3b63597f2cc90b2bdc8fd8301d7969bfacfdec8e3e801bd9591b18b93fd9a76dc87f4abb2e2d19bcc0187e9fbb6c1a7d18f0ed0f3b2a1ced78e9ff901eeadc4a79ca9d6b972dff3ae80a99fdba97bd8aea9acda92f28ce201d4a993888eb6a29180019dfba886ac91b3a69401b0a991ffcbaaa6f5c60193a6b4cadcdce0e454a9a1c984c293c0b412e296ca90aed9a5d313b7808be7e9cfa2c9c601e9f8a2c1e7c7e7a7d601da9de1b4a4bae8eb46d7dcfbf5c7e19dbd8701a1e6c0c3c0fe9bdde201fbf9f6e1bb86ebe36481b4d5e6f4ea9b9307cfc98af0dfcc94953d94818ec7c6c5b7a114e1d9dfcfbf8093f1ec01c6a0d69da5bda7a31c8a8fe7f881e5d7eda201a8f89dd7ba99ad9f5acdd6a1b0fccbd9e11594bec0d58994cd829d0183c1f2a1ddc9f1ac3895ad9bd68b94dca570b08dfaeeadb58c93a901e2e1c58eb4f5c8b80bfaef83abeef19ae316a0e9a7f2969af6ffed01a0d4f4e8d4d2d88e4680c98cbdb5eff7fddc01cf97b2fc93e3c3b0fa01a6c7cae49290cac31deee48da0eadfaf8f8a01aff1e0d9cbf0b9d2db018afde3ccaec2d5df23a8b5f6e2f190b19bca01b5a391a592b6dbb9b401e287e5df828ddef9b701e5b7cabfce92f4b213fbeca9b9db889bf5049cadbcee9fff89dfe301ffdbc6a1fba681857f98b3cff8f4c8dd923aa7ca98b19ffae7a85d96e5fdafdbbbea8974dbcc8abdd7ff85e87dbaa982e9a9a2c7aa8c01edd3aaa0f1f59d870e99f2809cfac9f7ac21f5b3a9e2bdb9de9479a3ada5e0fdbec3edea01d0afa796d2d983d6cc01cd83b2f6f3e78cf40b81a2dce5e48ebfb870e6b08abcc698f0f1cd01aba9aaf1f38cdac7df01f4f4df90e6f5c0b70cbda695d889a597b963e3b5fda3b7dd81e23dd0b6f588e3b5a8f7ae01a3ee9cd2ccb0d8a22bc6ef989cb1dadae4e001b38ac7ee87efeef83db8b2b1b7f7fabeecfe01cce4be93b1bfdeea5599dcef868999a4fedb019bcea7f5ebb1abca25dca6f9c8a9c7b9ffef01bcabfe8f9cc682e3e601cbcd97aeb690f3a120f6aee887eda8b2ed2e81d191e79b849de3a501c2f4b1e6c6c199a4ec0181d5dfcac7fdd6b6c1018dac9acb81a6bab94aa4ebd9c1baac97afab01ebaddaeab5dfc0d071d8f2dad192dfefc0b501dd8e9b8ae0f8c2fbc301e2bfdcf8e68dc5828001b7ff95a4d2fad2e9d201ebfee787bfed87d58a018c95cdeea9eec1f2b701eed7c6f68abfe8fa7ec0eacad19e84a9d094019494fff7fbbe91c5e4018fb3fde5dca7cfc5a401d48dc1a3c0a883d444a6f09acdbbb1a8c18901c0fac9a3aea8a3949a01cbdad3c7e6e5fc9d0afaeea2f5c9af94a2f301d7a0e3829a9caecc3cb1bab78fe2dbf1f2c801e1d798d5e89acba2d801a59ac7849cf687d28d01c5e9ed9da592868a8a01c2edaaedfee2fff71f8dceffbedd9eb98346c9bed3caf998f89857bbe18afe8da5a6fe9c01d2a4ce8e8089f8b32389bda0d5f1cbfcf6d301d4b1e8b8dec9c9edb601df86b196b89c94f223b9f6b1e1c9e7fdc109bab9d38ce886fab12ccd87c4cfa489ad8be901fb92ae84f6a683898101e4efdbdcfbeafba71dbaf6a5a3b1ebd2e938ec829dffed99e4f661d2a3b096c8d09dafa201b2c492a294dfa3d58a0189beaeb9c8dee8e5b501ee86cfc3b1e79d9775cbd5dec6f4f1a5e6970194d8e8d3ff999df55dc599f492d4fa9e94f70197a0e58fefbb8bf0bd01bdebe2988586fff60bf89b98a7ebcd8ddf518892b890f4afc4d7eb018ddeebe7baa6e2a939e5fd9bf3b4b392e5820186aadb8a998898909f01ac84dad9c4b1c6c64380bbc0adb6d7e4f717c3a2afcdeb8eed841ad6cbf3addcbde29ecf0181e8cef1a4e89cffe6018dc999cecde5ae9e14928a8894cd8387dbdf01a9dbf58fcff6c98c9f01e8a2d6a8bab289c0850197adfea7c289b5b4db01c5aefe9ef0eaccbfa001d4aeacd9a68c93c522b08dc6a6e3a29cf977c1c9d0c0efc0cfe4ab0193a0a0a5cadfeea9f201e1db91d7c5db8dd7890184a5e2eba5e2ddf3cc01dff3afd6d0a3d4a778a8ca94c1a9c885e3c30197f2f4cbafa0d7fac801edcd99c4b9eabf8e0e \ No newline at end of file diff --git a/hildr-utilities/src/test/resources/txsigs.txt b/hildr-utilities/src/test/resources/txsigs.txt new file mode 100644 index 00000000..147c5da5 --- /dev/null +++ b/hildr-utilities/src/test/resources/txsigs.txt @@ -0,0 +1 @@ +0xde091a5a3a4af250e74c325e50ee718d79d6e495ec6c552c4a4cff5b373e595b385e9839587ef821f8a18ba14d828fb854a3b63780288234a820330dd2ba80ee2f802231aefcbfd50b8e122f26f89c6d52318c6843109df8f235c4782c536b595b641a7c358ad72d06908c4ce2431258f7e0e8a2b94261874d84b8df06996668bcbe5752ad38e03f5e0e9bef1536ed1172027a5a77953383c889f563a688f1433a06c9ae51b1b680bbe2525596f56ef297cb7ee856875374da3ebd99cb883f36f51ef9f8a2dec478304d3348702142ef5934aa5e1cfe56ded82d166f206c4b9d56ed515d8abd263674c65b358abbd1b401ca20f2247c46efae056ea074b2a7fee7b4e67ffb1198a2e5f32b7a906edc87121069c7253ad1d5f93b21185886151305deeeb69ab91d2c37511318de6fc8bac51420a8ec3eb18817f9dc24ecff7b019b72c78230f33a5540bb287b585db2c590fe4e190daa6f3a84a8310246856be650a72483359cf469c9a0d8c603d2192a28d6a26212b9225777be4930fed9286d40724ea4228161ed1ebb9503e35eb1e5584e9810abf985ed052ce0776726592d7bd241152c7d9ebbd7365e28319d4c5161581757cba78672dbeb61c1f5b0831431105fb6960a901d70952b388789f1427af7b699194f72b67ddc236d5e69942a09e369ee6140bd86b9d82892761f77602b697ae73f8e6bd214792945c816db92105204318fa769624e3e9032bb8e64d861f39060e9ff455b9d7d767d3eef417140959f84c2f03efdbad37fe43ed15821b76847b37c0ad66d3f6601ea6441c15a81a0b174a3b0e2763e03553049f53e4a011dd066d714d2157899b8e7ee05a68851d7f968ec73c59c36a2150e62e52f5da5d5ab662c7f7f537fcaf9ce85b9de444ce9b6996c4622323d89760c13fc2bff2f0aa2ef1f44bd78186ad0d1a0d72b8c1ac9e1d4edbec53eedc084a89e1cc1e9d10f4e707a699663017f682cdda7dcc36b7334c3a66962b00c793e8b184812da7d9fb32dda9c8a791e67c91f9151f54335ccbe7e5e5bfda1937ead9a8712b97b0e506368b4f6e30496ded42a76e5370e3d91b663a304460e08b9053b872af76723f2d8b04496160cd83d08456e2f08c44a8ec9233a11d5ce0f505c32ad5bb51479f5d2d9c59c541150792438081e3cc41a4fd46ac37518bd5a3c51b8b0da710e0c2666dbc29590a5f862c1750c740f636aa359d016075d3c9af0ce63351bf39bfa1b9db025961257e15ff76d53e327499e65bdc26498964a2b93f6f14e4c3dc924b56a697aa5bcf04a5810465dcbb9f321ea5a1f51f847237287b8c36619a12ca6b7bcbf3f7e134faedd970b1cdbdf87f8580a563cc984a39beb2adb6ac25c0971ac7cdb5c46a3480a7892ca57dcb8fc215738257d35f653eb76afdd08b99b36aa096b5c1be893c4e204ab05b72d5925690102a000056db6db602b98ba4b6f3d199a1aa23bccf48b97d84ef3fdb1640c7643b2d26486bf11b424d31d6188a9137d9c3bcaf103740ecfd968810b42adc04edb9aaf012efaca6fd96f2bc35c39d7944367d26b386f6f7ebad7aed474225a6e2f0fb7319e6788395f9d4999dbcfcae1426b47df02086e22604b6326792f7b7e661b3be20c3ba58273d3c283ae0ee5504845c8d22e52a907f6472aa65429263df482f856b2eec32cddcd8cea007c66bcb982e3e5113e0f24486af4cfc67c35681d002ab206fa3b072cc63a5c90b73b2e5789dd2e34d716993c42f3679fcc7f2b66199d9deaf1aed6742e3230a616ff6aae0489290cc48dd0bfb8f7f9756f30b964f095a2a9a2f93b68cb68de5df563606c9e0cce5f6d533831ca6f3d302abd63c8f42bcc5df0340d8a8d6e7c06bb19c25d71e0ab568c5d9a987424c473fb8902da8067fc020c7c6141b98c9b4bf3529964dc2a612d12ecf3884d630e865d7758928355ecb3596188e773d7b864f9b5e224cd868b684696e49452808ffaffb94e7321340c72c33a4758b4551b343af9d83620872f5fd41d9f95dde2d04132ad6705257e79eb94fed372c85dfbf5352c59bf043e6ab3e666d741ca6d5d70cb6628fb397c79a1a6f23214eba23b2e70a72ee1a227e67ac057d6b118a16513ded70727733c3a155f8e21e98940c17cb9d8330fffbea6e1dbeb83181cc6e90df88b1b2958aa660d8de9d7f30e41c291c3514107be598d1dafc556f7b5e3310ba9b06f8e44c5598d5f5ddeda262d4e4d9cf4d3b73e6bff4a313fb1ab09b82131f4febc0a6fe68c2de531cb6e4e6263e8b563318336fb1f8aa0d673eeb90aa55717712c65a08998d11f0568eacceeaeff0414feba7c8e21f93c0a4743d27ebd0dd1ae92c0005ec41d78b9fa119f6915a4d0649428008566cf50e799917ed14ddb9be0152b1d3168d00ab736a458f43ffc7a2b14e1f360db7e2a05f07fb1f933c74e38760525ecd5dcc379062842a35d7c7fbd9b8c48c26c703df0b96df6f84647fe2e746a62ede1dbe4e4672ac69248b5312084096816e65c2b16963f728bf696e4786210fd6f8785097a4f47f7b13f151ed811f6add5cca6c39b9f1b3bb12f13d05c0df3c2e6225ac8730fc8d887961878aafcbcdb2774eb8f7deb120e61db3ea9314a1fb33ed3aec6f2312bf23e20b5baa77afc9930a1461203d9bbbe91cb142ed61ff7285dc732f77a4c0f312fb3f85924d558973dd168f72ff6b9973fd3fa96baaf0a5b3d8d3f4a737956628f3171152373ab8ecbc54a820fa4029d0675dc50593b6b6ac392c983c8b987dffdde00f2d6f37ccbc3024ca80c44387b38280f7249c14047ce06ef1bb6506b3ff41a0a5b1a562e11cacb2be1579076680e5b33bb861a0c144a5cb5f21afd81b8153429abfa48492d728ade81e76df9e5d3f0f57e068d57d8beaf61c7b57b5d7f1567d54a1d189fa2ec4825976d665ee995322f09ee4c4d729ec478845407c4a6254dcb2827834b58c771cab3a6b1bb899f448fb239933f3517f48cbefca9034a44491ebf167e70a4e1c183d4f085be37d4da84511a3616081c7894cea059248a7c17cbd9b19350ce67c28b4eabf779654e9e9bd7e949a16ca680ecadad8b96a1c4c2e9c9f0eb0e8df09dcf196b74a7bb2166ade4cc06decf325526a02cb0422977ad5836f2204cb0f01e083b5c599f0d6cd1c480f54bb154d52024ee1f2c6cfe85f5b76e8f98a24ba50a1293c93c8f87269f8fe30c6d06bdc46657e122e06af7b41cdc1df2372b094ebc09f00160459a3aab0774754a09c1488eeca23fa169578a0b340f07d9091694d87ac751fd53e5b220451c5569e6bcbcaca4f229eb30d2c261609f4f1b3b459bef088bac776b7127d6fd936a340651b2c4b9dbad13fac3da321c8e7c41b75aabb506d714ac9c39ea7fb899f1733d2a758c5c3e51173c7c293fd5fe795882cb6bfacb28abdc1d6d93473030e27054a5c20875cf636db7ae9c228a32c01be6209c234f319c29470a6cd30bd4462c73ae00081bf4f8b343b4b455b4908310361bca46a590059a99be908ab43a758eb92f0d68986683fa0beb839faa19b65245bbca1316742221248c1cf6e458d57ad303412fb0fb4c5354540ca911ceef0d07b100ec76c99c1b9d87a1ed31ab839e61562fcc301bd1b4f2f598ce66319ceb0a303f3c88843f76310905efa1024a7c7e17103b731359f23d7801769d243d0a59c6bca9ae6100322e894f2f450b635060e56d9a661604379bcf9633def38185824d48643a24b27b4bf559b4646b391d137c2ee0ff715747d55838caaf6d78edc28ff173b1005cd827957cf56c46e71d47d832c42e8305f1a6850c7e1ed11ad111557079654ab7efc7eee71043abad225f1bc34e9c803987a9c8785d099bca456ac5f336eec61a11c61f9f4b8a765eba6c1848ea960880667b7d974fbf83fbb5dbf54eb20ee9d6c4f5557dc141126d02d5f09c5197540afa0b5b8211173246fec9a6c79f5ba4b0637220d5dbba1b86dab69b5ada01b4f0351d9a32637888a7bc46ace80d38b835cb82377d4d0c0cba7950ce9e4eed654ca5ff9967f2adeb41a36b303936f82f1ef531a2b7232a42797aac480a805ccbe935ac6d3c008e2bfd4dc488b321f460bebe13feebcea4fff659d5d58b1f8021c7d03c1bc4f13b8069b57144d836d747f6955a7c001dd5fa1792171e847d76a8e862bc63e99bf5e76d133d8a9c0c10f8f3d3cb4d20e8b16a035a5321f98262c0454fca154436c470baa3e709efddb5ef05d99e273acf83cb294fee2b89015160c54955ee361e5e292127f6e20e637b3c81a16e68b59a6defd813abe50d497d2ecfbc239419523c0649ae40f228e92ead51b6f01c651070a970058e22d2d10713065f54d0f2c814cf5565b1aa95f8be832b2dc4ef7ad5479c2657f62fd75b8f649a0a3e889760d52f43b34cae52de3f93d5eee3c0498817c73dbdb028d3a4357e8036755ae4ff6a70d642b4d6270d1b527a93a1375c3938ce01094ebd498bdeabefc1ba4828e38eeb5d13f8c315cc555fc6e3616c59315c2f4111d51569857b5ae9820cce1366734681b40ee4dded4be33838e6fa08621149553193ba45351855325c5c43d3a83f46d47261e62bdccc079217291552b0b5f567bbd7c468f452df65c3bb21aa802c325fbbd40e2b090f45357a7ed36a6171ef8d463a6e96a1a84423ef51ca57f67f787224e55da9b8d025d7aa5a0b0ad24e79be2808da10a08dfcf1bbc56c76ee8ff8f86b5a489136e0d290e5a2a387ef98c49a3de85fbbb8521bdcc6dec541800771ee314757dbc17d4c56ea5a5b5225c1b86df74fab0f2451d4ce98d3ca53b4db7bc9ec9056c3545ffcd285de315ace101f2e7674a9e8a572e9905cac7bef0151cbd942b38f4ae0e9e148fff3d972fabdec31a297486d3d8209da3c6bc270b3012c516da98aad6c3486f3214b0f387f318eb453a4c6e9e2cf3ab1b9e87a2992f82bda74a05913a5506e8af763184fd3be51cbd8ebb290cd304bd4fdb6a4c4cbe66cac874d5661facd35ce9c52ef7d26634e9c1a4acdd19002049634f702f40c8a462265dd03d556ffd4655e80ff24b215f4b9b8ca67785c4c1dbcad864d06837d75ed11f35dcaec042b6ef919a8095083fe667f2da1c847698c50b70e49baee13d9066e979eb0690ccd7b6cf6da4040df33e4d734bb277d39c8a4f26ccaf2224661ef5a798fe4ab5026411ad2e13ef0bcadfc0969c79a439836dd0fa2807da8841382fd4e929ff4409a5474d949c6e4c74972c594c5ffe9aaa70bfcc94f2a9ee27c7dde2b0e1b56700589cb262dfa1af8c02f7246e4a93fbf3e4d02fddf6061bf0463457860a4b8cea1a4f7d32212f5ec553d66d91ea9960306c755b3c2ed052736579a0139dae909732b74a81cbc8a841ca545d2cd6ea9096dd7a13a3d4c691991fa6ef865662ec327eeffec55517a650d218ddee413ed4bb5c50fccac77c09a977c5d4bea044a88206a4422b16101020e9255599d586a192a5361b2d42f5d2dfca6f928e5d9219b1c7ecee79e0544b174b38ee9a17c75faa7d9288e2afa8ff79a5702441ebccaf0576d9d522afdc0708aec41c3da5d03974dac424dcc61dd5433e0af4a704940c1ae9b2b4bcdbf28ac7905e53b42802833ba085fc55889dd5aef97759e1bea3ca77cec6412d72f72be42a351cb0b4cb29b49ac69bd68c909074f40e7d316ce15f8877b867c2f0f17d5f798bb79f8c45c9b4b753ee4417d90894371580a1ac188cdf33feb6b0bc8d1af6d734c005be966020d08c395a15a277ff3c57309d25c0cc5373b450b1e7fa02cf80cd5faf4bf7698e37af3db08cd221d93cb7f93d4517a1ccb6e480c19ba950501250e2471d092463860170bcf1b947c6a2e463849229c005b3a36d21657becb04d9ed4bcc5e779c2b701645b21f18ff7175d4a4c1c68600b960cdb301c6e862dabe2ddbfa7cfed1d9c9641bc483b00903a564863dd8436a49a943d952c9adf2d9f94480ffa92a2edcc95ac1ecc31a63ad4c3318689866370dadb4e1bec8b83d0b8673193d5ad574e6071ba04b069c770f604dd8f651d5c3c557c14619d75f0ca2f95a4d2cc26017bcfdabbaafd339baa8b68810e5c19f4a3d83ebe41d8c71e941d2744d35d4b2bcf70a74aa508559d35358674666c8de6ec53b650487c6a8a0fcedc41e66640d3e5f3b1284a784d2d7e2e5699e94f96c690ecba4c90b1daf9868d3699cb71b72aba86d4948423c077b238763fab3312077aa602588e638db218a410302037af590dff430f6d115917bda5876e85abfa818bcd8dfb258adbaced232528d233b3441c285930dea1405030e2094508ddcfd39d3c7f435aaf08c1e0788a6f8b36f4641a0410d4800fe80ecf2fdf08510005ba0c1813477c838cb46c76775ffecdcfcfdad81173987f207747bf63bf4ab3dff005428bab677dfa0ca00c3b39420b93fc5ccd781aa39f75ab9af166d5f9c2db7cb77e6710b808f364b0a3c585f2cabc2a86d2642f05bc2524c2113ab2a2daa7508dff0a3c84e147b13d50b5364feebcf59f334cd4784a8c4b29de72bf0477e0e03ea7500ab1646aa730a5a69a0e4be9768aade3e8135ea8123cc1430315cfd3a6d56d8035f2ee08ec46bc3c6855fda673e523d1ccbdbd0b977f785a0ff7cc4ca8270d23e4f91c38f9c92b04f81f0af01c683cdffb689e09aaacc99b7cdf2dae5e6dad5962ffe1c6c5b03d814bf21b82ed91dbd7601d04d57d27ba51901f8e1fbb7f81d77c18b033096e4310e39700968690e161ef88de382e659068711d0ef14ad0f3a6a4e282954303b0193355511bdfb9675b41e90064cc3ee41f36bedd10b0a9f23100e9e4c617db3b72922085a809da0f0941c8637cb67b50341799db2ddad0fa51cc4a0577904233d2507a880c3ed96ae4c7c7a099b09168c66eb7b5a1d3bfcdb4b3014c1810cd56451aade2429bf148e04f514cf5928fd078a96a31165b8a0bb70758c0bc0f37fe25bd3762630b625a18510937d3aa9d89e4ae5931c1319366003a5cb67d8687bb13800c96bd2cfdc075011603d85550275599801550896f4724cf7764222de5caa92272aef9e746c2edfe34a7218d339fc15f2f0f8fcf9856b98e8fd03326f5167132298535f35da2ca01ade3ca9060c53fa99397a9acd8667748d80d8336ed9446aa473da16620126856a9c7536e8410310659022509753cd7fb7dcf4bc52438340d606b854bde0c6deba6a59bb55a0f76d86bd8f387d1054954d1bc0165d5a7c7d544baa7ac21292f88435e57e3cb35f596758e7b6399e6b44b7a4de80c6ea0c2d108a57a9033fd59edd92e87e8aa6f10f95997d1cf3ae9ede6859af1bfa600e7440a1c7ebe9c52d819ca04c5f24720a89ed666b6bb5dcb6b3ba61f95f6922466ee2375e34298bb3ddbf0acdd31dd0b03251aa581ca8a21c1769184920e45d766ca17002406ee41a27e454a79d6caa1debcb9b9ff56f4f6c175339e77465e054347765cca9ce68b087f1a8ca2fc8aa3dd5b09d1da45b5d711536796d4dd2cbf698e253d617581527e2c93832bdee957261efeb90efbf2008ea86b76576c49f336f906b5f6a45a6a4d81565407839299fb79f818d22fef6401c3d9ff6ba5f3eb14134cd2a8e16821f4fc77ae7e8c2f1645bf7d0eb6e9828d860af67d15e904457286b9205d1955e34a6a958277a9edf623da2d8ce54c6d3d1db331c4dc10a1974d226d3af2e02ad83d5b10f1273bdd77de14635983cf382c7bddfc9456aa0945b6d1b481e3bcacce3a788174fe5730cd0f88ddf86cb8b47862f98a9f0834d1ce1ba804f89727a377ccd287a5a68928944dc4f3831de25270b38f04ab141d0e915206e8b13773cd64e336178f1043d41183ff3bcc06eea9f1b2941340a2f30961f88c6c65be18eb0b121ed727a03b9d7474c335c70cc3a995d9946a544244d000774f6518af9f4e9ff50fdffaab358955e63c80c990adde11a3921b999efad6cc66ba01e99d7a291cb2ca09f46384cb6ada02c41bfce35ff9e86e0158f40d6e17f6544516257f83be2e59b21ea30e11cdc407b8ef0f464ac3d73acd517654a2a919562c9d8cc6cc9e1177ebc30d0947d0a72827908e897646d019bd2834ddb7f956d136670d46397b997ede4023ca601347e7f8e32297398ede05c87c9b77d37b60bcc5821c094bd4104c41c3308f863e1341b223d7af8c75aa53c04c6a1dc8d957c1da419b75214b2b29fca84433d50debf7413246b544f8b4069842f6fbd6c815074aa863e316b9388a52338dfa805deb9e864a69b8f0eebd7e0f130f67ca9733b9dce6a4ab4d8cb8e8f4380f9f2cfd3a3090938e4006c53e2d03dfe0fe6242ee4d616502fd58de6a12b1cffad4f366150c50e175b4461f09fb2a2c3217687d3259310c02faa5ca5be5f175baaf4a3b4a3350fdc3ef0a52f169e90c53b8a8b7b64632a85347eda4866afb2eaf076a69b761a0237b641debaede5f09d84e5757e5de5e350ad656dc89475e974c098fb7434256f04c06d874cfe1762f7210bf0e08f21849e86a0d316abf4ebd96e5cbe378336db0ebfb6f37bcf9e424cedf3e274705ce13d42f96b4c033f12330189d0a56a75d03ab55a106f6ae6dcbaac778cbd5220183eac9bf7b68f9156ff5f23fc660ec8889124fae27205e6273151635e9a3efee13438a8742eab32b4ba139d95636f94eeece566680f5e72ec0a2ec5d36d8fb037fdbe5960783e77c93b231da8620d9e214ae2716bc8bc1527db3dea59e505367ec36888fd20411e13f0c5d96405471881ade3f15c1f974e4dbcc53914b97ec75477e4898df1b1c4709ecb71852d9a37884222d1f33d6d4da6cabac7f68b747b4ae152f8396f11289d61fb63193fcd371674598ee0c068be2ad53511112f5915a089343f5225775050050f8c500e80dc1620567a08d414337ec2f2e5add9259868288f136cba73ee1045b947803cecb0c0eaee98d68cd7608137b486065f4722b4e1ca3ad2405e2729300e2d9ecde9c1380d8fdb1c9fb649ff3d1cbece7d31d308c878b2c74c707b1b6538f018ec0fcd8f00f4c05d7cdedf1d097981cb9def79a466f3efe4c1a8f21ad3f47ed7f6090601af5b61927922e80e24b661737f6cf3a171f92179955b1c317adf921bc0c7a7cb5f4188025d440604702d72a3e262a0e7b57637f585d0d163d20a664103098cc6b47c0ad8c63f76367d61534de44a7ba2b4554d5a9d5440fa1cd873cbb9e27257bc6c9b56d2c9dfa04420ab188afecaea80e9350eeee8bff268fdba20f4592a1261a8e8a2c49dcd35676ca00a34730703e157727cf27cefeede229547f09395aca25611c21aae926ec59d0d7c0b47dc5bab2835c3addcca88d13f5365ddbfe4f1baf28c1be3ecdb56c7ecc11c1c2b2a32bfb63b520a01c944ed44b5015c8fafbe758dd3d5b49d71ffa4678f4b4a947207bec1bb333077ab980721746d5ba1b3a3577cbfd8efd34d327fdf9651e9003ac69e365609ae330a9fd927410a1023efd65921be80698534f56ddbfc75ddec6919f5a51ad7978c4ce4ba2b831c12f096d1be6668d78ec7ea256e88845f8e4001a86387af7c15d96a99b9ef2a6df5243f0333b14b64d2d73bc386ef8453afba1df8ad5588f6419941966116b33452092ec7fe189921aaa911748e5851d92103ef9d8506b21417601f439ea7b6ce4491eb4e1936631a614a6800f2460d8fe5be9e2a02fc55737afa33702cf5d6a1337f8c3420128e09aff960df0d083167a356d5c14c0119b401b7169efc72ef3c5c5493c100bcca4fcd34f92f07ce229eda43d002accf478dae622178862ad2fc7ea84b8e79e0375acef163e0a7533b21e875f54467633bcdb9ecbfbdd0b6e77de514ab90d037bed7b4ac7b9efd223332ce5b49ea9d9da4b7c8e7d0e09aa75bf1958d7c55e6d9db79e6827fde62adc2b57f2ac80089ee716c3fca25180033400cf4bc139363b1ba6921e7585b678b89822ffe29edb4dce913871299ae20b40b2ec4162f8ffe97c04176097582253bd3362071b61cb92b1765bb1e0d24241cb4632936b729b0cbc787673de0454caa3f810b94278fe06f7100013b4217dd9199edf1f5b38c038d8d5bf5cff107e8518e8430500060c9e58cf4a747abf4c748245142020b0a482d2b0ce663ace6388e2517f9fbe7ade0345d5418cc37bd81775050d6b37b918225a3bd91c791852c7e1053863f10023202971ea17056d6796b48a25b33f027d19a42a9153545b9c9f421c99edf41362b326f19d7600bfbacec2685be53f0ade086ef979cf9b4831f1ec50fe6224d65bfe4162ae624a20e00e10d70e3a39d935b9c938be963bd02e0050b84c159becaa3816358ec5e92c846b2aacd67b5a6811790521ca3b9965d69f0cdb60c778fd125b9450753c6631cc3c6f0712c88dde09ecc976ed1744e4b8ba60b97d737e73ba7f39b5d77e21f64b0dbc1da39cf6174c807c9a1f788ae611118115971342b0733e470e5faf0193a95c2572e3e895bb6255e8e5134f1774a2826dce86f9863e019756a929b65bdbf21d2eec576ff4ace5964a19ade7dc5f5ccfe904ff1648c19603e0424fce677153ecca0f523809ef91b15aa121a638be703184ddd05e0143ffc4544add698346bb7af73c2ed99e93a192724c44c3cdfbb4b951b15e542471d2ce54e6a5a7ca9dc9c487afbc18ee10f567d2d0072672198b415aee89f10c59aac64fb5135747e85342d08b94565a83660ca0d35122ab621a4e89fa6b7762cf61afda17016df776de3b4fdfca203eb68c19b71bef6db61c4cb4826bc79744094a442204790e2fffc09098f8f2866aaf742ba7cd2a2cf4ee1f43a8b2de56f3a1331ceeb050b9b360e2210132163d9ce7f704530f60554792d7945234eeff89c9cff177d75ea5ed5c3aa63919c40ee2600d17d2c17285252a1d1615d0c2239f0ed6b4f42e1ce64fad696cec84558f38f08d864b90b0358039feeee51f82332eda50288a97599973c217c78d2c1bc7c69c8de812ec4959712835e3dc6d5271dad42f5a54c4bad08756dd4e4435f4599ee55be696b4cc8de78ae9519a7b65f3f0cb7a85d538eedbd88eac1010ff031da470708dbc4dd013e98cb0539d13fd46cd2a9b349cbb2db169dc53cf0a681a16d98b4cc15ee805b354d2afc6ca899a1e94d0113f542bf7eb48991d74f138e4e359bbb87fc7892e5775769df91f5e15f1137b29fce9ae42dd0a1e041b94bbca32ecff91ad56cc5cde50ec0d9b7526a5b72c4d1b99d024c23d4f990da591e8e1f672fd7af2f95b59ebccee00901c5ace9179dd1bf3fb98e20535be3ad515ef286d304a922f3eeddd3bff602444ccd75ac4b6856899bd0a0f44ff01f01ed41bbefcc6ba84eab024649d0641a94b562eb115b9cd48e2785167c4ee3c4626a81ff74064ac7622a01ef16a37e3406fa1b1ef7b4c44d3766a7d8e2db4b0bb08750db29b59300134a595749b9c1a2e36caf9e7b50fa8162d275cd189cc2d8fe247b59d4c63c5e28e21dd2d554238d6ebbcf2a1701d38e07c1cbd1aa232510695cc9f29e0ddfe1e54c93f2558f54f8372caebca9237c210cc9a95d766b465ff1b43433c6d19401d0301c62a64a2f38db32a99d7a90d5e287829c84d7383ee68d1d0fb4efa6c9481ecd068861bf8246edc754a60903d39aa7da0ef7e612f16d8083c3a7755e2e6205cb25a97947b7b8ef36e53075be26481308be5e171166cd78784a4e3e192613ba09194e906ed4bfaec83a1d961f723751de9c9b1b6c0a8c9c7bac3f73f9e4da0aec585e810bd9ed7f6a24ca0f820bafcaeb1627017f6f28ac1abb42be5a21eb597c3e1b5a1ae991a4677aef926e364b7d67e4ade9a1dba175fc86b520d0d0b67480f9d3be9403f52a5bc79eb4b774d2903b3a18cfc5539d2cb02e220ae18d7eb56ce75ba2832dfc64f580e9173e42068654ebf5b9c4fdf2c658a82625019f205d350475d9196013e69d5e122057c13bb7715d614d3998d63b5bcda1778ca6bcaa62cfa02aedf6c515cba6e4e73164ab6b3993c1866aa9bedb1f07353e074cbabedc9174a10b20404dda8dc025ac3fa4f9df9e0ec46083ac015b03be296730a44766d59f3d80fe5e4c4a08f6d4686d990e368934a007ac748a04de75629f1a6ef61f7c41b26a7b505e805050fe83d8c119bcb9ba9cb152f52b8c48b503ac0def7857b8071feffa39585f6fe7d45a6236c2e97811d37da52d8bd58043b7f063472cfdebb1ddc9b94882461c80bb4aa0203ef98292f966177ed3bb0ec26899d08e204279c934bf7195f54754ef6646c1532cc1111b367ad571723354ee0a45b4bc19886a24b5c8e2b3b3105e233f7af66b03dbd14c0cc3b5ac0b46c1eb644b95dda35aadd918e6f5e45d5110648035af89ed2460204b9e31a3306739876319f2710d5040d7666a8a34450f4af6d17777e9d3e4473d519d9fdaf9339c8e60255dc51bbd615f600e22f899be9a94281527ea2ef41cf12e708f19bdc02d6af80c58f1e699b860a6ae9315861b5ec268b872e1877b22f4aa9ebd9b0881513f445fbe05ab8f92c3b0519a2531a1aee5d213e05f8dcbe965bcfb4e7904a60224f781e32dbb4ff7f75d8c3b510b4403440e8bd4442c54653283d6bc1951b97afd6a30bb0d9a602484fc47e63c6a1667ad6a0faf11ffc73733c2e5cedc29abd9347e635abf0326c19b0be6b91e50f2f541da6852f5d9e4a7afdcbf3fcf5e9a2f393a5e193f7b7c6c3c82acdcee5fb3c970bc4a9bcf56eebb6aa9119bdd0ee5ab00e639b11b573214291c0547b13e2b33442c779878a2f3d5db4b2ae453ebdbcb8feec5e859691305a7119d3704adf386d0612f8c1b6bd03dc15787d78acc6a794d4e57632517812c06d0dcc3cc76961641b9d612c912ee2fd79e1c6fecc9a076729307259bf17439a44cc9f06ca523ec2b920a2dbfcd22d440710cc8ed080ebaeda6b73426a8c033532cf179844893456e13f8dfdf107cbeb8c9074c903ed80b69de32301f5682b079fd97734798095217966b3ffcd44f65357b33cfbe4295da59a12b785613bf56b373e063832f9c1cdc35efac96950c56429255ca439a8abdc051fddf65222225ffb59e8b62b50bc02fc929adf37c39b2ce1c4deba54c89930b0410688d8565d0def00330024177f41cfcd5b52c23dba89086ee4e809bef9967451d4aa312fef1f7c36496d170d4e23f092a8e9ecbf3152f206ebd3c218b4a852f388efb6827776666ab50e28d5e59eaa09f025860bda8a6ba9ee835e83261c21b25741e256d335be06f03c1deb0685db765696e929ca6b5c95a2b98d52acb98ed8d1b9cdcf1137ad2d595d25491db9f8dda7d3458e84a893ce8aeadc8ad56fdd65669622c19770cd68f90275fe2154b616158e1a7882d52f7286c606f7448e55e74eb426a190aef4299cf3ea8f43a10b6a6cfa17c5b6397eb5dadb61aecf5903c02159b020b2b0574b8daf20495d17bfc2c6943bdc1cce0a4008bd8190289bbd50b9e5a9e5816e9e9f291f69bba3c1ea8bbdd8475456d508cf352cfeeb26b0df726e08025abfc170240a090eee026e5e46149d643de268b9a7c8bbcb91c44f47fd68e5ad02a159d1ef3165fb4ed47baf7569bbedd9b6eb88caa34d46ca2fe9bb1c0530a314e80204bd89855f7fa7f89142f1dc5f22f5789be76307137f177d95e1893008f707d1d4d0a48a81448af3acfdd094a1b511b06d2449214e4d18ff9260c7699fb32f34f680f0eadeb725fedfd0692428988bd6fcb8d20c9ba9c108be9127d383c6df3ba68c4f5dc8a6657a5a10f4d98b3c521b91beb799d750d76880685d3de61d7d09449aae8a62fe84c51e74ef2b853250ea9c54d3c5e132e23db8a8e8cdb8bc5bd22dfd94a887962ebf347441f2f077befbbd4f4be76c12cb599ce4f42270b4b0d45f144945f23ace41ac80b5ba7e25af9f99ef0dce78a6eb4fae1e0f594f72a3592363281723089d76022c12afa2d767c8178c11d54843091317278be6a48ac87f2e6a917205d0733209d66e58ef6e47b4b361fca90cad7a92a8ca619f9dd27c61174ba933b25fadca10bf14b238f918b86f7eb614881186a8d9b069106371f2232e8d7f957982c8349232b1dc131d39b9ddaa3795586cd920bb94e2809a411b66ffe691fff4912679bbab05e0df2c76a568c04b6ee93ba549dcc3240d5683e504a6b904333feabe3a09b5bdefb3e1551b0bd3ba5f90862d36a86b84c02908c24c5a49a85c95b0d7d18a05906c28aa65c3e6b749bc306e0872c8dcd45503ba9ae125f597a84996235a0b47e2a8a974d6b68a5f02eac3650c01defe5ca542ff7a3c91d3992c65ba741c2f0d7e038b29a9e125700c3812b4e54fe4960e28a9b2b4e1fd4ea8d4ff8ad85cd5f6a917491ebe6c276094734445601c9e82335e9b359653887c3df6e9e61e1bce4282f6d6983184f7eaefa912d3e3b9c14475b3602f1969e183e123e0cd4c8703a5b4293a44a8845391e653a193ee51a7618781ffb82891a0c946f27a3cfc67c65a41f9c17d2c08ae39072c4833f3d7d5f7e2e83476882c6fe04aaa50a21b0a9f555cbbab9c20827408cec920f0f49429281de0692df37c5dc7b751bee86c23d5c169c22f370264aa7a4b87d2a22fc711941f084b423c73430c24418f85ec047655e9774f7f1f5bcad15ad48133d586969a4b1ba87183cfe39c66698b568d9a5ed697188d707084d9be3db68cff6e3a1f80d1cb3ee7eb511c766450598eec172f165d72640a9b8b219ef26e9c1ac88c793a554ffa749a13df261026f56f32815fc8785ca33e8d74b27a913485b9bae97cb458fa6067deb68d5cd1674c29b471b7c1d38b52445f211caa180f589977ee021dd88db162df90422e6075965004f6fe89425f7e1cb343a7bc025b79fa55d5e42d548ca59e12a3b7854eff3aa7251540767a76ce8e99a1abf16fdb4890bb1eff51288c3fdc5aeee840780e05f966eee4eace8b08828aff1c324a4ad513c1ea1715c12aa173797a8d6800650cdfdcb428443f49dc9ce72c282217606b40c7d040b504cfc04a26f101720c75f783e9aa092882bcfd716fb5e431e3435bb393a93dc7fd6e2fa2d2d5e98a4ca506f07391f775c26bffbeecdb96898ebf444a26aade31352aea5c97acbb91214d463a7bdbc9c9e53ee530956d6adc66620b50aa6be43f241c79328e6780932d7095ae47c01e53b6a388632effe5d09aa9e9e790f8b62fa979e846066af35cdaf4fb1473648acac5ac3372c148d75960b487b82eedd66a9b18543cb459d6321dc1ecd66a3131f1393b4c9f4b7ee9ccb9693ba4c2def1d042e8dc808092a7c0833f73cd1dbae368f3a19b533f400664b1f7152fdcb08cee59ada7d7da9d7b8253c726ef94a0e8f5a0284af81206ce4c3a6edfc4eb142b78970d47490f8913efede20054e5db517f5f1ccec382d77fc78799bc435d463109714bb1ddf4666f1cbb3b5dbfc5b1ef34b398b7e2c03ebcd7f0e3ca1906665ffc60f2b7c5acc82de20e858a4dc324765ebef23917b787d8f9ef089ce6948341de91273058a29b220bf7b9dfb304e16293fa84aa1b3d2835208305a284164d4c792dde3050b53f44cad2a6d50b1e666125219c5390f380e35ed83a5c68ed0e3cff294a16008fe5fd64df70d3b12d63096208a4395aea7c310f6f566acca77f5a8fb7b5fdbe2ca19df726c1f726b43b524d9a2507a8a1008ad78c93c7b8179b1ea8bf4be26a9ac4372990a537f097557e11d4784877c5d4100c5ea16d5d3511fad2f422d228445e8db4a562984744ecbb2e70eae44315e2e8b92ea6ae2df7aa89e7027f622da85ba9a5f1afbd8e914019308196e15a004c6d080adac3cd67f1ac2bd6061ba71c43c42e42ce707ffd41f0a933c7aca33379bc5466c08dfe95ed614e70ec4c7a1c9e932e45e43d44d0bfc676373344081c9256c443bcb09fa7d27c4c762c077e06cd9e8ca8f60dd27791c1d805337f08c57672cfe7d41cbe26ab45474bb9ab2a9095b037b6015a6d5658ab3273f534df389d6b97ff5cceec492082ac4c234b9f0e1ed7942f2e6ca0df1ec8e94bf726491d37850099bea8323de899c4f4720ac118c18305b708aef8d8b25e83438d0c62a7057f9982a063403b2a6004e1be81e7d562d2167f4d536f647d4a7b93d715c7f34b76b2cf83415067b1415e25c426fd59bd45ff2b1fe24f3a788a21aea20c358aebd134ca19c6fb7ebf0c69939ecf2c0a7ae1c9c57fdda4a2c2243e61e0d2d76d2b9601a3d5e8ab82f4f1b0dd369578b66cee59fd806304fa3c6f127843b7ea5425c7e4f24f8e74cd965c2bcc7aea5583f2ef41d7610319e91db72df0cf7370828cc46074a2f8311a98f30589499e327d0b1415784a7cda427c1e60b68a903f4ade48567aa42ee6b09acd3b1962eb35127e865842d043dab20bebc71d5984b3cd690809cf3f2f198522107bd0a612325312868b9fc74dc293c8b2c7e6191fe937588538d8b389f3eb3b7f124de361894c44282278df7c83a2ec53729b2e1f040bbfcf7dc22b4dc5dbc51045b9ffdbb3700502a89c4a3e5527a2e6f25b28c8391ca4b03faa19dcfecd1c59dd03500b691ddc37cb474bd21fdd27633ef8a169760aaf97e47a6fb22a8f466360a40bf26a0bf57dcff1b9efceae9ad325a5e45a5307e0cdf08b3bba7657503cf82ccb2163eff8f089569c2b3da9f5c52a9052868e147aff72f828ffe3a1ef21c3c0abdd26951b080d9a5b8b5311dba731e563c130231e976f5b575b725b6837b85acae2e7773935b6d6ce9a3667c003549381dd48f10c5ec622a4a42605c2c3ffebbaf6a44f5a9ee7a9f463c118c2d7b0b93508765ecf2378dacd033002be40592ce2d134924173d3aa3ba348b90db175452a8dfba653e2c5665eb12da2f6757efab1c594662ce746b311ca1e18a246752848ef2daec3969ed51b645c28a8be09b2e4e35a2f6d98cb84bad02d19992d213bc7a012576972ee4e089d4c46291acc47ff95182559939179090d912166fa7264b37bd608d2ad117648afdd0eda4b6c693b2654c0acec59982c2061b5d174917acc7562c6fdceb9186860c2287dee9a667f32adc2ab8d784df2df0a0062fa25e1deb974c444aa17d78ab69c56fbffb0c380f83351487ca428c5c7300bd846d1fb506851941a7ddc12664890220f9903cff7fc00f78676c827bba5610ff43615cdce5207f019a5cfe6ae9f34e6f4c65e6c136a67ece68207c15fa926c7d0afea4a3458f5fb7640ca3ce529264f6841f6fcd1b47e3061090525909acd4f98ded0fa20bf54cf27a75174cd3f95be7854c9ee824834c8a899ce835a695ce4c393b18d228f85927666c69fa24c074fcf8ae4df9eab1ac19f06020c1f7dee58c369437c7b345d43e0cd7511866df473eb53197957ade74c01e6b44f7b38a3d570c572a6106d49e1a6656d3edb2edc2e34188fe77118e09bba79ac716a529459ec5f553c54a3004784d1b374875c7b0495cd5cff264c9473f0d412943f184c620d660d3fa3051f912b2044d980c726ff8738ef9a0d4c2cd20c0c9ddd1126f482b86423112e4136dd9c3ffd1ae7090a8c718c65b94a1bfa8258eecab5dc5ee91e636a5c102637313c89be5869b3828a606e4ebacdf8b942c25d0c1e9b900b29ad49bf65349a796c13b5039e1f0ec9c09c7c1c167225c40d5a7f615ce5e9c0c6692938bdf2cd1ed3de65a581bb0f658f99c55796d9cae87a1f76cd878e79f320af7cde958501813e8748739f95c644aa2b33d91f89e3205e27316ab52e6bbc208e888f377253c080d930910a343cfa3672161447929854c0b5405dca1951cc282ea80fc78d8b48cd0b06886080c81c5c7b631ba859d83b132bdab13c8277386a306d91e900e4b6b8be8e9895bda546afe359d25821fb53cde4a28a14f8a383e7fe30c2c39c74974f6d503f6b3c39bc5245b02a36a838fa55764e86389a3dd00b9286a4b7cb8e5893a86b960016bb90fe8f4a4503ff6637249ca1e4e837352b20e03e25c2a0bc49e57b002f40572c7c5f203263bacf392bed30c6775bc5ffafb8466829ee9912c7a57fe9c045078a8c4e546785b10ac1af8e547bf10ee7955c699b79f20263867504f2c3526275aa80a1b7c1c159bf20c4657605c4d51244377300a1ebc474cc3ca4106eb546f1784ec45807b07b397046c74e81f5718b11659a37312c76eea7df0e6127d592dc2602dfcc4eca96d0b486f4684481a822a9c0568805c3499ae627b374761b7d07c870b55acb872266ef71873315ad6e36d1fe29af823a7730253a521a31d2135528e7873bcb987f03c8e3fb918cb264cef46d4bb9d78753f3a36b9c626e470ca0f65e383849fc0b8a06e0ea0ba3d5e104c8a49d9352dcc0fd382016ebe9fcfca691b8d17f31aeaffd8f51e158fa387811ce2d07106e0b08fbc752fcfda9b04de89fd7e74c8b80c31c835f4b1081441e3bc0fed90042cbf6cefb8f75aabe7d4e423573ae2304d213767a1fb42ff956b185a513c0866402326ada7565545e9969a64d5a487de4d39563cb7954ccd859c967caca05e03d82a402c461ac25776773baeeb24392f3ff47285972a13d99a87bdd90e9734b16e5104b04bd1ea731daf4bda57445c94ebfe8f737c612673e18d1f3de32572a7eaae35fcebda9e967a29c3bc30340eb87b8d1bee54aa15399c154ed51c3eb7db578ad968896e3f36ac2b9ae88c5eb4e7be2db9310b8d7da4781cdf9a4709869896b35a813a5b3fbe100caae7b48f774484b5f2f1305b3bdf43cf30a5454190f4d3c6279a1325a9e41a84cf9bbc3c25983e15bf1c43d0b427f4d5524fac70527e9b8c1c1b98de53f34d14142d3c827ecdaff7bce843bbfd920f28c1231b4a1e4e156105f9c5a7f58e17c5ac2beaacd902c25d52a23fce7b9c11094b3fffdc9bd2909a7fe7c33506af1118e3ecbc48799586872c7c16e617af11b82e46e31188c862305564698ebf97fccf0192f65ef759f7652d065504c7580f6b18a153f69d6e2dc515cfa76fc91101f7a32972f8860acbd033bb00222d46c467eb67fc039527ae10e0bb1da752a4f32246a56c8158b6a8226a3d681c86b7db7c8757f916ce2f29ec56c53b90c72b40a5d7a5b551740aafcfc71d07ecc474609b25e2f8a739265ef1d51bab040e150a863aa2658cf9590647608f7daad6b8861e7893d8575d3e6e9f52eec464363abcb55ebc8014ab0d3fb2fd6f68036098283f673b6fd51bf5e1614171192361c98d63245a32b30615ead2125fcdde8da73557d0e2dd7865ca2ef1652447fee3f4cc96e2ed0d7aebfda9bc120b08481e664466c9853af1f76a57889e0e4db5b992de295768d76c345d974c298f10acb3586ee0085710f0b448b13e1d0cfd1a91a4d3bfb35b740e543994fb63f38d1dbd09a68a0dfaf256b9aff55dfc7288de79bdec119202c7af122be61bb6f7aeca923819360498c987870c1d2710c68861a19b43dadd4d92031a733a20da6a413a8104ea223d76b77a1cacd7c614528c1f94787177fbac3ea23395a722a723c2982991fd2d8c33d15c0a819aee104d506ac4f59e9f6bc9c63104b17f4e0c140e57b4fcbaa0ab42ca5ff69c51f55d4885274b6f8c1da774d63c57e3649e46547834488c2d9cee98b1d8e0523c280168fc25e3171f4125cca0dd7af877527ba22b3ba0d0ec12300ba5c9205570c23ec7f2a571fbe82dafe955a58b9d76d01474786bdc6ea0d849114c37f36179d42f47424a707e252b930d441e8a26bd9904f754dd6abf5e958a32768dc779ad1514a96538dd2d3b7a527e1a598196b690257991959d1d93469bce0c7c8046a4b8558975c9de9a1e60a98a2a898a0504791d18208e4e4c2febf30a778619797725c598f57ddf5851b34c6e69f87e01dec504b7e864536af3bdf8689404c161dfc222ef746a05005077905d21f4a2cffccb66d093602d6826f3496a0dfa242c2947326b0e7fa1577c5803cf050043ff2e2cf69f7789c4c0102326cf039a45c7007e06d3feb7592976c41df3622cf8755819d44ca5465ce1a20c17cbc7ca8323cb323685a381a58a889784d9b4b2aa612a7dea9bcc3a4fb739339c197f9e83d829575b0c11cb3665c2ba7104684fff7a313990d86e61d7709cae6ccce5a9152c450887766b037d90bf104d3ac768f651862aff9c51cc9b201bcfd48d9d6e763c8d9d6d2aa66ec1511c03b2e26ab353ddfb67caf1115a5fcbb252edac76750c5ef5d4e5dfed6640c5c0500223f98c76e21bd861c7ea38f5ab0e0ba6fb6c906c3bc7f53121590b4f5a563db26e43378dc33a9f76bdbf3f00a43498311f68a2067527fcacb812991d5a0675386e465fb9cf46b2a3ea2a5c94c09792b1492fb2a6895d5872f9bd0a64e90cfa244c1567ca0be3cd8fed7a990acaa0ab7dcc8f3662b5db7f6c94dc85d6717d60290044d903820424b58f4ec9274ae51f9afad7b5facb769660009aff36edfcda6ccede7f11f26e1762197eac9ecb9cd1e2528c5a880e17fedba2949531e183bb85755e12a814e14e5259cdae52992b10ce085e3e62bdc92b4ca28c0469a3ddce27c2a5ba6c5e65344a66e54c370205c63551f5d5a2379d8f5886a2372b6040b7d2d92b49cae8bf355c37c5a1f0a715918239f47b694c4efb761b06268fe311cdb0ad739bc2d88fba79329e3fb6e337eab09891246d5aebe6d0110bb6155a24132570309349f1708cea52fb450906757defb7cfa52ab046410fe49e6992530ef5a78c34e8dd661a3468c9c58f8b192077656a531443a65dfa36e9d0607a4a919c244181cd6c24fa3fcae4f5e38a72f0bc1ac6a21b414cab136bffa7ba32095e8874881cc2e06e6279371d5fd20f36333c0e05992f02a87fe6322fe4172bb88b5b2fcd13baab79914cf91afd8381d2a8f94085f97d47d4ec7914f09bf4fb3ee0182dc40a313fa0551a79cc6e5a4dedaf3c163525fe93e545ddb602a42036b8ab15975a3a382c83e031390a701f3b0c723eb5fd78391f43d0380b33243ad806eff77115417ce8ffc170d4b1d6c6824da1c357b4baa9f64a7cd543bc906c39a356d885d69ea4fe7102897179643e8a493dc040acaeaf55c7ef4d0e1186c24cd1fb053ad609de66b501d669f4f09c2a33412803e51cad532a18a2a70968178c4406f06140dec3cde5d7e8a1af6984c65d4186439968258a80d1930fa0cb5d28c00f13f6e42bdfc8d41adb8b2e7deb0734330b442795dda0adbb112efd83d7d211e73b61692a8648b90a2890b001c992bb66fa678998447329084733e160fedad2d03308651eb32ec98b8f0740122c59d55d67c574898669489c0dfa09d6374161968f0dcd0c4e37967b0a380d86bff1d0fd5c3bb0420950c2feeb71c63bad2352fe72d71175f2ad85c6c382239df11ea60b22ccca239c27e161e7cad5df9d78ddf39a271d4be7c1f9c8796df7465c59954f3968db27ef5cea2475684ad5beeda83478e5ffbc79d84dcf84f052a704cb53c7628bb7fcb9b4104851548dda08f4970edc7dd8e660491e056c2772324ff8c74da2d66c694a45269ef2214696e67955730af01900fcc5aa2e5710c8f36bfb8087bce7341c2ca469d1514ed6e455b57e41c995e6396a02f7bb283774fe72e8b6335b9edf36b9694852842747f1f8476666a2b6a5b8b553af98513996c2aaa5ede533e8af139a43090b9228249f231bd1cfe8bef2ca2dacad42d264698c2c63629a274dd0e06ae797ef581873c3d9390699e8e03d4300f8f6bbad3b1a3ccd262bdbf83d87e28fb2f7af5b22894764cce8f23faf351605b56b64e207f0b0bcac55eda9b3895c1a09fa463100233d428dcba624761abeddd96dcf6d3c6606dd983c9ac172f4858fc1b362ce47c8efa2ca4a201809b840545d6571c9c5a1f86bfe2ecce68f337c924a4d71cd33037c2d53a1c1e2d81dfc5b096a31bf561b09bb24dd735103c1b355cb08e1460399ab24c331e77fac4dbdfdb1c01fa3afead7481a55b7498003cefad08039f60cada7bcb6f8d721a55a97d11c5e273327fec0e6e1d206b0e9bafe034fbf29ea82e53f098821b3ed45ea64e2866a2ae9d90d135175053f4ae827bd82b634fe604d440e1d2ee23fb6aa0212bef3baf0e85decf7d9bd6d6ad40f56569fee99c597cf6a7b927b9956ef4cf4a2d4b89da4c4c38a3edab98e36dd8ae0d22da77d4f5659da91d2b8eb9a0a36480728f99d7053dff8362d578e763535e24a1f36776053851e27ea05a5007a43abe5ad9edfc88cd1fcf4721889400f87ae9669d2c555ad1cb5b5090ac0ee58af9f680b529010e4f3c59ef3c8c7bef66d6b43cdb342db3f58ccfd25b4a9b5e204a21a2eb683d494c35167f58c24d0ea48249f877971d014059af08508a7f586f0642671cf8ee9151033e79ce27cd7f2199a5a2ad6a31b9fcb726e00ac0f5ee762da707f8eb2ca803f16cfdad4f3b08e3d5d7239e0d5aab8351986f92267627d096d0d22b50bcde27d731868e213f8a4d7764997ec0bb9e75fa6572becac1c84882b19acfa80e7de638d87f24e578a1197dcf5fa203e97c032c5c8daa07307b87d358934966b4eefdc3d489dd477ba1886be7f027f9a420b84c1dc289a0138d7494c99b4f339d6404d532eef973fb26222a75379020e4b5b431c755b86dbf3b3d109737f1a5a7ed5e6726fa551f6a56bc9058be684443e30c929caae374a19f488503cb44c3f3b25d26f76113055e8e3b00fe863a75f3f0f7f24c0ae0e095434773ac2f1e6101ccd47ec1ff9f7302c2016dab1f7febbe4f010949d339f0e47f2ef673dab157c3abcff40dec03eb8d6c261b37d34afd061fd1180043f6d6b053b0d6913c6f081305bd9ed88dc32da2183ac8cef79d0737111eda6965769bf1f7d6403b4d4cbd031cb1456068f955115770516435a654a48614976c496c901b56b28ab09d358ce2c7a59d045c5b3e99535a2ad3186b1950d97098c1729a2b513bac1067a21c25c966caf43233babe6a4d4faed8f078972209e4a737294ac293513077e9110ffa9e6ea7e3f3db58f64032ba1664902a5e87fefd44b74ab34c9435f5bdbc96b547877656491aedc28e7579c95ed4355c483c38b3f9c79fbcb32ee826c0de4711914a8a7b9b11e396ae2d8a30431ec9837ab3a2c4731414b5d81c3798247da380f1a6737c4c3bda45eb596dacf8c905ca774ebf057af342148ba1c88d91d6295f3723be8c141404bd29af9506f3402ebc975aa2af1252b0268eaacdf641d2a80c3cf44572e6685a37498c5ca482734acfecac35c3f67aad9fd1a3f4e5355a69f01584cf0078d435a946d39429f9ff6d91616c4617c4ac529403996ce01b4f43d179e219274e2d78c4b812b9f77ad73a184c535d11815bd4ddde4bd160420c0b0fbd0c9e671956377b084d70985e79072c84a0a5e497a59852ee40056c6667b32189b6de4559da7ebea364829283187454afd1c976e04237d0a6b0cb77de9bcdb678cf16a3a5df4b162bd66dd61cff4bd228f6fc4203ecb0486a9bd353cb625eb430352cbd8f4808f6701882fd93bd529118887f9129cf926b5c4371ac41ed75b48dba0d5383ce7551ebd4924b8573116e1ef9cd1b2b1d18bf300a79795b7bcc6491a5a5c9c82cad4be5e15c14e8ff058f90c2968196deb6368de1d38224ee0673e1df774ffaa90ce337eaad322bf03a91c2893b55e05ed9b1786fcff0d6a4745fd4da2e850c33b5becdc7a4e0802dab58ea6d3257d5a44ac9348422aa441598ab5cb0a2ced701b1eb1e23545ca83b8de4fc500cdd3f4c789cfd5d304d83616af9776ef03863cea4a7524e93c95b1bfcbf27ba36a6b1c5ed7a6295b5142d3a5db088e2bc08e5c61847d79e71142446d8c0e8bafc799175480ca01db093d077493915c72f92bfb9d09afd85e6d10af0dbd64c36c486b10288c5527ac1c822c56ffda2a75037ab02124bad34cb3148e1e047dfd3801255aaeaca4ee152bf21b48fb90bb1c45cc69264ed5776a7e858e00a1a97374950b38d49dbf576b7d5f8762f6b0d7b7a05e8251fe17853b272c3d4ad30d1fc09155a54ba2024fba9093e3f356c77018b8f8a4bab3b19ad520033a8dfe4ec47b7c7387d25b4039f794e968944f6f66c694653a7495d578b756358d8a9f8fe59eff3116ded64f80d9163713dcd17987b94ac795f6e9b135fa2343e387a1d4e093820f44df7e886a4cdb7a2202f9d0b827550a7328460b0a95748cb4792c1a516570d00d9f11cd633bf951aaa6a61bbc65f7f20f3712be38283e44515d83e803e92c5f006cd4c5e3ee936dd8e6319d962f7473688a7254cc12b8296fc9e4753a57b9cdca16dead8d6996e91caa4e91ee1b3bd6499c5b0298e741be7cec42bbc941e6310c726cfc7bd25f934c59562dcd60aa4ea98ae5f49479749ec449a85c476afa2f92b7bf7e0126d5b11aade43f053656c053f8c55d7f50852f560fdf430140a6546c7130a6355aaafb10c2329adc594498a8d65616b4a6c113c3d4271298aa9e3347aeba9cc2a7ff51257af6f0071639123dfb3a9c65b5480aaa22bd746908841e1a923a712e45055e186ec80029825eb45df7f785805dd45f7479db84177c71795550b400878358f2d4b6c84a864a4450a682cc6ff69b66eb40399d4553c791490819ee0c495487a1bd0191b8907ba08e4afb097e11a914eb42a87be5772c019cfb0ecb9255120c9b3ae82ba507eb1fc230a58483b9b6312d20a1acb15514392abb933656a631c214b7337a720bff1e26f4154207908f1f19e2e84b3df6ee6c745dd07640d0ccf7bce367d02635a62f98f851622018bf07f4788df6df4f0f255b0ed20763f7789790490c4e807c810bfa783185977593e4a2084da9634223888d4a5a079c18b7441f19fb47ced38bc56b7f98f9e1473a31d3ad3850244de9197f11a2cb30866bc91a10dac832407f39f23675e15b2916d938b1614aa4fb1d0bcedb95b756082951e9277d8ccf7e968c4116d6931b54545194b776c1a7eb6db949d7f6a9074dc26f37889d76078055c61764ec9266464a628afba975d274ca8eee7032a663f1400f3d71be14475c313ae34a4e4ddc92003ba203b5c5eec641be30cfb1eea3bced117f30d50b90debf24d9dbd189c61cdb99c6f6057af185b39d638f52b3bfa02890e0d192cfdbabf77fc6ff90bf2d12d4574838544fdd971edf2ef2a4cffc6a6ab1b577a43d971c93758557c1363534defc16ba434caa8dea745ba096d81ea07fd48bd453551bad49d0cb5ba5d88b2ea6a459eaae644023fa365c4d88f3ff8d8634c783a273b47a1ba13ec633f7de8ce749225813e5a304191d683036c0c976c3d9ac186ba99bb447f8ef584cde6e29467dbff716b5e608a55336b6bd5062054f38e246c281a8b969d48d6bd83290109a07210f47b1dc50827413ce6fca2cba22f50af66438e74a0ccbe55d40b8ca1cadb77681a85a4012b70218199e3967b1474524e9202a959d62a57b3407c19f1bbb690f84aa3c9586b15d95aeea9a190bbd488459a866ebae3a4de36715e2bf28519002c9ba2fde020656404325d9f7021b913154e825682efa01d0170fd86aded706fbad8b0a234d2d8473d488d73680e5e30849135a1c8b102e46f1ed28531121b569ae16973ae48a47620532eb3ab6cabe58db4abca70acb820a29d8803c10058ad6b75bba3ada2bcf41245c102f1daedfc1b5c199f86329c8e1e586fbd09c990139b4793413f9546c2b6eb4141a7b80659854c1bbd7070160122179892f2362d54a65eb16d9b9a43bab44f3ba2437919f2e57856af3c6dc9b07ceaf7cee923e5e0afaaffaa69990ef53fb8d7e70d3cb427aa5bda42adfe666546788cc4b86b78ccf5d24c87f5a4e7641ec16dfa5ee5da9612d82779a5c98e9e6b4bd33b537b076ca828eae1fa32f0326e4fb308739f4646023e66696552f5010ec0791582236d942863628dd12cbb0fc0810d36523331e235a2214949525f89b3319a25042017502023ebb0771c6aa6325880361db67f569cfe94becf0f476c970f1b9a35d789757821f685f1c687775f000b035684f4196b8da56dc35f5843eb4b400b3013d4f58b019083a677616086da2f2eb720f661c03714026c634e0a40b2d2a2e39f0104d5504446b333066423f36a6e6179d768e78e50305da4046c23d9d6e120add38e07fb97505a72e531c5fffdb1471f12609136370132df2a77e7fde1601d332cf148d93e85ccdb18bbdab055638a89d0ab316fc8ba53e46a956387901604636f53f8a012169f5d23f0fabe8da52c537ea535eb0ac843acb4b562e7b1b4cac61d88f38e597aee4d4ea816318d4f4a0253888b79f82769fb7523e6e1820f9db578c79672c1821b38f7c7bcb8b6edb84d36097e371dd7565e7e85e2c2d4b8e7348b73c10cd665c3ee495b51b178b475574a42bbd47365ce9af789c23c3f3900d6a5be05dd3ab957b1b907529223ac73c6ddb232e8cebc4ef6a8d35e81f4d473582b24348bb07495dbff44ea4afbdc47f536f36a77f8c70bada62e9095dc80bd752eaecdbb8c9cd2eafc176a149d9dc8bed58848e6423f4d8ae86319bc63c5a4b9d80aecf7deb6e818343377a046d770a5947c66d3a7e08876c135fe3c19ab31d4ab4af96ab0cde0e52b21ca3531954b4996cbb6c6b54b4cefb8bfc5b78feda0ec9572eec90f72d81000da5680c6763267cd31ace184e7869018dcb4a16f73ce7d30099d619fa07f66d8b6b24c263f00267b962b54e8a1d5cc26c8fe5b003d62bb9e281d68ae903545abf5a7a1c78fdded2d7807eec0414dafccd1d74ada9a1627ce35ca16632b9f0cf2951eb73a9627f2936670dd862e6459f3333ab2fe8a2c127a51849b9d38b71dc8afeb95c668598927491a00ebcbba595a641cf460813a3cb922c6e5dc04d867d85111ac5d380140fb44bc9f116dc9b484464d8da37acafa8b7b9364eaf011ed9dc9e4d7f07abfaa0e174b8474e80bf040aea159a5ff1af3312db70302f3f1c3b104f8db709c69672ee082e8c9a4ac5909a695c1d9f3ca16602f0a0364e51732f5ee80a350fe84d8d58e1edd506722141d93458513b22f573865986cfca2d3bfc991ceee5138806bbf1428f8ee13d7fccfe4bb163d2482ed9347a788f4da7dd737b9d57538893e04d7fac9f4096bff38a8fd2d4078e54e5c891cda7b7d17501182b21ef5ef2e611b91894e87a9c6677ee464c721129243b4ee3401e39a3e2e7be8b7d498d0e170418aa202222d907f36a5be6f1a7f93ed5d9f0dbb98c256512c71322976c76688275ccd0d333bf2b4a73c94072d1da197ddfc2d28cb028a93f469edb7f7186e2d31e9e99c56ffdac76f7fa6de02eefe9ad1b4e2741d4e843eff2db3ebd6b3bdea24276f112b9dd04ef4a23ae021acd67b08e4be04bb66ea8effb39eaef0d73d7890f13c61596b20e80d2aa3bad808d9825470e7eaee6bee2494c2670edeecaa4fde4bb9e1522938df53ca302f35484508605467dff456120140ee1f6cff62ff1cfe8eab585a8b480251bc774353b52fe949aebd82dfd30488d54ce348c559e2d6d9f6edee40a87caca019e02104fecddd196820a824354d31c04ff3f6b6a3a653bcb24efd51bdec71535cf19dc7df7ac6fc9ff07fb60e0940289fa1921a54f34f7270eae222c88fc4f2ac75836c6c39275f49b04dec1a463af38852a85c64c6be260c1ee740a33480aa27671e55cf81a52da84dafa4943beae9e5e3d379de73c87e5c5d8b33d1697d638258a2a85e9d4454d3f04d6ab7e7c62da775736bf93a0e1fbc0a74259a68beaf847f0d1c2ec0875194bf597de54ab132902149c5e8cd80cb1a512246b0dbeac37f7aa884f1ed78d0576b95e549810741f490dadd390bd7330634c774b25749e3413c70a5c098b890b0bae66ac592e1cb8af3a3cfad9fb3b54abe0cff05de845e2731a5ab8d36755944ff2effa211ff2d4d27f3ccc56cfe655bd87d82c4ec3a1c63f302b1affd07090b2518575191d0c2522760d72dce8363ab4c3a216029b079fae8ec4d565e1f8eb8364b63b92a99cf1892c00855affa4182e7eadd4a5bc1326ae50688fac2d052e87034dc91e8282954f6241e39d0b06a6226c12c0d1f470a2f2d844934cdef26c564739faffaa79b36f909176c9dcdb2ac9d15edac78e9e78de35ac5dd53485dab076dd575a4d083c6e5f1d7210373d434f148ab3351a20ecd7ca1a3fff797ead05391ee6ee9fd93e6967f5d8dd8a9ce17b9ddefa97bbd17060b6d1d0df379beac466cc06189681f74956e73103f7c4505f34fc79c2371a329c509e6b9ab7a66293ed6b5aecba9ee27d64efb3205832ef161567437308e389f364e756163d44310b936e898fb260c990530e300aac7335ac7b1f0767c7f8d4889298485c160ac1bcb70c9eb1291ee2e0b537b9817aee5f2c333673780b652eb60da7c8d4e0f51b7f2456f8766ba464a81eb389d40405b6328ec21aa6327d9057c199e42eddd49eaaeeaa5755b00268d01b6e56c53cddc0224dd3f84ab159c4cdd52202d8375963134de0e13da5ffc44f3fa4aca689d3eec8e2bddb6fca1db7cbaa8230b7ed8ba46b47025b8481c4bc93254e5c7ec6001709bbc364d51ff04a9966b7102844966d09901cdc1b8c7d3f352131990f063d78df16e94f38e63d17538a1d520686aa79c20f23892378ef73bc865d965b9b290fd68c53d3b0979909f07533346844b803b48dfc40e245f1ac0a25eff673d83a8496657121b4985da83cd6108c78535bdc796e30d05633bc4c581e897fe12a6c8b91c954979830ea5f4dc5f3d0cd430464924cc410c84f942ea3479aa10265937fb45c7624e6c00b3d111e275b6fffac59a9855fc71972427ed1d358d68694259eae014450aed148d6cfc033f3efbf689b66f579501c0e8b09a258d13cff580578ff3042437028b97dc8e1ef09ee733ad6cf5e163983aa0c77ee6ed9bd254bbcfb0b1ab5615e4d5e0530a5e826aa4fa86beb5413b0e1427690a37a5065bdd552f4c6600d7248e23a0b5e714aa3a1ab2c62f5c9f30458279614e3fec419093c46e1047f40a0af04ec37ca29d625f06c88e06ee934c575eb23f06f214cc051e9dcac75237698d23928f6c1bedc67784a0bb813bb5868b9c510f359199045221c33624508e432833caed38496bc1bd9ff7aa14270579b5a8404eacd5a5ddc7916473981da97bf3424dad12532d5411f82ec19a74f023878159ad522e83c5d5dba1c175db875a12950c10931e40d5bd76375253c27c1ab5c22f7beb805cf1f61e64dda95f0028232da44fde51b8e10610ad4b12516b2baf7301382808806bf68fac28e2b51e29acf7e8a45a5b8f22b941ce1083074d21e08537d8986303413d6ed787b8185f1b5fc546c644085720e82c76f4b6616c31d25ce05dab5cbf5e2b785dc29e33200a60b06ca6c29353739576e0acba22c257070c624ecdd7520c7713f42e5e93d53b4dd67227b1d7da0d32d1621a50026e893bac59fa5d6d24f1498f0b169f2e941fa4f57e213a7e9c4aec77fe81a2d65bf69624cfdc05178473ec83c0c66d0bf4e440b1d488c08585026ca535579871e6d426df658aa2d4fbc825d03cab13a3da3bb2707b419c208bc304e4e7aeea21292e9d8d30a050b278cd3a56a32834899777a63b32134e700e10c201e2c10146ae84695e1bc752a8d878647acf6bb1203cc41905a7e877eb51b833da79d6c49878c869abeafaa190a487b332fe60ded89cd8945b9645af4852bc4ed5ae2f058bb6159372970788d64d96906e2d5cf465765aee259d061bde587939f061b588d54b464949f5615bb34cb505ea0e77a10141da8dffc6c4d88aadaea703a99a95575d0954d589976970f0558710e9545ef46df6efa72f0d29d804c090a228e37f30aa9ab499ca93b5c313701fb0db0da64c82140f7b4b87535461c817d487b55185dc98af133c6ee3dd7d4d65d0cf301f1ec564224a6c408a8f814ada1faf6860fe83c04283a6fba2f68be861715fd0c95d984cdb8018e0abf527d9c04f4c4f94745f4550e53461f3cc04c04113b62c9ca1fe392983beb0e03ba5036ed004ad0bf48fb4daf94e00e536d94f69eab44904a4d56a6bf91ebed95253cec0d69ebbd9accecadaed6640c842aa096d4ec727773feeb75683371f298cf85f7a91de1f74881df18c7ec387faf4692087d2e30cc7bc8a45ba9fa92fdd69623a3585afba3df1971e99ff059906fd032c402a04abd06b9f6d799ad1bdf38572b823fe6bb67e4632a22009e3c84291f3aeb5be57da8b1269d894d2990959f56c9721273c504b1e98fe64fa213f25e43c01621a38355ec7e3cfa822a8fa4f36709b7f8b74a309c02e180b268b47ef63284edc411523e53cac6a4a37c494ac52411a35dddcbe8c4719974cb8ff063f3bf811efae9c9eb98b9243afdba6a4db1ccab74cbb8e054a2a6466b9c8569c7f57734a5c0dbd6d409ab2b2ce1cf730b7a8e1785dabaa08b4c9e698a57d103c680504d2c74a647743eb298edbccd3271965cba76ca55536bb0685b4a89b84961b6286aa7b3fffa0e81248a2165eac755bc922789a71ea328811476e6c53629c149d4624dba77326fa44beeb1027cbdd9d465bcdd8a653f38d1080e5d6397b826f542fb6208b2d0bded86b23c02533fafe98f539e1bf7fcd253418bb09684ddd75a4a9db66de0c52b488d62578be3476c31b9285f9362d52ffb46c13c3416196a962dee74f807987ae403812e43133bb98c959a58e7f90568fee66021d0e83b8a5f094392bf428d29c44d51642b4098a32be69eb7059a78575e4944486ec1cb6fb15619cfc3615860e0f7d37951a5b9290d0c63f0e096e0a1e75e8f8ecb296fc35364a6eee659b3a35805998f43ae31321676093c663bb4b37922df3b604867a7ea3724659a75bccd3154dab613c03f9ff4dc612624b411bff8284d5c0c1cf8d521cfc3b19c8c6c5c445e45e8829ce1560defba7a764d1773033547818834ec35395a0e2c49ffe78bed571c8abe2bffb50b96dff3b867d319aa43ec8c86d454b99b0cfa7307400cdea66e5b1501480319cee24f0e0e6f622aae09ab7ed489d1360d3700de1722ea8caabe38a38eb1541f6bf53b18086c549c4dee1bcbd364f77b28cbdf75638f95fedc20b3fbb1dbf65786c13e87f4f0bc82a497e0093678671eff2100a8d8758b1d1861c1b6df6753657eab2634e52094141c1172f743d1ae533856f5db2bba32e4ee78b7b1ff91f8c19d06a1bbcb415e326b5dcd5e83c026e5726f729098eca25a2c1f2f39b7f42cdd40f5b1854cbd5aa353741381aa512b08fc3a342526e385010876d024bb3c62ef02eee0473af0c42c7ff97e9696e2966e2d3fc246792c6b9f95f37a3c79118900f09e31b228eaaa6a5a3e02afa99f22dfed89359d89cbccf861e15b17a97e14d8f5b68398662c6a017dbf79331742e26c0c240159faed700c12d5434a9b15c3362b91f3b098b10b3b850674b5b78bd43357f34264395eea37ab63bb1d4f94c0933f51b80e1321aef77f8a0c6a42bc41102e0f03a0ec961ca3c81052dfb9107405ec84a9a6c3bdec3a65d5288bb8da7e1215fcd104a8147455bbdccbcc5d4773f63ec8474884547e57bee3a1c7da975b6f6a71e1c89a0508917b81958b8dd78c2a6be8c4a965f7d60b8f48adc3af972195c2119aa45bd6be01108a3e9fbf2dc77fcdee49c95590794963446e0c09dc19f12c7cc66367415ed557865382adda1d1a3c5932128f0f82ddc4b0838301d85ff571b80ddba7132cff54f3e7fc099ff4a67260a5f2c55f4abd45704fbfb3381a810f0ed42198f88c8502f06aa691fb2ba1bde8cd2394deafb07a637b7c41c5a8eab2b1f724076193349b9d08e1efb48262485c68d7df41844c0bd690d3307f88d62b3a37a818fdf4f4aab3da0bb9d511269235f59e6776ee4cb8974b414c55c873590793902458adb47c4010913dbf1ef4407db854390f33fd6516d10e1c1b51a36e2b7db661ce6be54063fda7bae08de1e5a7852e4acb190dde0f409d7771950d497b702b4421b9c625ee194e167035c0f2c7ac1c413e6722213314a8d20de1a17d682133bfd3246492ac0b6d13db2ad44121706f45c9d2eca50dbd88efc9efdb5d903c02551e2f7476fd7183da731552a3254425d5030abaef158921407738870c0e59a9500a7de11461756ff6fe1073cda5bf5f0b78f3aa6a13335bb4d0deaca6f8c3babaef787ba3d5f9de0cb2959ad37d4909f7fadb5183853707a86ac3f85d11faa3009ce4e8f2c4df51d31726b378d1dea2d1b7fed20f43efdeffe5dfdf71d40fc6b3a39b7868f2f2f64b3ef4d38c411abf21e21316702cca4a0573114d7a6647be8363ad2929302d3f20cf17dfcc39a58a14802500aeda61323c654865ddacbdef2554b398312630fe66f3f5b34181675077d7e0992def4041435f07c64c74111f17bb213e01ece77d72df80a5e4dcbbea1b3b8f2677eb490d5108c95b566a93cd48ae6f89df16fced17f04f16a9fde628d6efc179cd5909d0b16c043584161caac1f8babab43ee9293bfeeac2181da01cd5af483f32fdedb1b4a58839da208f508edd4afe325f7f3e120245deebcff8832a3dd5c41c6225a5ed391163994ba4087bc03f27a12ebf67936934fb200e6a08dbb7e2a56470068b9279df9ffafa5b01eebe4562a2f585b6fb8a4ab6ec0b2e7c8d4132898206430eda703b6f542333c1df0e5273c7fb2b8a625a82fb669fe1703930abf1b13e77e30dd09f1a5e34a4d5ef2eefe2a956abc59f00ad7c9e266ae63778497773801cb5e3f768966622153a57ba4c068f7aa62ae73d0dc4f36e76b83b682dad609d5d966bbad9deb286d9739fe9dd38c2ba6da95276b7f948b9fd73f8d897cf21712de7eab8a30d496314d57258855b88576f3858cafbabf4356c19cdb0bc04faede0b787ee0799bb5d08105d30cf2836b37586c2d0f59aa6ecf85ff1ddbc119dc5162906337e9d6c341e48d57b457be10ab2ae55229df52549a482d18ad27a5c8b25a7e4f5707e1a8b00f31f9481aba48fec4a09ef780c022c2920bcda590ed27df4d3ab6028d9f33e33235771dc7d13a417e47d4a1d84fe87845d2aaa77a954f3625d8089bad0be5bbd7f61df107a9ee6862ffe5b6c039785686209dd49b86f84a6c7b31ec4585868f3f46715cc7cd1694db6b3ca1bc92688edcfbe119d9fc4a1874b67d6df6605f3cad2f1ec20bb463bab0cd5b7d55b7fa2b44268936ae814e5d29d81217fd4c174b34c646c855e843893420f54a33cfedc2ca8804d2bcafc36d63298bdc5b1a7652def15e9054e3afc9359217d4af3d63643c583db416c96b96dbce822c419555f1eb492598cc9f4dfd022b0dc38fd262e86b2de2fb7d18eb6a154030660749e8399ed6250534a7e781097589af77c09eb00f0713f269b4db48b0d1a06e1076020c8c0ccb2b3f4504a9250339e591697b1dadb9e310fdb6df87e18ded74d30b3f04597d6af7e0ddc6cb08b7355750dba697c4c40b577e63cc2e32fa96589771a5511e321f37c1c0224213efcd95a52362bd8493a03e1a18bfc64fa247961fbe15bcbe490c6f6aafb309873f094a0bb479e5abd50387c4b497f61afc3610f88763c3baca5a37ee1465cbd4e44e02431b3fb217b026cc2c70e6978410bea648938a2d4f5d89200ec627cf4919fcbd5d72a02fea89a50c710832ceefd8e7132e6271fa087e6375e4c62bbd9916712d68d0ac6379da0545b68d0348455b4de5857c6b98290bdd78136359760e3ddfb56b9fa06e3a5f2bfc8e3c06ea7b74e1db9ffb6648bdd74bfb80b0a0a369dd891551037734b51456bb0e3422a52d5eedb3dfc36ae4c20e891d7d025dc31f24c9a7b71ca60c6adfecdfe01dacf58dd519bd8f9ad18c1b9ddaed6405752eaab3c0413a6b623fdb0733a65f70d596b17b7c597c91fed6c08d253b4ec97df1c0a7f5e0b7bb4c5114ce1874257707226d9da3f34cba065cb78748fb7fb57706c39e2bdefb8912f08b4213f96fcd74513954602ebf5a1d447f7d0b2a76fb28c268112f601459f420e3b8f4b53085a7dda08f48e4a1c8b1438721c675975ab6edf74a7661ca41a340dabc1f689aec7b10b87230ebfbe9b0a94abe69ca78c33af0ce6cdeacff0b166f6fd3dcb763bc4804ef7d0400147d0782cd215c11b541939b86dbd4746b34da9f3aacc5f14046c88b7050dc443751564a189ce58a5adf1355715bd3918a28c51eb6333daba927022fde1f63f1f26957b91df52e557835db1c2fc1c6e2eda378158959b83e7f5726502db2c55685e8afbb32ee2da1443a8bc2bf93c7d8449cb45ec67abd3be5dc73f1621a684f2522b7195c9c0ac7ff6c8d2752eb091052cfa078b591e28d758416bc7a161699214476ad16ad60b7f5c32db11402ed4ed08ae862cf451027675d01003bf1182a44b4133a3f89d961bcc8951caf0bc76461489ba3423dafc340159a3a53e49a82e460ee5fb1dd7dd3ac16ed822738bd8b084d80f201c3cd5ca537c507c57ce0f25cf9e0ecdf5270706c9bfca5366997f53b195d563848f35d807ee2ae2a784e99ea273f1072df38327a8c62220d14852c66490aebaefaf9e7b23acd86fc609af27e91c0d7d024b7f73411e0315ebe5daadf2c656c36a026f1964cbb022efe2610786c5ff00d081c3beafe2a4cdc4926d6cb781dc83e966a6e9908da1183c2625ad0a34252f0946388d26736bb0847f4355ae65edcbb3a2e549eecb191a45eb28fc81f6c9927e847281ab581cbf0c0d26713f78321a809f4e9ef56bc8bad3df9529c793337b98898467fc48e6362a1a992113f6a381aecf774b4f70840ea30379f745a112bc21ecf83fe0e692a2a4c7a00e4ec9182bd6d374c8023551dcfafa0d5b5d652d42fc29dabe075b912d1489632645b2f9be93acce2856074421c9202e04d7e79e5bea9eb6346d00cd87800b353d4924d597762d3e1cd9a9679a0be844e82be717fb7c0aeaf663c235fcc0198961aac87b6df6f369fead947670f2f5f30a816397528d52906156dd04b6b0b0f5bc8881fead69b7d097d0d159be2f344707a4701ac70fd249fa833b1ab6c902e4c0264d40470138cc0ee82830b87432a8584de07720d68dd820aac923347595dfd1ed6c57a1f1489740da773871b003d43662a05a71a5c0893b489e165e9ed16beab99bf33b8027a793dd91ef554ba53b03db27ee7b29a085ccd1409e5148bbf3038556e13492e5bf9af595b0cff2b33a1d51fb44fa7b72cf8ef77f8825598a968ad44c13dd414f8940281b18af9cb0cb4c8827f617c1f0a66a1facba57dc15ff49c7daabe15be0d6b8d7015f5c178e4d39532d00201f77a28b381eacf5adeeeac2f073fa72dad9afbb17abfb11215af06b986b841582bffaa5496d2debeb85c397971a56cdb88512ea46b50b4367e593154be605b3c4d3af9bbc2f57c71069ac3de82757f65cc308dc33cf0e54d37a8fdb22d1565860ed4c1ae2db03e164f0f6d8f3a1fdd8e181b145cb3c5146493a51106f74311765850def3f15b1dda96cc4b0df82565b0c02946423f37ae0f846b63c838a7e1dd894c8f93cd917f391dbe996cf1135365e6301ca407fae1a967f53e272dd049ad87d676b023ed27bec89f4d01a3fa14c70ade0bff385f3807261577488c51e6564c694f55869c0ae6b9998b4d62c91ef9d4326064024e0a468148ffa9d030ecba6148fccad4f5694f2859573024fa01b919c93842d8b2ed19abcdf25d1b94c08a1a45a65fcadab90904f77329501ffa04192ddecaea3f1129525b6e5c71f651de635a29a2cb09920df0d39deaa31ad26d1311c42fc8de8e6d65879fef7913c07e404bd5d3076b4e912fdb5ba1c5e1197d2ae28fec260625ebed6b917c5f47fee6a73cb4172fd1c031be86d3ccb7594dd0c40987a4e5e4a7eddb71d52adf09449666b06345a15f1527442346f366d1abe622c1089f5f2f35cf6f716c1c0120c81a4a4cf02d58e59da59b84bca52ae1460c537b2e5325fabbc9a173943d001d7ff37e1435b10723e435e7d9a59f4d1eaf6b4d33d32008a5ad4b37f0029fd444e054e79b2c76cfdf64ac51cad1b641eefad12ca48336c36cef3d6c524af7946f5dba16c840d305bb67a6c52b84121d81e3d517df147e9c55338d0b2a2d400b2630f741076ce0258ea6a122cca9ab36167b7ddce37844551c288df803ce8ba1437c7fce3a62491dfce1ab44dc69316804d4d73e990d01dfb2bd61855e240fec3738e92b526239adeddde28ad3d6c56ed1047e4b9307de654a23e32c3ea6a07a188809190c955cf8d903db4c46256caa39e973fba357675c162520643df3dd5dd6b06428c48fa885c44b33da7fac115ddfcddf1bd9e8af581ef5c9b2c6b9039313526429078dcfb2df4dcc1f88b7b04d63ab49225a19a15b9207e1478320d19232d35e972a630edd6cb3be44de42aed22708b9ca083eae17700edddfb357ed60cbd2024b16d70809de73126cfcfb3b4967dfb43b46d635a47e5f728e2f6d015ac267592e4d23971bc45a208f28cff7c3257f392ddf9e4c2d9ffc2cd673019cd513c6fc00ce6ca3ee64840e590b0522be56b98854495ed472af7dd3ebe007969a80f803d3a698ce5ebaf309fad7493c0ccff39af341ed784b9afce6358b2e7d561c3590272e75aedb0770bf9bfb78a5b0fde00e26f8bf64d869ae9e9ac3fe844857b609af827bc845763ca44c1326c82d8a3e126827431cc135e42746e72b691672f30939db08f99fba03fbbcd9b6a3f1e0a871608bdedcc61da14dabe670451eb472623b2d4db5d411b80a9aa6e13b3fe7423d90bbdde71a331c2d64c76cfbc67c381d6564ab3b7bada57d3279d76dd8351f3f4910d59b08a585c9be9711b54276391b6611e67c3de63040bb34c0f26a8819dd10f2c5667998da0c9941c94f9126aca80a137c7a2f564e55e3806078e039dc8f15d33f9797142194a00e3b06571521b2c4c92403440072fe837ba796d5f31b16659247d5e2a893df40cc96d6380fed889aae9d2fb5e3baf9c215140981fd885939708dc43a3505b929dda6f69472bbedbaf49cf83b4dfa96412b52ddda423d2605905f2aac35bc69d5076205c6b65c94762c0857d1edabd26b29abdaef8c510199d42a212e1ff514db28672e429388c457dd466011246e2a574336a8718246e0cfc2a546b9e357856271a0bb0c9201b4aec25859de4fe4c0856ff554086e08b12fb4eb09e6499088f88e166d6e64eec76c8d7b1e654ac352fe83fd0c16fa89718876aa89b786110b9ec54a5f7d896b9458f0356db54484e3a1146a9396f6679060666047b33bfe12028724f8237244f8fd24f93cca5f3e6a252b8c17c5839a5a1ccb8fd92bdc4d38ed7ee440943b50415c485403af45e479ef3b9bb556481c50502505c4272d1b4eea3fffc42734da32395ce47ced4e78747f8514e64720f8573b39ea29642cf991a1e4632bdf54c67adcf2379e52115d30342e8b3f77bbeffa2344cb2b5861631a56974a0f4537915f2e8c817d5cbbb7f007c09b02a785c9e3b155fcb101641ae62305c6465e2d1f2fc7028ebd729e329eb1b561790a20234456f1015d0f3ebacbdbe3f4cf3c60d62cda6cb7e38d4eb1dd936fd7fd8d0550b0e7beb5e48b7940c5a032c36a54525784c0470b0ff790fa8128d6b3bac66444b2876303ea988c36f94f165bcea7d48a44e6d638eaa9983d39439e4dfec62f69ebaf220589129a1ff0d4a824a75314e84960c0c6a50ad074186723e643c03e749a88b8408aab382806b01498f758b56e8589901b37c8d0800b9296991dca077494b12f481ee11c597e449171e2526a028ca2d464f6e73e7618a0270467f41b6c3f3a6839f80dc73c99f4508e418cb3a9ed418ff2116a0f01e2845a3c52b8463df40ca740490ca2d4d7beaccfbec1efd8f477505c11ab411665b1d8b8e378f362ef18a35ba1c4d0e7551b0adc7573f7e63bb66a0b4035144f367e28ec6e4d2a509e1311b77fddd7aa8977d6033d11979a008cef0c77e18c4d829896687e325be66da90df7591e5fb3628f8598fe1bb7384ae64befab9ccbc656011b014c0e8c85bdc1d808993f0c833e8bc1445bbc4218ccafe2030281436cb1f75756a57827baec9ba865345c461a0805b45be345f0bf19f5654d6e87c5258acd449d81ad32e3c1aba66a6559e110c531983bb3e1b57a238e54a3b450109adeb196f85786dae71c69247bc8217963c6baf8dbc56ba3dbf4aee57a303eb164cbfff83edc5448720375f041228d7622d573a6013675925333f34711a4477f44b01421f35cfc188fffebcae2314ac30f343c3b98fc8c05f2f35f6761530b736435bf3028a55fac2cc7933981bfc9ac0369102e0c218f0a1cd43c9c16bfcc112e57a2039a3db96427912afba17197d4ad2331774d813055ba8fcf097ac9c8f56beb3ae7182e3b4d819f1e3aed2072eee9f693a06ff41b7d2654b89d22d4626088a5295ff1131aadf359c421a972fcda963c0bb90f3df9d0d711f6698d14e11cb07a3939c5260c22ab3ea9228bace0b740c3cff7038b5f9ff5a16dd21b636424890604e326e6c822370852becd55d45193a3b2ac674317448eec4328bcc57a113f4e5a8cab0e111160dd2fb100a2a0a2421b098036c5657123e2913bce394c5ec56151ec912dfe842fd4e974601a7210c3f612d3f078dfc5f22580a0b52e0f5440c90592b623d15bec205c3233476fe7bddfc269739dd49ad92b1c6466c68a459930fb48eb4f3beb45084044bde45d6587fd9c046c46aff5aa25d5737a7084d8ede3d49034a1ed7b8e4c4913acbbd333a8294159e27edfc278dba1d024bfd8a985c1b12e2e87b6ea50e83680dae76697c65d0fe5a35c411689e38d377f865cff63f09fa6289c4b3646fe0dd7499dc6fbb5b72f2ec54f1a44418dd4285cc63f391d5389ca1af0bba5f0979b772193c551fd8cd28df8abebc1734e208120ec595055b9d44946f9c864c437b809d1624ee045f2393578fe74d0a8f03d6a046ae8265b17a6f4e83a93b0cad2a6f38302ff5f7f8f76b619e1479413a566279062c5ed918d232ac124d9c4b7208944b577f755099ab5fd1c1057707245f5b84b3a00a14c9351b360d0e43a10cccb49400c7dee1804a75c24fcd8a67e40a8301b9094117203ad9f94355f4c7eae6584e56de7ea4a24df6d90b0f2f84a611f68df1a5e4d269430aea37d65a3b5806bd6bfb1e094de3be53f7be22236142ab99b916d09550b132476ea5aebb0ca2a6800c21731fcf9e88021430694d0045f4d4f29de243b1d0fde94d2e8114fbd2bcbc37ba6252d990fa6376f4a2b41f05ea9efd174f0f438c4d47b49d1b1bc0ef5034dc270ac3c52eb9ec8f7957a89a5b77f1e5a380bc59cfcf90771e5b1296d5d4785b01fe749c346e35f1c74ced0bdc9794fcfbc480eb409d677ee986f997f3e14032d102b09c50eba38fee158d3d0d1ec1b72e9d054ae97ad0e89191f025b63c6fe23c4f5493d274ab5da481192b9b4add18416bf37719096b0e3a3183300ef24d920bfed4796b7b4e52f514a4cad09d9262c08d843dc7ff73aceaa5624d53bf4e6a94d18bbf97b83dbef719c87ac44583ce13ceb6d86b1e95f789dec6ec0940a5d386d2f6996040331c73a0f8744d670744fa7f9111b5735aed4b5632aacac0cabbc57443e90e8ecab7f29d8d34ea9bafd21510e88e1cc9196317491e16735f0744dafa5aec0a5f287e23a470ffc7f9c0117c7b5c308a2231adbf304715403b4901711741e7fff2246132823a13e255e5b6f983e5513b18232f792d1388843e8293681e339f9df148516a161f8c718fdc87a0710fda8455e9b15fd5e5d5cdd507ec0724ff0095ff91fa2e58f734f1a5053891ad4652efe9f8f7c6bc59c400a48c79ebfd1410c6ba6dccf752ed68e4ed61a6fc40248bfa377be32a9fc17fce0970c3621267bb982618029066882223e6755997e4bd48b1e719e573ee8e3ac65c8337e3a65804ad7749bd528e044027bae4992873c94304fcc43863f9b2ed361f207d104e9d6e16f9306897fee13329794133bf8e1261d6fcfae98ccc041786df9aed0d7a05783ae1fb09f9a6ee8b4001470770d392111c30245888384aa5aa3cbc6dcb0badf7a4f7c416c5579c40a2032433833287c4946f08e2d8d950b6703ff804b88b634e8720cc8a08f3eb142e0753308a2b94647942948fd4828a0aa86abd567524574b262039d8b3911252fde6dc07309bb9bf00363886d5b8bac9f1fb140bfd6ff9dfced9452a00390450a61ea15d4b112932f420a02d7108f276245614fc4360e1bca83a5744ad0a820706226fcc58c3a602794e1d8751e1c4b87fc3c300910220382c9c31db53647234e2f7429349a828f2485bc9645d5e8fec434a94a95bdd8c0410c0fe641f3ebb7d2b7e84910b9af8bacb31c805b4ca6d9ac0cd9a8a731880cde4a4aa36e7db0682e85910f8bd9eed3674324ce2cf039b8c1e9f881770009fa1b763a30a4a1cea5c751e737f577fc4454c2f15d6d7ae2ede673212ea1db804b40fea3040d24693edad355b70adb13efc2f3b6ddd8d92645ff5eb823317a2dae67cef7b73c787ee116acbcb651e91eacbaeda9ff355666bb8211b2a58e75b5c6840ec4109b049cb4de84e65b5df6d46230008b7c306e4c7cf5fe6c7efce4d3b53f1f0379573d9ef021ce3c925370e745e07fe09ec0b5eee5e965d20aaf84024471619f18a6c2694f6b1f89237a21745967649d4bf6d6adc20d5e19f52799212e2496806f471e0245eb5af438be9a3945cb07b31150950717d27a9f83e8dcdce0b913f3f8098203d7d519a59cfe141b65e307fa46ecd3bf96375c04a0d2f7500987c0bc1c413d5722f3efd37f6233f2c6dd88d59c7f1d63ac07f85fb2a81313f9ffff52388fe5b95838b752a6706a59c623f3b15a395eab5557808e07b8324e370493edc3aa082f47461aae8961d19c693ccc8f827703a7952d30cdbc3bf9fd4972a41290c0babf2be0f6a7f8b2296dbf8e9cdc96ca4bb90acf4f287f4e47107a95a1a80acca7e1c21b9335a3e86bc731d1ca809e5b0f301ede8fbea8a3ef434da8d6662ca99aa000d1a08e29af669aac2eadd6fc702fafddba27f4adfce95c1f49654c954db21fd7dbe6f7349780799025084bf806289e63c2fae3d83e4dcbc86a8cdb8d999968b12eeae9dfaad5b9cc6cee5756921bd3a4337c0f4ee67a1b781e903f43935a45209baf96aa513892b7f4d8b320288a489d1b53269fa4768b2695a431d2e204ab097a03b0db672ad8cbb10e305ed7395b7ba07b3702606cc905d97a51753990eeb70a3828ff14730f1cf583075a9808c3c378e3619982fcdbd2ba041e6b256e4293fca8bd4456d31b2f015b15631123e8a74b02e88bebb12edce4bf3d13045c2870a3249b441477a8d4b320ba1c0a8202d364d58202832dc093be286a456be351f2b4946eb8f113338dddb70e36fee348895edc73b97d3966a095b9ac4fd682dba33cb258f035cdef7c5349eabc3636fcdea803f8b5d709bcedbb33cca0d667f363e9124c0a8d91d8d118ca56b3d3bd72fd1bec480ee589b6a45b25654c68a85e1181f77e2579bf5ea259784b25ac6bf2f108425de4066bce2e8d499b569e4ee06a1b192fc9309bf3ed2f9671db763816910a8f87a5ae3b017415d1467537ff5cc127c1577e6a1a5cc241e46094e5177f5e72e5720dd82968ce861eff03d1e8fe0742bb0a655a1f17b0b3ca7322abc97ed1873b5c0b08d2986daef1a606c19b9aa36fdd0c28304be16ece3d9962f12ce79502b74cb70d64d164c293fc83db0fbae4e89fad76fb4f0b16f31dc918e6322b70d33786c0eff6a4f05d05f8c2a35e9ed0a48471ea68f4ec7990f59cb81c76f36f30a5d4847eb54c3c4c9503f9b35887b405b9731f376bb4cdaa0b13d64c32ed6ef898bc7fcfde1b05b4385a2c5327d7a34007f3813311b16ec758ff2a5b749db5ba64b1cbdd6094df5234227d2fbefc76e7749cadb67a5e1a5e0a950e1fee4be0d24138db5d68c6964c25f1159fe725c2ec262e93b293b1b2ab7ceeb04d475deb23d818efd38c0cba6c50a32d54fed471335f2c06c56415c3a74fb0b856a72250977de3204d032e79a00521efff17fe7606fc824341df2a9da55c3d01cf94cde1f00d4b32e071f3a8fe7e3e516e9e3b4e5901a8c63d7740adc1b0672e7f202470d7ce8c91f9b956720dc47d775cecc7e7133243b22f61e38a723382bc6a0e92c6a892218f9858206f44920a47bc0dff4d036695ec92e7c97435ac855dbb66ef359c5cdbd89b1fc595c000c667fec85ee358f86ef6379b67399fc006d2a6aeeb8d9f83677df3964f1d1621696ecf91501d1c4f2a18285e89bc843eb14707dbbb4e052475005d357e73dc3a1b23d9742991bb28d38352131e7d6e8e21a444f0a6f85b8d36ed1b75654915e3b3ba0f3fc346a4bac5cbda193e0d627c3ad07c4272dbaa0cd2d9815dee1bed885725943fb443c4bc932c18e45e05b102accffaf57969ac3238a8f4ef2ad11e5aa97a5b147c9bd854fb4596bd0e59286b595aa911a2023dd4ffdda22f3bc783e418c763c6f7c795342b948b38aa37501965ae73c5f828456d41300bf5b178192d1753f7d6a48a8e4a9957d21d2571f662520a328cee7bab31a2279d3358986c16657eca41fa761c5c618a2541e48ca7b8812285cee9290ce520189003f779da83abfd4791ae098895ee4b8a251eec5f9390ceed2a1a14a533901270b72faeb4d85eb9ba2012e1cddb22395afd02444424426cb36544e3f0072ae1ae9f93b15a993f3aa3cb62b317e5a7e3e3d22317ff7206619987d3fa0b372907aa01b8269ded23faac2300148718c569259ede66fb5c9495604ebd19cd6f9ac20e4f9527dd55723f869830aeba2094563654681b15309f3443dc5ee7ca3b74357120118b0f56155c522938e216edd1fe6339e0906bf7d03ee560f1016822ecc6195df918a0037798ee4facb63651ace0e6cd6629fe9519529ad6c1f36c3d6e4d0c3b0f2fc1c6f96f96b6f2203428354af7cb5322df59089c9da2ba17356cb3678808fccca36833b1541508de32e23bea592190b1ff7f1e6f9fbda005e4ccc1836e90dc9d3c3ee4ca8f56acc0c71f9c8a2b873516d04ab8a20b726463fc9ea3e72041e9cffb29a8bf848f24e4f52aef1146c61317254942aa1cb8c6da37344115e5a41002987a4fbca848efb40572de7562380f64b57b835b61e9895d110b224c6ab674fe109c06634f7b8db5f25c79d726f84b8f14e88d14ca93a6a80deb7a6ff1e21a99e64d04721b43f131c8428196ca7baae509b8b640bfaab701737f9e35845da20aca8e6b3587af0d80ac44967f522188a10e6c477b3b43b255c33fce69490512e4a099c16f83eb8e35c340fa38b9b6c8aab6b302febb91b8afc9f8e66da7bb2d3da0b5a30f3606f7fbda22b586c5ef5a04d2483bbfd6362303f0dfe59b41459c7455ae28709b5fe117f178503123c040e90d931b19bca110696ed6fc883a808f932d0de3ff23e60e634f37226f631834023427981951141f9ce47490365a9b0412d55016e0c2aac11244d776c63415d05ae571257fb75dadff4100891755090b48c130c789155c6f258b48b91d79dfb62befc5532ff20256b1ab956ccca6c8caf47e6edc0938ced0f7d65f8c293cf6ad66a4d32d992f63144b8153641b917d933d12a7dc69188bcd1c5ff84bbead82ec3c097820dad52e524ea995e5a64f9f2a5ab7ed45008d175ef1751ade108c09b31b99d2695433665f9d7353d16c30218217b066937bc4db11a1f76ca62c56b350d7591559222c1124606ef13ebc531c69aba69008ff03608b330debe69fc54975b087dfd6481e6e7bc7c0d2870349be0f89014b705aa2b637a727c69bca98da46b811d92cc068d304c7f00e29c517c7a91ca0a2f9381e9dad40fd7ddcaabe8016005b182e4595aa56fb5b9292476e8ed6db0887dd9376f06d6af9e3ab97cefe22d1847bc3ab8d7dc242ffe7caf44b42823510c7954daf880600af7b51d9382d49c11948bd67e216d97bd90c1c3d8db092230b06f79cb01147a7bcde24a84faf07d8049aaace2e84ba3c4c88f21a15b227841765dfe6e5474de5f426e6a02584f0eb0234d2ae41eb04e0af4844eec294f867b0f92f90caeb453ddb778c311a66475577ec919a6d352b9ef37e1ea746624dfe8087fc0dd4cafa664c09f2fd7ad6bce15fcfc4c09a514363ef6e73b751583ba54a0ab548b6f51d0f788a80fb4f05acc549921575f262f0c0213c497c06db335d6fbc8b579c677c44248028862b85ab80b9d484d8138800de43605427ab9d68e4ec629a36d46a7ff3dd87de27d542337ebb2dc54c2de083479792a7b505f52b23ef8486f2a1c5cc763c4fb78a837456bffd448ee7905a0c02d37e1737bdecf9e2865e3cbac53452a3c8f2090d2c53c8b0ed24d2c8cb057ebafdfb60c7182e2757028e8c7bf2484727022cb78115ef14ecc481f55d443d887f3dfde390a6918f71b126ffa93771378e088265b141df6535e09ccc60766fcab5e6328d70f64185273d31b70a72aaded2fa6b1e31c5b30e23cf6571f143440472b1baecf379382d733580a7955f0eca21d120bf3b934c8c807aed743005831ea1eb85f68b8b641344beb037521dc77d269176815d3e3023ccf1584ec32458d20ceaf7e3a7403427820b5fa40a3fe0451e4849c3837714e5ca6b31d9c883ceccba03a61b23e4f4ef5320b3232b57b30ef795b7f23b3fb30da6b3499a04652f399d55f4a8b5c1439ccb6a70f19f89da62e659f48bcd49b49d3b8bdda2b0afd97376ed676e11a7b0010ebd80fadb880b22763ffabf15d1d5b1924077a1e727df9c89fa24a6772c98a0e0713303df9d72f40a16a911368a944a6704a999d6707107910f0eef08add0852ed12a6c1dbdba53a7c61035fee1fc3a0e26a8b0e58fc62031d80472ae45037cc2ce28de6c41953368e4b78e9f91a0d566a3de5e6b515aa96362ba36e4bf84b9bf7db9eb6e5f23b696eda825ad1dd37e6d7676df86fb9a2db341e15748f35e596c58234d61199d7d11b336201a394ebe7eedc4c4adb55ac37e641e24807feeaffae1b24286ea861146b42aa8f52e68f7767990dfcad9034f7a874f7d48023e82e9951c85886293bf61cb23d758ed90e78fd4224a1f9899147abf1c429e523a3f45ee1c2db03864c501d1a98964c2746d92c7cd61d51c3a1fc70407266a3776d4e39bee99b421d420d597e35eb936fe7a88b30b8511a4960ea96dd86743bab4f8aa824a3be6bf4773031e061ec4fa17bb693436dd0b3b2070346038e66728f95f1c66d766bedace69c3e1aedba35e022302fea4efcdaa344209dd0c5b5a36f3072dfcdff57d27e46896beda58a16b4cc22148ac06e8ba2e3112b7a317e6ca7bc2e0b5962b360e02ac9437472bc723bea27db52c7b992f933071898e0074cb33497ed272a563534a4373a8f89b461725d64bcfdbc8a3651a838295b846970b91da1216b8d892a9d5bab71e6f4ab86d681364b264910b81a5f270b2eafb0d9defff00d7da792284f601f18c5b2fd567c93ddf7437b6dea13fdd9a25d2713546bc9293d1be9e2060983320a82b5c88c3e3d30f1cab5ab5c45314b763b64ed8944455f13b59edb92d754ad4d3f7027bec6f9707a4a4ddf5f6232c4439c5360e584fe725b0e9dc03ecebb026291a02f09ed1867e4909c67b918f356ed3474b9f58339b40975cabff29902f30fb0a130dd370b13969aa6246ac05c74dffca5436c97eaeef9f1250b11ae0126abbbc65d22af875d5a9dea9a20244b98ee263acd9902e8fac799db9b991170f04c13f868087760e792e10313a17760f9f6b51c31eab078b7f4baf2e047ba5ca306e952121c4c3020ecc11613cdfab36a8a31683d760202c8950ea881f6e7f6446ada12e94a28689be4433e151a5cea5534c05120a556dde163ee25eb30d1874aa8803171a7e3b7213b9093435f1f89f2024f1a9ccd924bfc861007bd1229f3946f596f2080103187f0374f96cb2f567b267fd7dc0009612dd97614e7793c420f5c21f8fdf556f520a33fdd065ef32250b1be289068dc68bfd55479d7451b3c6571a1b9dbdf2c5e630cadf9ac715d26e60a23596de78e58948afdfe366e0b80d466fbd2deebfcecd9f5e3d1a845d0d1ba5cb2605d7ac326a34f63c3321b1d35525c82b4cc4b633e07d61dda5a36f4ee64e096f5d501c64bc97b2dee5eabf18d786bbaf3aba9fc110fd2023c3a4c5f47c8c578a548916fbc17142371238a58a3675817b2627b22a472706f941bf0047f34191a01af747bd9a2287ae272544dba99434871a631ee76e36ffc8a1846242d116a4a7a98b7754438bda1b4cf5cefc10d248a6a98873e374ba9952ef094adccc0570e243da31f2963f683248411fa971da1ffc10f28c813f4f643ecd3810b98e48f8c9ca8da9dcfd8794f4777e048645e3f7a434dd7a9fe91e49ff982a0f4b0bce7957705b18e9c29aa434def64028a83876da5fe3426fd6a9799fa7d90b4c933446dbc9fb8765a5fbc5c5603dc0371cd4048d1e5c4e0debd9316ddeb7ed9d1b96367bd18d4a9d27f522f816c4b0029005ee638a733caa12031e86a3af4f81acffcbc6c6e5f59281a4e6d3a8f5385b1dd5d21198f3cc4e29c2dc8bf6f018e621c192ec08ebbfd65fa40ab575720fa9888567e407c278fe77e1fa5bf7c01ad7809f6edbe23d0af9b62eadd5f35b5b3d9c528272b74197902ba2b3178078647ba716e3eae44a870088c34b5568010c92d67a45297043542f77ac6c11395e7aacb43a30f5a4094acdd0db167fe5629fa0ed9713f60554453641be5cf9bb8520e3782a332e32f0e61ad463e8503368c7d60b669e0f8993784af40e69dfc29720172035b2f513bebb52e993141929124cc13c35597864cfb613e2689a3a38ab085c28314900f8fc62c1fccf259bda882fe462ba774fcb70453130db7fc1e36b69f215997f47e1bb085843977aa5b136c85c5407af223b56511fa21531bf781b6fcc3e814e9180885b6c05448a23fc6efeb30003738b517b5e9df696bd3e7c0d1f6b4e7c1f73a12ce75d0f4c971ddaee536725b70c96f695b2249a316cd34efbbb7df02260b9971c4aff2bd0d8b696d5504c33c05768abd043d013dc58bae83473c44cc1200e464fe2feb1300d3f6631ae868b55198e2e61dadfa5a8fb9464140328952f6a6d4e3adb74f2f95be80f3d9b1e84c6a3bb43f259d5cfd6e2ad7925601ee7e3876417f2042f2ab688cdb9b2b2d0a8a42bb628961c8ad2882373fc9c25b7a9b4bdf2b7c9eea8951dbee68988eb30347387eabc9b4b13a78bf8d6a933ed4928b8ad1531965748107031d5bcca532025a59180ee0785775cf5a3f880b5aad59526b3042cbba182cba31ca328c6d4c2be1bbfe392416ddb00f88afaa8954130a439f7101753256dd7c37e43be1090c0fe92da61b7650681c5b43a80f219879a296d0804ed19b8f6e98fc0443123b27d060cb0f4ed25e71f2b9a7666d890568e48323eca9b8592dc54657a3d07ba48c107c0d9f747905bb176a7d140228db8549d1e760900b2a50fd787333bc7633d5fbfa6a0a8a18d76df6b88f70c848a67e7c27354016dac1c68adfa035423df9583bc41956053abd9c00b7b8dd995879d5decb23acb81037b80f1d47cdffaf69d8a87a4fa260bbba9c2f4b6d81dc6fdd12753a6d40c8cfeaefb57f2035eaeeb3e653b4515936283034990827ca02089eed30cffc26eedc546bd23b7fb1ac6e00318b9d37eaea3853eaa348cd4487e8e3993cb70a4c54ac939e10db46ecc65729fc54947f11b9c6188c543a47fe14361e44926db55b6623dcf7d614495d2cd0fad5d0bba3691ceced28a763140a0ff1e98d213a09103cacaf0a89fdf00290dcfea0615c3d5136644caf3e0a6da879189941070bc984d2763663c0c85a2caee8ca981c34acc8be172004a96ccdbf81d70061dc618fd3ac2455da409a81f7d08c4795c4b53038e427dd386ae0a9bf1ccf54f40cee0e620b54e5fbfda8dac09a3a23a8b43f94246ce74af7eb47d79a6bc095fb27f31a945057c2ac50ca4358fc41f02add6263f7e518421ef5d395f512620cb1e610aac0ecd0bfa1fa32d861472f004157a3476ff60e80fc084b5f9f1d41d8dad5a4d88bb0e9420a6dc2cff69bf12fefccd341ee1b679efc9e7cac4c011ebe71b3a51548ea6b73bb60d0b9f2d17c26176252cd6b5caf0e41d7a13145e664d11d6af559893a9c1675bbe129b0f2f2461ddd0524edcee95f24ca80470c55834236774c22eec34620b2f1f9c84f1e7229080f082cbbeb3658290d0ea87d9a3341baa18f5235b5f6aa613688282a50a355fcb490604f5444a9f4823f375e18845e18edbc1c349be2d769e5893b5ebfdb9e28f1dc29fe4b07b2471b7c95a6b75771c0fec8ea9c7581117590fcd1e79c906143def659a1ea28bdedd37b04af86db1909be5a3648356f56327bbd6476b0a3aeabe2c784e6c9e2c707f983030dcf60f2446401e02f1f2f4fd369bfb3aaf47a48aa0fb77262bbd07017e62796a2063a15261c1e8241c2c4723ec3ed8f21f34f06c6151eba2fcead3ed3962368d5ec4a1eee47def8eea006df53e87869b5911cd65b01044bfaa4e3383b35c1f40421a1a3534a0c3a66c196159577d529cfd01f9540152904adafda538f0689daef23b860880f24f965278e82b796d75010aad83f9c60f76ebf48c19d75f51c5fed724ad0f08389cd944e71ad3177fcf79c7542f21b2ff167bb422263dca057def3e67fefb9a9e3b2aaebda8c432d906aed0d323e572ca558a8d8069b2d1dfd569e3414655f69633ae6727555ebf91c16970aa7dd11953441b7edfded1a8aa8aa0a249232396a9fb4f50528a8e3fef4c65fe281172fc573089c558cdebf578750e31540af63945cc166aa97ace27aad05a3216aee3639cf5ce79ea567cc153dcc059edb9239b89de142fb996552b1f685ac2ad9612cb7530f4a5619835112571117b2c52a0d423710de0a6d300184e16237f6a49907a2d2e2faf4b0e6fb4f4c2557706c46b8d84274eb44dd4e120efc5ed8c012185d6a80021c6f3775ccdfc7388f896b7cdc101f05ec4a422381f55a9e9d8f18a9997d12bccd44711b8055c328aa3a5229317af1d8d8f1dffa7d6747c09dd5b0370de38521d10e2a70a29308a1b907831e638965d59be8f6a8346a4e70a0cf85fd57817c62dc91435d29f7f984a95070f46e94a9e078dd902c82b475d8c34f642b3d4e8440a6059a123d9680c660f7b5ebff03f01ca1d1979d3e5c0f35e41da216df0078207134a33d9bbb51451c9d49e7433273b4895bc15c35ec15179287c38dda2b525ef62f099767684f2a4ebc4a6e8f578c1d0f0c21a4462b403d6f207423283346c1cad8912f5ab7774ba9485b7960fdf14fedcb960e47ce2f0485e07a75c30ad316d525de36895f23fdb3526eff517364f8d86a8823fb931983f453114ea01e1960ab452abe861b0e1401ec4fef30ee769bc55e8efbe59cadbb3bccd6b097cd306e4f3c584dde92d845ad96618adb8b93ef673b8591c59079041a293649a5cc531dbcf340445a4dcd52f16b47346b009857cbb79cbed4079e854cc2ce1bcf72d02652d84ebb01cf5b472f619a6ed31b8bb6e4e772bebda2fc725326e8baba2c9c488141a6054a4c3e8565794753af9a76f866d6830c06f88022018854914b76db6891e27d78062810164ae381ae27d0d42aed95b3b85d2a9d251877f6a6ab202b3d03afd1b9fdc5d291b0a70120cd378e742c3af057ffe3f8842cad9da2511f8a582e5801ea032f311645e0ae5b1bfb5875b93d0beb05fddf9f8f19f5edc024db9f483ff1d806eb4fb65922afb37ec582cb2f5ff005e36c6c3f86c03fb619124755737cf58d08d2a8efb06567474e7e5da5e78519ed438ed4a790942008a96a5c69f73adc013bf30c2b236ae826152a627285eb343d444f8beb962e075c0a17a71aa513b7f46e405ccc0eb2853e00116418788f5c588f7bb63c5a4a646634789141057a4bd87cb075babe6633e628d1ea10278dec7eb9fd9c5812225aeafcb1746e651ba700a65fd4299b0f449af43f5416377715c80dedb001744fc43e54ba5db7e538d934ad69bac7183865df38b1ff39b74d616c6fec4a1e1affdbf5697ffb30505942600b44cd02f713ac492818ade33013fef972675709ea85c324981e382d39c27489b98d1ed3fb1328c02c2477a2bbe762591951e93b495f2e43a77a624e0205c43f4d2e8421415494e0a793a2f63e59b7fe85edc0ffb719383e47695918fd418996ed3eb7c8949b103baaffe5bc655aa809afc7f3547549fe9e26006a3d4225fee93635f33ee05b59a5e183944fc2ca25f5f697ef25428beb97fd0337807a26ea5a97d8bec1aa13d17e7f557e5dedda7042fa6bb84b5034f2dd462da967b89eb5b7869ce453a3158bf139419d8ea8c60326c83f6322c05bbf6bca5729125161ed1c513372f71b6fd045c27fde1b81000bdb66891f1d543c976766edd36bd45ee55521f62010de9ac8dc34b9c70b7b3d18fee0d031a2ac9a4b2068fab2e190f37c6f0bfe124f966fa353308f426c8c1cb27bf2e6886c8e41960655288c0b4234209c4b05137114ff1a5119bf485b93e4a7dd87e874f91e88ff45d6009ae0a298b7063b52f36c6bf01ce7f842a84a301d40c44657bd10d479eebe5b62b165b849ba86014f9ae6670d80df1c5b2f7202b5d1ec5eb47e8e71228e8095e58dced06b1a289315231fa920d288123ef2be3b84407598f6a00cca4292601759cd60d2f0ae7c535a32a04dcbd376791e66a6c8678dfe594595bb6f7324f6861d56c47a3992a19e5fbd12047af195f1d7c9019ae2fab0218f773934e20152d87c792b0754e8739589164c6d7306367df9f03538a6b11852d009f7620672dafae112dc8009f983070bfa125f631b26d3797c16e45aed3d21d2998ff42de71196fd530d001be8528142fc6f9802fd98f66393f0c52f598196344d53cada921b3c81fcca495251b0d5877e54509e7c4dcf3aa74c0e743c5ba9b45a70c3817ddbe045001fa3f779c288b3345b0e46b666b5ef38f93ad65f5b6ae40f3382bdf5ade51fdc23af904dd3087f4fc6e4c850360cd78968cfc55a607b17cd6dd656facc9246e5123400652e755d1389d54fb9bcd69662b330e9aa3e56cef3d585f5fde7649f8572e99b4900f0ec1f8c19d9ade20d13ebfb9cb34c372ef1f486ca0fee1e6a3c5722134734d5317179872f2daa0d7ab4169a0e2fc532f4e1ee705ee8e790232871006a118909b132d9841b6ce2d6195ea79e03d66d42525dedff5238c318e434fe55ebe4917c9bd75c6a2dec67b28fe015099e5589455fea3fdd2b3dfe83f0c2a899f986a6923c2724732b3c761657c27fa97ac26d22df8f298fd06b73b86c2b1478dbd04fda8119081a45f81449d8935d3849da35c4af85ba6e4625a5523155d3a768f2359f7577cef0b5e304df3816322a5e531f0a9234ec298c40e304e40d076331cf3ea18b409781ab2561b328b4e072c25b9b57c74e14120eda044ba31c3dbbe1084914f38951b3cf9475c21dc52def7f7efa81a454a3518c416b2ebf24417d938127d0507fcc948e036740004c01b33313093df0c2940f45e0511a27aac97b811d4babdba3ae386a99349a93b9e3c0fc3b2a60fec374d47afacb65baad9a57d0ea284b625da5beb4fb7fb4a41afa9f360c617c679a76fc3a800a1530894b60894125d63d4187371ece8e019bb4d6f96e8c155577d170c9f6258bb6667578711574b26637f07afff8538d323a630ae22adc9bd61ace346ac4df961df10af360869546367811ca029b6826fdc5097ad891bf3363f372eb18bcf3bb59aafaaf1542e88dd48650b2931f77c8acc71468a42c472806a61f29630887d11f416f436f1831c0aab8dd8b38774074d80828c8b29ddbbefce6f17d3d2ef2dc5cdcdaec0da822a55f06d1fc468f94a34da3da17f86cefdefef0dabcf2efd0ad339ab4b3008462371c52ec24b1427bd698e72a4bd7fbfbfcd129222fd91dab8d541b39f46060603c22fdbfdccba9cf98723caf9bde56c7e1d04b7bd3f9af96b3e89dd98b6ef3a093b94b71fe009f0b371a44abb358c486e60c36944c705b763d469348ad046c0b82d127a542e2aeff3107dd2e328419fe0102e670418e82c1bf8c88f8533d14381a19fa0bd078835b0fb27699590c1ccbf02ff1b8f3e6e76da931f15f2e5c7a1fc39ac8eee9bee815a4564442ef5a9404c53ca78493e8d793df007d467b255b480bcdfa65ed784f72ee7f364b34bcb65e25d3e3533a6f3a09d63fb8269945c51921110ec109c08d28a99a87a47489892277a40abe9b90a701f9927e800d9f823161886e094970bb1d7e233f7c14ac74182a995511ccbf466c77e5789a0529c076053ba733b5eec882b72cf8c48541bccf5981a7b55899cb1094d034abe7d29e2edb454c7e15108690c5e39354ad6eaade36254de0f97a03848876bca21a59f3f83113a40160dadd59c8142199476e26231ade092fe8d60adca793dd797ac389255efa3df745340934844a283279d1332b07af2e3adc82310cc8d42d3d2b2c90799090c0fc141b022b1f4ec40301879f47af6e4e5eadd6fe76aacaac9a0c7bc836ecd8de40ab87e2fd646bfb153df1f51e53fc432511a7b2c07a5978b34e161640af9d879635888bb9419b6e5bab493e2428ba97795e0ab999460569b310f3d605052125e60dde6f33f561d634ad91263a6571d74a71c6464a1ad10b887a76df36cefe8f1d681101f2f99235acb664abf7e45027db1a566f5ac1b4a1403709a0f182ae14e8e036f626210769a3d3578d970268899410730ab8a93b5e4d27316ca5f9b7e6f32bae562ddd3a2d7ec341e129f416a7ff5bb02ffc5a8ac8e94d2159364e1f811979f8e57dbf4e7f24f11c44186d33eca428f601bda3697ed2b81af9e95d5a0e7d3f8a4b8b2679345ee767ad78a3df87059785a222eebba750f4ab0051cab9494504d6f1cd0dca7d75385c11a92002c1f07f3c3703ad5a5140c1194311536944cbb4d33210b158e3beadad26bf120f0fbb143d35b693a9029e5e783d7beec5492a823037e1c774d991c27650f1645ecd57b8b88d3d8df0f435d9136e27d5aeca892ec86053f006f3abfa5831e6545791e9ac1ae09aa2cbeb89b53fc430645381d9cfb7c751d361623e54bfa581bbfd07f82210653e5402de1b0f63bca0b10822e4c161067364f1a035326d97bc235ff4087b308c7b39dd6d88d9de67dcbcd9b59e22a3bf79d65a859c14cb8d0fdc1e7c9348d57f67b7c57db9e51001144f68022885dbc15a23f0566bec689410a5e6708bc80ee043edaf9c1e9794aba3cf870eee0687836e80dd09142d39c11854edb10ec1c4a6123e6cc3ca825cae41097fab5d5749435078c861342667fc7dc951f54cb55ec88258052ca043219bd16f61b954882a9286ddd74b148f342efcc717c2d683b9631fda2ecb27d13a1dbfd14f0747593e5c02bc4ffa99ec05bab7046efd69ebb4eb09f5a3bf79e67a0847649af0bcd8ba4638fa4cae1641885b6c9474f1c43b4edb13ce1bc288bc126f026207d454668e09ed8e813f3dd535496b9301af9b0f2ed1cadee355b1f07a6354358641fcf802b2edbf5af8fd5c7e63910f3edf37116477c4c87fd66de1447ebb03d1f772abbf7d35506f77b101f66bf89ec524f42fb046a1fabb0b8c1e2e0cb52077646eab1699545213b50121a9f5df8e4d39197aa64dd2343bd29b67129bb892b3111926433bd0db91c8074dedfa2b160bdf6d2691a5d9f108751799781ab36c4b0c161571f0785b82fa2542ebbaa09fb6a792b37eddef1c3ce3f3083092e372202c76fa8e8e01e7484d42ddcd652bfd2591ad532a8d7926c5a9208824001fafbd0fba6d2999eb2cc3791dd917759985383009d9d3d34fee82c9dc4465edb9ba12a63bda574ba79e431bf98afe32ee66d99922ff66d5b19e0e993a04d0c3e98c57dc96943ae579cc47eeaaea522e8d816ebe5a5e73bdb626450d433b748ac4194753c68740df1ec0f47acc3bf532a2587729b1707c22abb060f1eb57fbc6af5cbae77b4b6788cad62f0fafb383e0920137d218b86dfdef16b2f34c623ae0c541012a2ef088d238f17d5cba93757c17e73d80c8f7df2934965a391d9af64074e6d2cb375bd4bf5df09e807a4e9ad3aa6c11fc56ea8c63f9ed3af7ae90666ae2a58e5272e12e728f3b9acdbb1bf0b862d31c05c31866d238fa709add229148bd62852e59464dfd560a58d3f92523385b632d82931dec0f43d516322d94791ea3225551c0ef51cb1fa113c2c544429629e75f6747af7fd977e479eec422c51add767d5d1748d4de04d698745a6d85927a08c57bfd5d3e25783876427d3d09e8505611b42e3d016ec59a3d1b6e02bb19edf87d30744e6eb70a497bb6c9d13bbb70df347f8a5d6f017ffba98ad7eb1a8695cf3dd3618e9c195b5d55786a195c8dbb3dc6a593646ab9aa55e2bd6615e271b63f4140a921fbf432f00461d7cb0afb2058e3f187c27c6957e52018e006d71704e636b58e2b5f5c3328673ea98e6edb11ec74501e977e8e40a7102134c00e5070b53940faf663f5155e0fcde593b8f51c177babca70a9a7b3c8432e2066c275aa5d9abc1d57f6a946e1540a4ba046319bc8c747ae8efc3d35fc43b915ce598025e870d17b6a54a8cf61cb43a59420b77479a196211c274a10c32ef21901ef7c04956aa286a2b27601ea2199660833d7129aca9a8b076418970407cb309ddd8f98fc641848b84a5b0379fac4fc5bbe8cdcc7f4b23ba3245b21c6dd4a9e0f40a250f2bd93e08dda4916ad870e8897585688093df57d27b4572a43d8c9a0d60b889895ea08de491005d3a9765773517454988fb7e245ec768ea317fa7cdfbfa67cf9a13db86fb0f9e9fc5ccac4fbbb4b2909f502d1b06d7dc96a2ca4f20e7d98e0c64e412c830d38929a4c0ae0eb056496cf12b11156b50cfecfa095c921e78d296158dac0b4fcd204e249437f4c807ab7246209dc54412aa7bad67ff0b5c729f39d274cd6d87f3238a8cca5ea5afbeacbecae348555e74c923caab7e96775227843544ae917b2bea9e0e26c88446a5c217577bcbe6b9064166e965048038801edaffdfb4a8b39b457b96ec7d4ed1bb3447c5a611bd211a529c31eacfd6638be109e652390ca0dc8f7f9fc5a59515a40a3ff11c504c39c0bed76004b63841c9b4f9702b4ba3de404d55b2e9dcdf35bf36b8ce6af95b7c3739c1b0258f26d12ec2926d78fe1a062b1afe64f4fff7afd278287fc7c502a538a6e9edb7cacea88622a40ddde54873a66d1caa13af854507760a19d40157a9bc6d2d00fc09dd5dfa7fc77c4e684688c5e5492c61c52caf53f3ed6d0e2f563736ca9d6542f15c504b7fcba505216adcd2490981f3f3f3cce1c3d08dcdc93c7c386866ee765101e9a2e79474501c9b5c17c0d275379879c1200589517ae4ca75d07188829526d2105b2fba5112819c6b379362dcc628c2398612b6e8dee4134ecbb4b8bb98b785c4105476c4d9dc1aaad009349fb43805fb46cc4030ece30576412eb6a4340a32e8c69bfc84f2653dc2710efc2038352e715eee86bae9f8c19dadc37819af05eba09b1d9c0cd6ace360ddb497599ee5babb806318daf636ed0fa9b3f5ee769669a5f92de57efe3aba6d48a5b896a5a5cb6b95deb825df2444f097d960942fa415e7fd9c2db29258c22fe18b75f9e4b1e9f472bf891a45a27fa22ca6fd7e65752cd7bfeaac19cb106eebe825411383ced7a191327f8f0408731984eada0ca9df2bad6ca59029cb7a1bd9668997d13e01a15fd4be57e03a6d05246bb9de73819f214f2c9292c9b37c59cbb35e5372fe88180bdd87678a1082434975591e80a558b501f73a80ffa65f2c7884781297794627a356e69a6448d12b2796fe4c74ea5859c40299fa88869e5e73d825ef5a9e1d8c5521152219a6a152d5070929313aa5ffc4fe558b6405fc258bdcebc2b9e903de1b460cc85a8d4589ffc600449fe714a1528769c380de648c90abb6dca138909871de6e923d6e694973de239e0aadbdd75f7337ec8f19f42f325a4eb6b6a1855e6fc58c8c92a45ee05684ae833528731d61573326aaa76cf2dd8b83e2e7d472df080c2db8953ef57606ab81fdd61866a22e224fd01632f272a5cc7435f9a09f1332452922692ff8d0a7948932f63ad06b472de863acdbeee3d51f2e5529a10ee69076e5cefec4f540d9b0b2d08f5bf311be73b9a5b210c1937a6bfbc26057b3414725f3dbb84241973b51a12fbc1d1a4c59620c61033062369c260cf1e5d7696a3e27155a15b4720c74f7f8f7828112acf237b814d0399d4a697173ca6c257e4b52d4b4e0f137c3daca8304f95119c486390a6e3870e971d1127f91a6dae15ea442c680fefc9912e6f946dfc512b553e92cf5d31753f8a61eebaacf0992d891e640f6172f1fad374c5508642008e20a66e72f00bb03aa437e1f5295036c5ea4b0cbba47caed57d852a3e105ed6c476839447bf7da5edd006fecc02721130728288374a0ed659311c904f048109f837915856949671faeefe67a3f2da73910dbca08b966fd6a91a9ac780a9b88b1e8e6211758dbac6ecb2268bd60381666627e1a4e66ffcd4fc655da7640721a9a4225b3bc39909e64d5650b957f4e0df32e2861b9831b5e715659cc18023c738173a777cc4983d2d32e6bb847457567bffe5551941201d20dcac53fed5d3a8e69e708f9319ef8ef6cfdeb18b0cd20f2c064f635861c7ec884f31240060ad15e265f1d1d2c641fa7c26333e127b9129e6b9e04d5e5f015ba51105c30e4c43cbcf8b479e77b16b101d0b3062008dfe99ef44d50b2789eca598edcbe33248340bdd21a6c19402a18d4d0ccc52ec3c4ba8bb50b90626cf668dba8a2a7a6cfaf54478944d9295068002ab2a7433ee0259382fb6434ae21b7fdfd135d656aa366dadd2352e391ea640a17f446ea5df4aacca4aeaa4757f710d4ca2263f2061f15ecf106ec3af55ece48e5d5cb112eef248f3bfa473a1cfd13abc1fae0fc89d7b97639726a869781d162422051f130320430f24c0a0372ca71ca51c6380934312a72f5cb04d2037fb8295d62b2d6f3200498b3837d2cfa608a007c13a4d707286024f1b7594ed51deb65ddcfa40e75b34c19b3001281171d21b5076b2593856b803d66280c426a6bfefc8dc5f7a5d28e7b6e45d1f4f2f6e5988ff45c12a4fd655bb3f4083852419024a554c72f1900fbb2c6609e4936d609371bc21bb8100540e24b6e90b9c28ce5f42b81655280ed38cc5f9f898ba7d7be0cc607333bf7a37d8d15bdc3eaf81150c48fea82fc5f79c5a95f819f39cb4b71f45f50cd1f180bdaad4e9240ca7790bd2f662be5a94e5123aee2fe8b5983a3d8fa3d403d0a1d14dafc110b890c0292beb9f5f5b9f8039342e61e0ad2591f4de49216b5dc8049fe51b99c96790aff4d6dc8958ef3624c86a8a9cda67df4695abc85d39f212726dd3f292309a0fcb19425a257d07b61db0bd3a7155ed01370189ae04968da1826cc67ffddea3f9db93c85ad6b4241e25973ba9409bbbac85520a32ed9316c02977e9fd40d7f6150ee3714394d014ee094de430eda4bc3e023eb84e34c68711c999d36befa33c5fbcff35fc7406dfeb3b4ccc783102027e0808df36bcd07328d8e3ee28694d552a38559701f67f9d7726cb6b5c19b518fe8a8d27a45ee4cd8f31e6723da5456909f45d668caacbc7e9fdd4287d0712b4bbed54a0ee61f349ee6ef9296e161fb9ac01d28e07b218931f09ddb1280d27355972247cb85d757710f758fbcbeaead983454788f77c0f74f405149b78950388697b930353c1a0c364bae2d9ad6de72e81d447818e94698c6b70299c98fd384fea3feeb4c65bcec89d3eb541de9e9a3f6cfd82c73b708824dc52d9f3e4c35e1724d11a889151bce285d29f1260a7b71c77c7ce061de22446f45ce577e79ffcf9cc65c9b36234d208b3dd50ab12e903a1c004d4f407b5f947362a2b194464db6ba794307542b371e7f9592926afd02930e5a021b59190043cb265fd4dd6f3f43a60ae428b0a552d2b51d5d803fab9d20bb6d463ac9ab350c1303c3d4e5bdeb1f1b10e28418b6bd71c779078234b22e55913decfb27f80e253544815acaa5be3ac1f82a49c71320a916aa82359108eb41778bbc394e899455f20f2aa6b4a738c5ca05f8dbb0c1a9649cf860c62ea4d357b8e06468083f374aca33e3c88a4ca62005d462eb2cf53b325a7a6e401af583972aca9c5cf203cf3d57181e15cd2b5167bab0fcf3befd75ececac89d9ee9abe0e5f8d8499fc98534339fa6d6e1ceea0e7ba3d8343687128a9cda4c787cbfcce148a273b7480420765976095a863a3ffb34716014690ae1314fecbedc27fc0e64bc4a28144cb04e602be17d7171f42305b7311b9f2ce96df62b631ef79b6ff1155828794084372a7e3f30e22008dd2f4178b23224d13f31ef41ac482399dd0b57e3e1a91afa1159fda475968538adcbd2cecf3ff595b41522e65859e821ae3ea41eb9c93d00b9c7b49629e8a5f185dea44e76d4b2267d6ee7a8f775e8ce4555ffe16bc0b2e529104a0133a336a5a84370be020ce014f036776e61f535cd6cbd02387465901a8401f914af9bfd0cb5b329d5b885a9ee9bad7513ab32dc24e07885cfe98135a064f05f1026ed28d4e4a289c68ef55b3aab26bc241e2ad59516b793d61d4f644f817a134eb3eb4c625c559418b1dc43d45034b58bbca5ecb6f6259585ec7a4a847bac86789292bfceb0e787a85dacb89664174c4b1dae2c7365d76a25b3c24ba8e44d2a089bb8b6f35e8a5cc331958ae1017d6e1c455ec8b443b30842fed31471df09fa84c6b1b9b1ce1f825976479d4aec07510d0f6be699a72b8e1261d6744cbf6fd5d9e51439f24dddc754b1acd53e8241e42b73b1686c6b16b4268646c10a2546a1ac46efdc8358b583049f67e447c014fc9ebde2d2f18bfa59d3812f29c8fff21bf769f3140acdcaefc7f937a586fa6225bf926a0b42bd231651ada9290ff592b605a75f41cf1f22f576211e4f7c04686026845eb42729aad0daa542cf8ec6a452dbfbbfd8e3c9e0eb650079376332678b78f3e8d5f64b7dc559fea6ab4450f93762190af0a10d4b59c146b5b0d6572b64316430020ab22538faa877da28479f928a6df4e543d57df37a46892d2cc2a6807ae4281c31caa14a6048179e623623ad81808179764ea055c4127ced90375fc70d630b837508af38a9f6f9080dbaab676d81bd8e400c48321e598cc8c703275b02075b8bd26aac5099e3f62aa0fec8ece8a1bfd883746a8d5e8e9d57910a193b58449944b2e444d90efe5d98fb1b97ec3935f181ec55673aec74351f3113a681ff2e2415f0443479d92a564ab3f5cbc568fb9deadf82b1011e133590f6cb2513f835b105fd9785702fba74a2dda6e7a17d5fa365f885c6bb56b40ba2cd3c8b985f7e4df53209b9b152b2a4b9ae1d3b6481e2d0a1a560d2fd82f969c8e88e30bac6229d428f51b2f58d2f166be795403e911a9187e7f0ea76a97f675181c1760f78aa33d12e1f836cc829770169940e525b6c73c06b6bc124f2c2c3f877894e3b31076c2b346aff11c7e98d439fe3c259440ef7adeca6e8e9a14d01ee9312045f542dac4a9a1e5b93b4b14fbcf9eec4171e736f5fffb9535d0f08534fbbfc591f915b754c5ef219a06a0890f53df345db25c0195a672205932e0335b4b524d2bcb03302b90f0770aba66d86dfb6960925318e7e52db0f9592aaa2becb8bb75cd24af5c60f9e5849b73c1bb04f550550649f5fc0507bd238a83c8b2d0a063cfcf7b676a6dc0081a7b889427ed7ee343f4c970ef006036acacf5ddaf8731cf84484f1e5e14ec96d496a2569398491b6ca0742c81962931069369e3c0eea820aa3c22fd6ecb67b3dea0018f3e590ec42d9295fd1f012d203154d787232b257374b75bf17947236b431c298f55aea5d758494e51833f989edc737bee64c3692a6a9fb755264cdde519ed8750464640a5b00bbf89b3ead89ebf8469dc59443956d603a4f942bf8e9f8564c141754331916bdd1039dcad31da911de591853d4d45cb095d93659fefd5df8c6aa7bb50d8cb30df7d97a90066430fd70f9bc0fd776fa507224f39f42f1565c79291cb1baa3a1736dcc62bc58b76f4177ff7589fdf7d79900d5ebcb26f3610d925d074136f426a0cb562ae137296f07d860a81a16bf9c79eefe06f99571b687791a26de210ec903c09ecbf9e7426e2062967b3876d4632b73a27c638a3b3139a9fb4dfef71d0b75ec73a849ff71f96059ec8ec14f5eef445897bd933997f3932e023dfc52d621b8fd8ad5173ad153775f2757fcef316b8f3cb8b406d123f2d152d9bb2f33e7ddbca491c5803249f2e0093d8a8b39d2fd2daac960fce6071588f5824c869dfc6438be7351d5c0bb91024875cb1a45589e54095d794b201c93e0c6a791905fef48a0552cc7097b157b297e7adad7c328e80c791319e9afc619251fbcf8d87f8dd3c2bedccbaaffe566431f90f04b4ee9c533bbf916c1fcc93959c101f5d4ed04028d743a9112c0f52fcce3e7ee97cb09dd10b166334afbdb4307aaa1f43a68a8da2fa6c1c2828af2a5fe63433cc71a3f682c5bc19168429112cc9a5d5a5e1a5caf4f92ff7b73d9b2328c0d83cfe23bbdea7f43f9402e72e7180a3fceb03886511457643dd020bfe46865dd7bc3a6dba98c6fafe1b79c45f3c36b86edb895c32040be2da35871bc0bb30ac11da70735f5716c394a784c0efa58d0bc157adc964f48dc96483cdbb8b8f3bfdaaca88a032bcbac24703d01eb7667cb78a3d9135a17978535d088ae5bfbb5f3e7610b9ae281ec4176583126d44eb2d1f8f8e6581d9d804ffbb924ebaf4fbb613c6024b2fb351b872296b59b35dd03a2b9d372528cd4552b1eab9b848434d10a2834fb94093f1f6ab0a24d3c08a87a9f2a8cbad3a95a829c8d43655535ef3494d2affcd15ef882bb346847f8a80f134ef85bb0525eacf3a099d594e95e1e7674e9033832d199ab1baf93aba6a11ef4f4d85395530a65f198596205a3a3918053994d1371ae92cb00e3d738e7fc85aeb79174a6ce1f20944de7b5788686b7e34d429ecde7ebec9163563269bb10a800e23c3097f5a8fedde2c0010984fcfb28b229999f3fd7802bfdef8c68407101e0ab84b4cc3cde339ebdd0a44f234488c4dba90d5b9113d9c43fcad3d2638ae7e6c17d58f30bf7bff21b70a807c4a14293cc886f1b56336940c4970dda58823ef30fb5e506e9871ba8980d210355e6f00dea4c1b3e439b1e26202e8222420c35969b90326f238434a891d5c812407727219c319703099f74ab6574a8114ca6d802c67de3b9728a078f602696a7d98bde9a0b1eb69cc6746b642e3881dc0b2202047a9e2b2207fd64db813131aed7790510712d41681be3b4d846176073e4c308bd08fc6196045d1fcb235b35f3dbae6c48c4dadd1174e741dc2076768a4fe6d38de7b2cfd72590f31c35d6011b2cc51ea43f17645cbc48fa1fe6f9bf834577200524b939090e467d5bb89e11e84c4efbc5bbc304fb9ab35ad058f2aff268a509655e3d5cd77b7f23bc7d66c10a7a080faa493eda301d09e0f346d5d1c87de919254ae86cb7b2e60def3c8c0dd30da93d329b2eaa87b4f8fc0427d41de3164b13f1e80346a9b285a0db9d60fa92572a5c52fb607912575bd41c846f4be520fe6d82e237ff0c0ccb89f2063f08bb59a8bd0f5fb94916212dd6b7327179955b613957291d561af62f74ab51439ca686d1412b2d2dac72d4b4fa3825cf997c401626d0ba3a850f08bbf0ef408f0bc51a436197d197b29c2f3798c024ad723586f250258535e0f3c55974ee8c6293d2adc9f844a2564fe70fb79890be71110b380192df48b3f8f51a9b8dd6129cc2773ba9e90dd52c7ca9a43418836e9c1ee3ea8e6ab5f32f949cbffdd2123f57e81a727c9a8d1c880a3273b41591c032672363518cc49c0bd08e8d3a908096b67166afcfac08bfa8da3d6ab3ec0d2f8fcc79ad62776d8262da0511ca23606de6dd1dfffc26f44c443df9a0ac7818a179c9443ebf003f5d96b54ed958bf34b8d8ff12270520eac40faecdf24b380c3072619cef9a20fe1624ff84ec40984af8bd6248151ceb2fc4c12e10ff6558f9d64796151677c57cf08d6424b1aefefacb4281358d72a76cdb92e9c7c2112d6056e62cdc2ddebb7d0937f5f670ffffe1ad4290992bc600964307f708b43e5b3f6a3d38385188d72f85abf8b12360621724ba079f01bdb759245ec1ab17e89ec664d8298b0469d1314cd1e6b1d096677d7b374080827e076eaee18f389976757cb6abcd59bdaeb83ce1ee3db2eb0ebca21e1312d5e10d4e4d53dbc22fa23a1807596c84c4050a0ec6864f058e64af89a5963b808d8527c2c30ea80689131a67747151994e96f56383e46f28a6953714ff4e83ab700686d342f3d939ba4bdb151404343ccf46f8819fbaef7a0ee6493ee8cfa61ec310152f57c5fc15d8e2916dab7e612f03a2638e3da5b08ff7046f53793a834f54c0e99acf022c11be3b8471e679a5ec1e6ba1b28db9c1e43c9238d84ff360537c66291ed8f357b65e4acf2539f3151059b47387c81f5d61c36cef8757024c96e36e2f01233bc8128675e2a372476706e6a105d1a6f62ea03ce73115f8a8119855e8810ee1f7267adf6c8b26a3ffc83205a94d311955c6dc466f69a291be297d5e2fc9bff15a844dc83ab5e0d322ccdd22cbeed2cedb049118b293a08ec53afb72d70f1462222518327221c710472b2e97d3e0a1c363e1f22bccd179416e91fffadd68b0dda690724dda9723f7430a01e3ae24f305e9548ebf4c43ae58bda42200d36da8b46f27f0f5df47c71d27fb28588fd35741fea8f7ffee2e824654486eb67d5f1ac3731f8912c3b7cc6a4c01041695fd198675c966622b05a2eeb39b7ea65edbf5e86898a71887aff44e47fe90102d3e7068ad8a044c384855284ea27c04914b902c7d02cd05393905f532e96933ca9fce2b0267c2cfa418a1f73b3c8ea14d56e7dc1bac885bdd2a2a4cc17880a02a95c83400fd85ba6560efd2f03f3fec7b5c73ef571f0799284067853b3f975cd1a65e24841a121613a7d38dc6c929ed7b941cf5601ad555826cfe75551b8f2e14daab0070f82a1f6e448dccebac10d095c79eec19a619e0a17d7d983936af7bac45cf2288d979ecb71a7c90a1c906ea9d636a94ae442b21a04a938097b90dcee351f331b92c32a0570e4dac22df184e48cb952bfe0ce64f1a88105c192387b497a787e51d2e5d33c81c5956adcb995e2306da4afccfb803f63810441da2795bc49905240c638c5ddfb295fe4328d8508a5c8423897c1b619fedfceb37d51bd1b5c1cdffe031a48b4ec393da15b00ebab4364e5bd5a08d020a856400f5d3708863726fdb678571f207d5c8886daa664bd311a8a65dd46366b9b3eaac49b5a8d15bd864165b9be3647a7adb203f7edb429eab25cfb638a89d42880e0ce799e30741fbcee627e2d7c7deedda3127e0cbc8a0d777d1f032543d067b371c1aa337ad3ebeb3e013021e8086ae8ca4f681995aa61cebfc4868e07963d06437db4cc58b93e009a6c44a0c0796b0f036bc9c3b46548e961069a0acaf63b979547ea0bc37cf04d97caabe5e72a25ff1fc88a52525dc57bb5ca9f5a38b7232e3584ee74ecfa9c50ac3b7c0855bdfc1c0f0693a3de2fc5c1d9e4dc208e5ae67239f5a9409206fcbaf242c172582ca1972871dfbe3a326eb75afe08c496474cb63c53865de4cec0488819227b7ba1cf287fb937d475aac54325bfd11ed47d4047a434974a7edc2ed2e7488aef6f478edf88fb7814d58332873e85046fe2c56683dd7735dae2c96878dfd136a10a43afd0edf7ba2e0931fba23209029873f9f5ed336217d3878c1ba14b8975a04bf850be581c7b3e9b8ffe1d7a7006080cc9ba9519abc02626abc94af4a347e24d6587b166755aee43f7053faf94b22048e78e52e863a413e9804350f9f5233b53cab68221c83b34226b0df10a6bf46c4dc9c56c67567a898b947dda791acf42f8a8f7cbcc23c4124817b3574a7fe1099e7283f3baa083a31258987797d82193768854887b0fd9e862678c4893c3749d4be960aa5ac0a0eef767758a5339e050cd47840779f4e164aae72c68290223554cd1bc643916b1a55dd124b62baf19af5fe9dcba95b05e02dfe86bb77f273733f6699a22c3e23b23a97dcdeec01a29c961267f0771642eb31ccfce8309e6defa2d1c3e00ef03bd94ea0da6900699decb5d5807b346b2dcf83dbd8bbf38838e3383b3f11a55dbc6c1601bb442909492f8d63a300838b9f941d2647867a484d5f175feffabed715349f7c2829d939ce95bef45df33e95c1597998c7a2633b6e3ecb839ca17b3fa203a96913d7134f4fc4f38ef4f5ba43fc9d895c83753a2f10a4a8d123e76c86528fa1649f535ef9513f1840df67ff42c4495cfaa4966f480e7fd90836733414196d4b7e944283ac67e63229a32c1cf8cd65244369938ebef3c36c7faa82c5552be51686591bfaf8e7cb087b97999e8718d2767fb4d263a25227d12c1f421de1f130a306d133231df173bb74aed0473d0b21344e8476a09cbccaac6d1a207be754f544e61ad6a4fcaee8eefbe456a77a56e6f40b6eaa9a21c72d7f8063b0db78c8e3c6ddf302f113715877f8e569f787febdbf82e107e7aa0d88fdbad0f802691ee9dc8d569d43e4244eaede595fe663edca28cd843b633313caf260c894b1889e2d14a24e7eca8f498cc1b76ba6f492764be4d443d1862728eb70a2ed10b6d37253649942f8c77917250d0ed9ae1189bf4ed9f200e7b0b5b7123f8eea2af81974bff45b1545d026aff88f5318dfd89d1b864c01be094aaa241c19777a28c00477648b4512f56cd3e787d7e71b85364dae5533bc54c0265328a16104d6116d7bcd7ff646c100354d61d3622387a3fbaefb31af2ba98182926f4355beed77d2087fe31b8f8182b733436fbf1190c5c6fd92a3a800a3cf686d1e165661e179386892aa77af49212a2f10a2ee5a705442df4d79a42e0851dc7b65ec9f96f29f20ce3464c66e727b66bba340a57a81b414069015739e23ce45aba610aa8f3571690842e3fad84e58bdc9f5343ff768b931015c351e3eed5840830e607c51d4c9915f1fb1a908be16e9f6b43f0672ae327182df8232a339b7f96e75f298a8b3bed5cc07fe36df5cb3faaa59d86e8fc6d2ab90d40522459ec36b6d5516080d6f733c956bae2bb346728c6f74f62beaa1449075bfbe94840ea01bc06ba3cf0a4d1005d5deb91ca42bf196035f9d2643594d63350892d0e29747acb3bf671657579c18f82bfff19441bf72d0ac8510623e5d161ed9081d4d612ad8f2f7ca26973f7a10fc59fab5f7ccf616b1499cf4729ae43a05b31d92b6ccd0687088fa89e7404e83df4d5a511bafd2d5da3f6248ce585147708c5b1bb7a7ae6a8ba71f2290974eed42c1a00d5b3d49f5c7887a1becc134ba70b5e5882c847f81660f8f5f5b8f26b7121e3400757708a9becfb95b03ecdd7e6cc7dd4e8f0af1c3cf487449925659b0b281b0195632931b721ca942aa5e5bdaf09baa31844601336b4719bac84f7dfe6e4a08f670fd3cf3e0894344e74b494bbfc8dc624178d03e370bd9b576e5cfd15467a8d8cdbd8fcc896f72f34cab8d26cd6c8b42dc2dfe2e3128bc37992d9824d17dd2a41b18967c1885251b932911c9ecf4b6e542f24e8be8e7b54bf060522e3e8e2107a6218e085ec469e3b30455b000a74ee678250869b73b4b0b41f846dcae55f99b7b92aacd1f9458c7697b96ed52e48a362f4962684742922d462a5fb47ec693f9ce6cf7a13edd4cd19923b93c257d140708ad835e43308bcdba8ad9febe7f3b129d3cb0702d437f2b8ec416f4407b682968030152f06e4a33d83ba79901db9d9e09c1eda5175ee50ee332dad30d85920fcd724f27d1b0566edf63750d4d5be1c37f1fae3e6cf16d455db7630a28cdee32f9d28d85bff6bf85d28b1256f1af9bbbe4c96f5d1da30e5042dab66a50a5aab2e6f2e0b64c29cf8ef0bec4a872609e71c58aa51e1fff8af4cc5baa8431d21ba3ff25eb90833db791adecff966cbcea422a3fb3add39dbe42ce003e92b47c2dfca43615e38aa2272e35d5e6126a713102d8d8044a8347e69ef72f494572c3202be2fefb0e7aec907371e9b58945a89109427d4edcf84a7909794b70ce2036acd50fc6352139b57180bcce23a6ba4566303768e092b53d0a86d7d27d644e72bd0979e5e5ae601a37711a12dd49ad77ea5b51abf88e21e44ca5670d9d986cec299522f71639a49d6436e635fd0ce76433a15bde9171093945e915e1033c853dd9655c65801979cb8eca1b7016a63f7ea78ce2a57a81e048583f38c15317dd2a6a331ba5c234a5b5df0e1e0798ba271979912af9f5e40a85d940a273775848919426bd1ab1210c567eb4507d95e8ff783c652e8de5caeac69a69d2f761a4816e63a3acbf656a4bb6b3ead9a75c3d3d3a1a2b22bc59a59ddae4e53ea7e9c85ac7d23f07b194d61e1adf3eb0b72f5473421ca0e72a488fe00a1b3d5d7f3851d6d0df4db51e58aed2e97a43e14d9a6327683b7bf01c58bce9be416963af2c0b5aa0913112bc5289934b45c296fae9a6eaac356c7e1b48e8cebd0858cb19089c5031d559a202a807d4134eedf8b7b9f2d77b351b069a8a0165f6c7c258697b54937a5117d488a76d6fc0d4f0291da009e2db8ded3f8b36701be0212a00a7e931e086cd194d6baf2ed331010f44fe8c8d6476a9ff9b90908a2a20376ef3f5e22635dfc41249c53151de30b1051fee8955e6bd1b4fb3e20c8a3c83285a1ed9ae91808c247fd599de16c2ae3f15906d91666a1e1e160b6450622693420d2e3e0bae32c3ebaee8234d812b718c338e84a83ecae0ebdcffe29cc6ba46d337417662be1e27e8b31ddb5eac6fdd18cd45b3b32b763d18ceb64c5001acdafbfce6d874054c3d971d22e8a32b993a9d2434889560068acf9d22e1b5872ff775ed08dbbb527c5a60dd0d072b82fdba8e238eafcc86a34ce4d9065a4a0c9dc27a7c02e54e54775e1e2ddb7720aa0f83cc7fd8ec733ff5f50ab99814933df686a4d4bc37a615a5f020d41686eeb7c82de439268e3071dc4343c3e50fd6b35a7b946c5d61481e1705592feffd2249f55729c8b0650e4be3299901491af95094361fe8b8e8f91072b40363ec1fd0b6d873bc08308afcd4ff6ed2ea2e3813d78b99853e1a6d80c229c10586e786918e072fac2c50c550b01420c5765cd47ce3dadec928a880c472d69156d708f867e51306ca31c3f9f4aa761444fe1503e66f4a8dc2f77270028c69153e27063f3470af2776e506a8de3377a3ab87913b9c8d605423699a30b5b3958ba0c32e62f81facffccde58e4690ab83d5e5f06d94385fb29565429fed0f2e8178b54737668676f4001fac1b06cf39dd7e315019b36f1d1d50f6d24e3fc83ce8bc40fa133927b9ce8a7b791749f090b619f12bc3efab1e37e0ab99714957c7ef6f8420738f34458aebd4b30a3d37e668ecf5c2f1c054d17021972455f9f0494bc7d32b55f74e5a5c9ab0709e7541cb7270cb18a1e1c987e8401268be5028a6875315d6c684243eb96bbf76a05385c9cff5e1814ffb9ffb3ea76f02be595e3156e7f26a6702ed2faa96aca7ab8e7a74157cfdde462e8ad144d3cc0f679d0f36d3018d388b20533b805f8e85c86bce2dacbe8686ee8c1284a2dc1567dd9b961b358e32337fc805e5858fd7f4e29ae6d9318ce8e837b8f2fdbaa827a6603db498d00e0561fbc5f91248df97adbf8a9935cd612787b912090ccec4252e3e76e964987eab4e29a7e9ddd59e43a41f05c897224c013a26696f46d2b3e8829c30b2d09fd5e2ca22f63bc520e1a5f18721661405f4e0f407c18cda7528a7a39171390a1ff3b4dc3ee9a104ec336a8a1a6c816d84dcfe2eecf6f1d58c07d07eaea8cd9acb18556fe4eb322e487d6baf2a185d683e19c0fa1c7a4b6d042020d631bb12d17841491dc7d4e473a300f94c593a7b7ea05080daf05f4252f3b34bb263466311666e78735748cf1abddb815683d06e99a30a5312dfc7f7d4dbf0e44d6f2e8e0ae91d4a28318c1b124320dd96b89faa2c7207f1e1f07de61cff4c7fbbf137de3f0cbba371b5108291f15d104ddfd5be1f75eefd7d68947fa952734a61db9a50dac2736493742f08ad17f6b9a1cf639993e1ffb36b500ea472a9147f1d1ec3982796590ca137a3f6b986c433b5b01c3c8a64b86845a565ee4dfec8d116630de0a1a33985ad0ef94f098848082eda4cdb8d40f530f23bd7c6d2c9d685982857838b2103452c49b208561e4cb774c84f1a3162c42d5f389ad21d7d1098a21e6ea1e164008d46b5376d03eeb38b3f03f66b57c6d2a2b936fddc5491cf192b98fd51e9f1a602d97158b6de0196716ca2cef23f82671874b1fa951f115c9fbcb829fea28e9229b3428ad56636abb872f706add5678428b0eaa99ce4d7de4aea318b2f2b06a5987f8849c5e7d79788898dd9f3fb1ca6df5d9b861e689e26ad73b8b21ff258f792c5d42878147136174c00f4d94fc504b44f3437932a22d2c6ed2704eef847dd388ce97e4394a7587264e988b959693a02d801474ddb7a85dbd5b51ab2a3b6716589382e693dd154f9b520b9da6134db31f48e4fb41b1f55aba5d7ee4bc6ffb7398690bdc1ceaac91644cc1f9f0ea51b678c55c9e7e756ecb9b9dd493dec531778af42c827497a382cd2997270c267565da5196129b3d24d46ba69cf10ffc5ddb21a6574ccb60862a929a017a729810dfc9fee818f4a3a877754c4b1d1142eba98b56e6b25127b42e196ccbbdf0c537d33a74258952050c5ba4e871d64ad073e7471a5bd7ee87f182a453cf534df1ad3cec354e171ffdcf545e347fdc4cffaa502905aa5c64a7ebd5669f1c288e36385ef8454253ce7fbf64362022ec5d6c842f4e2e9bf1588d4726052d46312ec27ef9790fadb74580bb9c83e83399efa1a30c1614c8e25932589881e8df677f7b3cd64dcafd9ddd151754adcf7c5b18eed887b33ca847c54437cc4f9d3c3def3049f417a6edf1e9b2028408f26ee4bb9479b9bcaf561a8357595ba6a0100f38f03220291ca56c85fe1e968c187bbc90474fdf5092b229a1ac445a3208bb1a55357c43c87b6b1b2cd357f56565ad807c0178dac7d79c1527e2281167881bbb621b1fa4c9269c1afd5a456c9da1cd1c2263179eeeb7169e84e0f986feae9f7fa41a9ce0677cea0dd1e0b17fa04f68596e0cec87c69f1b4b1d29a89145e3d6af615535981a823214efb8976f6f292612415082de8efdf6c4e445259365b78be5f0a2d771181e58df86bd26c2577275353edd591c2695f45d1491e9fb889d258dfee26038f3ce62572fe3cf49c0df1e8ae3a0a394d520188c46fbca79b4ad9aea74fa33fcbd6c387bcd9cc25a4721c2d5d6e5245ac4501ab684c023371f921d36ffdf547520230c704a70af73fe19010132d67144f393a62133706860fcfb8635c7dbc66ddf3927995edff9b18213b0bbf8ae6b242f6eaf30de4fb2b0390db4a6da8c54b2b1af955ad97d2d0ee343ee2394243d17d3d7a6cec3d4be95680dee8050cedeadbae2f9e90062290b21793b2cac5b47ce8a598da34bd833ecaf085da4919b71dcbb5f84849cf50ce7b80fd995f287bb7d2ab0df1c2fba0476cd922743fe096228fe6eca168bc9e3337781e53be004aa1d05e18f7ab7e9a2f3f6cbc079ab0f42da7151f514627f4a279201d690c8724e903fd4062ff48d2597a88c49a087d56f407f5cee94fbea07e1c6e2230bfa66f4366b162ab2ea8fd5ed64ec8332199f0ae354327ab20bdce2bcd975b14db714538b572b2a77a47ef744dfed4a36d3b701e9765edac8c38f18f47e7a9838fe43ffa132a6079bc4a50fea3f3c37df39fa6f81326c3cf583a87af79e12ab33c28e9f9a7b0eedd1c45dc68ff1fc8ffcb68b7f0cde16ee220f4b1706fb43ad958071cdc62b4a374ffd8c0fcf170c5577630531ea809499fdf2f1a0431c1c5eccb47bbc786f2c9b148e8d9e72f8a32839362bf92b4b234868b7b2700f22d811cbdf190c61001d0f31a1e34e0334dd06058ece454f4f1ea6f3ff842b909ac2ab55974f30c3bd871f3c29fd5ed9c4247cba9e504130eb3ed24d555ee7565ed49c63f4a113d6c9038ffe536f699d4f6b8d4e66b1665a420142fdf2949a2fdd51f64e061f5bf91575b4f1173ef7521656fb8ad844727088911c292c320caf35bd05ae8ecc5d519defbbb89baea376549cf2e5699a3c55dce3ed1fb90bfb702e3e7a516d71f5a0a2844cf48d86f64ec044d2001cb430c20b30d6f608cf8343e8fe18b546e012eb15c57a973abb633b41fe11e80ff60bd9e18c18ed5e70de7ce1a289a4f25fa3ac7ba4791702e3d733754db342960a7cad923dda41e24996040f8a5bb149d175389d1be5cba878331f463e20927f20748ad9ddeaf44a8edfc854f8c00ff782def6f191c9bc926f99bce6c3dc9fed8af6c13e91071968c26d22a81b50dba41210d259b52c801d566df1c5f4668126c66a9c67fc444aebc449db876f80153327dc9cfbcf099a4ecb579c43ddf09c1955229ef25a845e02999a33e3308408e124c22efcb75ccc370086d10f0cc8abc95f646fca6310b3f19650d0af02f3efb691eab6b547d28dd1628e8072e95b80199191d08341a3155dbeff1599caa16df3e47cc5a3571902e1d0f0da9ff4322ce59b58847fa6eaa736b451233c5752f3e45ee0869fb177e0b44a49984374e6fff7fd619b868f589608b013777df25fb5286d3c4e4ce4a0b81830740cb6edc92e350037345a2e1bc1dfe3bbfca9d07fb72849067f01fbfef9ee8fc08afc8794393548f3033f18a43b417e0bf6695db612c93cecf7650f8432de618eb116bdcf10ad9e5c0c06eac72455a0bbc557def7382902c02d0043683b55bc3532e91cf2f638cdfe43d69be51d10b44461ed822851f17c758d6f4e3cf99f2ef41b35a1b43c6086299f2dfca77ada4255a44fb3da2f09f4fe1ac2e51751f120b1bfaf279e0627208e4ce5e1df6c2e0e24bedba29057b3480e2665ec60f18edd0caf9a3988c6a2f5713e6d0cb118c582607e638aa78b8f638045bfe588e20e4c53cc7bb19635681ab156117ec9c72c2c9336594ec8c8a16cc34d5e5870c2ac8e51d61d03751dc906335a161944a358bbd2cb9b5e78114e2bd71d90984d09b607d9860b2ac50b0a4b572ad627c57d1953ea4f156b21ca79c196e9784c4f63cc6a971cb2711c2a941e38c513083f72a30c09463a393f18298018dbb51ddbfe65e7efcc2edb091fc7223257631bfc58999c9e17748e89ac55e07ad3bcade8b63cff20174e0cdcfc77a34e83b899c3b15160b1b89e55ee6b6ca412ed890d9a0d2b717c3a9df1e56ea460e14d2188bed12a1c1468f3eb5f02efdd8170238cbb7321b1b109ee84d93bd62a7868732dfaf7b69e712537c881c172855d48b44aa4c2687ee9628473529292ba6a3ac94d150d347476a6f596edccd78a7260016dfa8c938bd53a1fbade08588c5612fc1fd20c56a6afdc27741ca1ef10032943d9420de3b4bfdccc33582eeb223f52d9595d74bd4d09bad9f24788a489b03e5371956de5fa559249219a8328854ce8a1d01f80d4e264554631546d28d6267ab3fde961cb7fc7a62d4eb92a6bc752c38f8469cc615f91d1d7162ae69d1a0301b538696d9d5c310c2a7f75a4b1474019dcf448d190419df333f0f7f93a921a43127c771d765444fae37a51db8ede98c7d7221798295d986b09f4aae3d8b5f1d9e48189e79e13830f5f3ca62cbabf138161b3af96d63a9a52f94ab5f821df21d4cc69d97fd2cb83d4397804b9477998eae13739cae33bee3a314bc18de73afda1d9f06d7dac39a3ed7963520d934d71866662a1043a2c803589eb2f73b905aae341ad380898d85a2d1d2e669a29041929c1fbce8e9a0f3dfdb089b6c3a49fc05c86c884e8ff0e3708b79349cf896f58dd0ce7d176db2e998e421a60d69b8f801687fa64d1fc09c78af2e4348035e532f1861a8aced75c8add4733a62081a6933df5f8cf75c69114d61e7c0175881951289fcc30374878a8a7b0a1cb6cdcb90dfd3cac6e3d8e945425574077e9fa2191a1bb8391ad11a60c3748208854361378c68e5c82ec29650e074f57d7b93f1d74addf89148825bc6465b5ea1c8cd1d5eee99e3557ec603b760fbeda4d069ea8d70e48cac7723fa7e5f9ea4e24e2f2026011d1278276e74138bbd93f7f48f6ec6ec0476b8189255405e1a92a49677d3c62bc67d3d882875b5b018381bc3f854a6717b3461d5e2b7ae96fcd4dded43672a675f099107f700ec3cda4512acfb83d7b12b844b350b110144ad20352c33be1107057ef13750102abf732c65b4dc7a7ae833743e55e675cb84f1e7c90ec6acecf9bcf55224d4bfce893416e67540da165dcca2301fdedba009473b9a5f036eed6231936b26e8740bcbff3844aa5195ba497d184928d5ae61788cba96164bf45a9fe3623049de905528c3239148e5d6757b62cebbd8f70efc4c979705c6899f1d38d5b5dc1e74cef7da433f02e495f0f34cd6ff19ae375c44992264a370356439d07d498219621ba7a4d5a55eefd5af603f2de829944efb291b8883b711478f48e5960193f2ddb1242bc3f54fe0d47861ecfa370156fed4c815a75fdf917cc87065f7e95b1b0ef5072bc4240ca373b292cad6c19bad8bc0af12ee8ff0665c713617a7bfa7810e8a0eed0f1205455b71e5fea08b89a5449c003d2ab2a155cf4e27ab953708aec7a070d199e6135fc5bf877ff7044b13b17cc7c2e0722258a14d0cd470961c1649c50efede5f17793f39fdc4452ccff9401ff77dae8b4039ef17c0593587e2bcb9820bc5a95edd9b6404950d1bf555e406e19a64fbe7fc93cd4407990eb17fd2c0707095b426731948230827500f7d1f54dcc8d5183c30b4e3b2601ecb1bcb46b89e58c52fb7a521af50663b2a7428cd150498e36733d3d91b56b053b87401f0957bf7d314f184624ae55bae57374a65f87addb1f1cb7786277b72d7b2261f04f27139e8feef1786dbb9b408dd75759a1126cf4abb0b34fdb39d8ad7954e63e6fe99ac6f85b79a8520ebced75c9ddc42c1c00130f78e5e584102e33bb1868ed3983cd315496f361ae1a5f4012f35d4dfa6db061b7bd71aa916678255e2b3d2717def5b094b2ad2303735abc2d00ce008c9f97d4296b8db00eec77fbe5ef55f7f8cd5c7b04eecd9c3133411af89db1714da4a6bed2c4b550efa60897adeb12586d98f5da9a17c9cf9c30b050dfb461ee2d86d190c7930dcd2f4b6f2bd748f76c8bc37d59ff5931baca94243a4f544ac3069926e9e21b011656297cfd7460392e8474f389b2a7902df03199f4a3b4dbfe709a3fcb6a4983380a2b09225f7aee845d67e4a64076c72bd5930d14d9fd1361430e258b8a10a035f74209314d95ee2b7b13bdf2c20727a21f64cbccc6fb7fee821b04dde48b7935ffaff1fd7c6c9a5f99651fc662e3234a9d0b0060cecda0a66918d656789497425364df6115be4b7de2b8430ec9fab8d7869bac6d3482b21f20ba01a806f56ef04af2caa3d9bb1f049bd3cad05c4d45398aacfe5afb70075f3e2033553a1679153595aa48612d1ae7b241d255e8e526732e002a92c20bf4e01d7a8419eac7e727ad69ec5790ecdb6a025b4726952d6aa0123942711a8d1fb699587533fa06b43df264dd928230c310ccbf4ea8f7d1d3c6c6962f9410bb86608828e273204eaea7fde62120a8fc9232f63a9cb2d993f46208039c1883b11ba622f3fce0bafd244de666392ac5044388edcb24c34c07ac5d7acf46e3881d5bb23cb2c2660a914c9e44c711a4ec9940b18a62a2ce12918bf25437ff569c60918f1ad6150d7f9e18969f0404b2752c186d283001077863cb7377b08af335517d989f0a083d18c6fe3f3abebccd53a94a1c5cd3ee60257521e760c6840f4fe2964273c001e6a0ccf5f02169884ffd6c0e7fa12d12a48c982173ac96200ed6a6d7f53a95beda76c6d83cce9a56af3ed483c0000ab71f0746ac35dfdfd64281e6bce462e8da3abd46196c1564222e61940b9e54ec8e6a81a8e7a5563faa354fe0ebb695ec1052339df1a56d3be8e98154fceecd6c9f6887ecbe312ca373513c6b1b7415f760c75dbb78bc4c1715ae701c5d101bc4ded257cb45abb3e3b0bd8aec61b8bff3d2b25bc3d27ba59bd2d0c102d1dbc56066f9799cb590a2b2ca01677c03a05c2eead93ab13b32edbea3994a8dbc17a8e6dcfe37cfdaabec2d608a889c4a1191af0c96411074cde76b9647517f9a9ee558d38a9060f6f46f0c953faf90fe189dd9604ae3ebe702fdc26db519b259d5bcee862c9d25f4144ac62febbf2cbf945662ca4b8d112006b9df906cdc1df7e688a6f62a32c862ff28b84c22575206d14ff4f8d6ea82f71f07d7a37ad90c3137f5cb5c3a76170f14a8dcbc4d05a0ba804bde65f73da93540b2e64d34db7cd48f35a774bb4770810369ff3471bac9d7d71777634a86a67027a121b5fa5b139c002ca0fbae3f23d7f02f29b2a9b96f98c430f2f70cdc3495ae8952deccfc6ffbfa3f9e5754f3380f9e23422e7a49f49e70eb9eb5cf3225e8f7a67184cdb61d80e241f927bd29e1d760396f51864958efd45978a27207a9675225c26297229c67700bba40bb15f5c092dd026f194dbcf31901281e3754261879b94c4064cbabb15f45af3feb56529eb58117cb7723c1d2b885b391cb27adb185ecf20bc2d19306a0220d0b2dfd28b6eec107e4199c3a1bfbf600ecc27e3e758f6b310a425635aa0b4ac37410b891b55c4ef09c39634f8c7454372f83ffdea81b5871306b92d01deb0cfd225475dfd593982cf95d6940c20626c212673d6d7488ffa3be86f87c75b6f3f670f74e605ac199753dc1aabe0cef11199ef66eda04b4b82e6c961a6b759e02c0a3303b57126bd3a09372908f9de178d9e104174507764f1a0115e8b2f7ef02139d092041149da325435dab9c44e1638d0cf20db398ca60e624f1ab1bc1c10ef19da64cf74df69b8141457127abbc8597d8a9a6f4e75f6ede1296cdfdea6cebf4b4afd2adc7cb63f1b2bb1a1250a779a30787e228a469760f4cfa0b8090ab5f95aa5f639712ec1decd151957c724f86df7a6d3e5f70a93a01e687b91447b6a2c4ac23d76fd45fbd221549fabff838eb881b8ad327cd549a7b7c8672db118681576282d701e0031a920327c6f71e96173f04aadcab766b50e496c6367f63e6417be0ccc7098812b265029c9d1c80d3f69275ae6e0a9f35fab1583c827fc8e0d9cec4ed4381be2df57a2936629f0418bdc032005215a4c30404a639da9060ffbd4813a7a2bd16b4a11ce6c11c2ab541791ee3a2b8e1ec5f02c7e1a51644a4b2eea99b67e7299e4e090a65073210fd60e42045d481f684b86c08315e339014e4b18814a1ce3be6b36544d502ea0ffe90787fc2cef771740879163263d0c65dacbbfc31e3f672ba89abdce16bc7c44f62a2b94b088bca9df8cc515d0eb6d4db4cd5947c21523702db5f8f21c3e25194bbd42a9c3cfd9136995f73cbe20966cd33bbc2ef4063380f89c9dd10661cbdf2e72b6f05fd3cf2b3e5d2ed6ba0eda8e6bbabe692a7355d2a009d3fcb0dc4542744f6b69756402ddf443ed3a02b208d43228710af591619dca2093c1424e4eb86299cd82f7b1dc7ba09f8aa39d4e78bc4254b0a8c5cd0db0c7cb9ac0adb89d2b9e146b38d2edfeaa24353eb41e8e5c5032a1b21c3284eecddc882ce2812371de3f5a49da78ba8cd7a24b707072cc2cbde1f171b0ce77eda2544175054050de55bac44b306a82178748c1786649f622292668f6239c233c8fa52083a405cd5e21d6e8bda13ea10779847ca694bca6eb869ad4874f8163aa44ef323119c8f4b879838fc7dcf084ec422c8307e93c9f95c0828b386af8574a437cb8d2634270aac512bf1f5bf03b3619fe170ea74f9de26ee30f208ce10d77c370cbc0c1e0ce1b7f2ef425089be00eafabeae9529318f799cb2348d8834d2c87882582f305453786e2c79c3c9f139f42d8d217190255803a17460b9066e01b0d695ee8c1735f3750b97b15c0d3a4894a632374c018c0b3e5f407b85b63ac914c9116e42035a175ac1ee7a25cf2fe45ad075499f4fe9b6a7eefa2791aae70fda56fe259841dbd1f280895e1969e299547b300a0c9f95cc7e3d5c54fff02f70fe9e676403923d793583133ae393fab6f08b8d21a59247e660f9ad4254bcb206dcb3a703748761389b046199c63e0a9ec66951d2b9c93d69b090968f22bfa0cd028eaea077346a44cca7e4eb551a6a010399ad8101f6216bc10cdcaebd7c07fbab47fa8221629198b65af927d3460616ba240b84f18add41724bc187c7436f54a27c77ca05ac2bd053a9357837823b3bdd5581f672129ded931ead91a6220d16b3d479661594bee9f1fd637b012433f8e8053cbfca78d7f44b5f8c51361ec0709f0ee53f26be3494baafedb6143abd6202b8976a2252750f953ea4a8fabb4586b3225ad87101c1afc00059c22527f291cb149a428bca8b1f867a72198db2cb9fec0a82ee0d7207a76b1703f97ce32012f32b97f10d03416d81c238bdeaa851abe5518aab64c4bd8bc12a6d3c13d3d6f10b09bb935b66a71325bd9a0edbd21a87a38b553358850ef1513d162acac37bbac50384a3a9830301d01f80532613b9eb677ccb8890e03ce233db37dd260a4ab9a63cd2f7fabbc2bcd6da604b506cdb24fd2048233a672203a5aec5dbd5446d3220ff14f76819dd67acf014d9af1937370bb382fdb9ec03f44a32268402d24598395091fd8cca9e69bd90bb1f7faac75a1ad6567065167a579212b5ffbc90da8be937fb6d60f278565f8daad59d205ec3020a3064f0bb66b1304ebd5c1959d74e616589074b20e634aa01326731d0e748dd7d3d091ade5a28b31426db865a891289b6b7e0a6c1d1ad3fb3d78ef04d919880df363af9a739f5afb58ab2bd90f58f4e68f06ae407c392b957f2db3de1d6423a4c37834e9b5031a92583df2f6d0ebb9239793a6db9205138ffcc7ad962052b679d6559874fcc94a9754fcfeeedac51f301735dc65fd8c47b1ee0b0076a3a88fa509bc6bd8863a9ce042167be825481401dffd7cbe43879433d273afd9ff601c24bfe73f803bfd82660a021aa15bcd9f525057691c939dbc8965e3ee3f302eb7282eedeeb3125f58a016a3fabb3a95efa1567a0a1b14464b47ebdfba0d42ba673052c7069bbe76c649ddda60c16e87eb9dab1706b517e000da955c25446a18bfbd4e71617443aa726e7fb752042d6da2f3734cfb73cc2bcb55cebee58cf30c72259d2465df29a77b2058879a6613dd9b503daa8c32ea2878c27621972c08c3fb8946bdff69256e17caac57f909995189fc50acc3d4e111b502c95967d94984629ba9cb0704da2a8b0ea8107b0951e900effe31c24842d63e381b438cde7505797475c5340df7360e943902d5b6cbb1f5f2889f1fc8cc3eaaf3eed238ecc0410853aaf888fcac52f3e2943721a6a73baee69482067bc4b160547b83c0e9d572285e2cbe70e3b2939c0026f4544bf1cbbd351f243c3a815b9eff62aaffa137776baadfb149fdb01ccba7a5833d1f0190c3df8bf86b6de68333d071809ce08f1a0bd8af341501242306574cc619de01597b6d08ef777f92698b963a0bc8a5d837748ebeff5977a3da1c9858e925e37ab8652cd6162751c9223331e336d49ff5580cf5a063995a94f3a5ff68566c8a083208d1d19beb98ea552a5091de08a3821552b78f488de4f4dbd3138653dd718902063f8819f14f779ef8437e95f28544908658df25397274ffdaf46f7ab885762a6ae970aca914c852e90db88de13c7511e91b189f77a3fdad2e03995bc3bfafe2ff5981488656c695f0c7937efb176df64f5a4187bee70667a2d318feb171864cc5b93f8802eadff88cd5addbabd5d0ba418e46368977503a70fbaca9551f37108b6f1421eaea987f225c3b0f8fffa30e6cf933aa8e35c6875824056a6c74908e7973d1d5c16bbacd57252ec8dab4262ee3bbc9067f63d9a51db16cb7d87fe4757f0430a4673c3f60fa09d6214442d70f5226f13d10d9f31d53cc8d1d0eaa7d237c47c7a6efd46b4b2e76deca83d89411157f961749541c29c73efe8b14ba40c2454bd91267747ed7dbaa57420b7f5d748487fff9b717e3daa27f6b06f396f179dd1375163dc70e5b72b529dee833da6e9383e08b21bdbe72f33fc818df5348dc9dd06ab9b39984d5cb89d58238703ec6c9f8fd7d78fa11ac3fca7ee73ea2421e2e3a28259bbfea2ca55a42fcf28efd7745d7894d27355e2cd44a2865687fc5d0ce508ef71b0170f8899b702f547f6107ba19bc1098a6a6dbe28643599c46af8d5d15f79eff50a7acef39b726f6cd795043f5d8ef79cda7da76dc0c92fe0074e2e4def308875e4fe3352c86c0ec453fe67e2cc27bc37da7c3acd0536e082a37ad8be19fc5bf279fee98a2a096faa332b17a2f6de5a60636c39e6a22174884cb162c1f2a057d210b385875bde08a0bc081a5e8c934745b3040a64281e3baf9622c12ce6712ff2f294fa6f368eda55f81a48b424a53a4045d16c7d9057a89b3204a64c6a9c5520fc77631456194922fa04ebd0558c4f508a1a3cc2745b7c105a2d2b150176fd831bd76af4d7e9af83e6a4b838326624fd299af3f973627d838c05929d97cf41ac1d44f8ddbced4759a243320276275198195f8f7880bbecf5cbcdaf7f054ab489bfab8089819b2bd18cc5fa5e7381014f9f78c2ba6542f443f6a7ba21331798fd5fed922091438fa8fe263de4d1802669381b11b74e31785bd613832c165ae410a9bc8b8498765a8b0e2d57089ae5bdabd1670144247a83c29ba6f298fa1055966f9b8d52c3a9c4b1ed91d7296596293523493d7280baf4102e66b8eb35c68ef0cbf0cf44d70737eddf0d6c0770d84aaeda1253fedb48778de960574eccf3505ef4e39f128015f16fba9dcee9c26afed5a5366b5a4609f66d401e3338e3f82144d803a37926b70e382ede34ab228ef2a61e63c5cc4ca50c566d33ed1a79f8bc1c11cdb1ab8d5a08e0fa40407650c8468cd912b1f5d764c02df4debd94c864fbaa043f6e5a189dae9f9eba19c4d48dee6930a0d756f13c4386ead5290b225caba8fe106e3547485b0d95a7b1c43c60cfec310b2dcc5dad9f58c237729fd48d5ec65d65a2a6dd0d2279fe2e7c8482f9d5f2f8849760b1801fb444381b017ee3750677ab33614432085be243fa2e45b1bf54255de6a7d292e2871adb6f5867a025e0e5dfafdd558f396748fa5165ef89780b1c78971dfbdc2919ee4b9bbf65fc85165ef50914fc863ddabb0e4dd1fa6dea15230e0ebdcae661d8e5b51d7fa746b2d92c0b86f0bf4df08fa7388f72ebbaa3ff4ebfe5525611cb09ff62b5ec0f2f4d4c52ef6fb0aa40d21525244a49dca96f2d9d2d5d07db353de559bf7d8b910ee534e3b8f4a1b532b139f3d5830efdc8a4706ab6a35d8f8e73b029d0dc9843a89bca66d5344a3b1d73bf7a5ab2bf72ae02808125f31bcd3ece7571d8ed0b181d53657c292d7edd56832557bf5337b2c1346b33833a22912c52efd6bc6e29e7e3e4907192b7349b6b3e0844a79de2fced3a5b56773ba9a51d6f471f175a2d27b2af261ec0b7866781d2972b45884ae09e3eff69bac3a4514dd6220a7871c69e6c4770303015681e8c6375603f6c1767fd07ed786bb639b8ad63b18c241c58bcd5872548d0c57f0b0c04f076d5ac4a221f5a9e96662c925a9ade1a8219d320bcf8433f8435ac118ca29f39f75610de51f114c3174798337b8afe71a47ae5fa8ed17ab20fd6d02df6c4e5dddaae35b97051bf16370e1e39b3a6563280df5c1dea35076c7a64c4e552d28851b6f01009516e690dc0722cfe867f7be4c9c42bf5ec155aeea4e1b179f10fb45b30a60209afeaf39d6f05fc6bb1db20b0ea896a01881c09887075af24b6d80f535f30a07048f59f227f2512124c81104d0b0ffa0926945ac3a4e13ac73ac07d32a0fa980a0ae44be0b324ba90c0fc9c9a0a487cff6e25639c21c34f8135c1200e1210931a8748f73e691bcd18cf256398bbb4ae7eb470d309c6e61dc502c56425022c79016e2a48181ac56b20bb892bc4727a62b77a81251a1d795ef110303596059d472375adc76ae6431beb7edc5b95a1d6f986b984c1f03cd8ad1399729d24f6ca4545f3309a4c53af5ba57613389823bb882e360e37a8e8a843681f503705f1076bffc54898f0ac0b7888d74511130805d8f0027ff734fcc4bde6dc470c811bed06aff08c4436f49eb1949b011ce3651f69544ea1e78d366fbbe1d53b4a9c467eb9838ffac24dce0a95207c2fcad4aafd3f9136571fe2c36fb0a71d87ff60073587843d67944d78309cb5e3f1b54679a90d2857e294de54c2ad40a1654650c8118f8176ce096fd37ea402005e8e43fea720e5d894733c8ded275a1a462b27948850846e5c9f7dd2fe093372b1fcdee0431ae0a4680f6d0c63af16704831484c0827c2125ab3d51739173f856cdfa4b9241f6b68bf7afe001985d0015b6a67ea6dc61864aeae4de654c8d527058d2258f4a4af0f3f9fc64cf085c7f50eaecbf0396e64d1c96a458705fa467461634dc5f06cf965f2ec2a07d79c29f3a4684c222304c24d023bb63b801b9d6b320f74c111ce2babc15d7caab6141ad3ebc0ffc548047866b39babcc2b490df1081e6c47b6b665e72c68de9876a0b69b876df117a1caf3d3ecfa733c6f2e928e8bda0c8d4d866f32cafb97e8e892f2159da2d2bc9135de00217d21e10c7b04be081ed7f1d12defe0a48decf515d08e3641581f1c8f381554dec30022271eade8a54e6d41a8d3f78b2ff82513f293dc99cdcfedb78e7d046b21fec9477a133de42d24b0191de007a27c6bc12c52403834aa552fe6520046453c143052dd25e05b4c0993b64a2b6b9eb9381b9e26eb50b49227b1905a39192a068161202e050af1aaac3f4231673f2eceb5881b949dea3ca827d1a754cc51ea4d2c9a74167fbb40c955743d6049a960ea10682c488966dcb7f386d84bbae4fe9e8f132277459cbf7bd7a8b708f8ee642faa3752404101aefa0c32cc5f0d3b0982dc9c70ca7ee1385e892d910e0d8e4f8630f5c4edb9f4d89efab0b7a290ae87aa8cb4867b22b388acc5c23f02324c325df376582b72a9f926fd99946249f050433875f3a8f9e8c0a81a62f280a4bce1e6ad20e968b5c8a8816271cc839c190c63e6b5b22249fdfc5060353efb9e5bac50568898ff3f6bb2f6e07254f8a13f6a24291f052a71d5640f8ca25b01fdaa247ae7764d3ba417a420692c84d5750ac790fb860135fc1a1e47a5869ffb73f72d20c0d88c4837a00f3667702f1c6fa3f7d4a59b71b34119def18145c0f183431bebdd508dd6faea55c11bfac0296d6c1d243cbdf552bf548da4838b7a42f2b02205dc7efb4085927a8747a5e910c25c916ed3153b5e6d3f17bf4df4a61147f53fd3ced017bfa8323749d5082da37f39890ca7813368b3d5ed15f76546191cc81a306ae8d819f6f4990a199c578b465649df95c184b19fd8aac5ed653f1e65b2bab3d57b8be0668fa5e998861894671db9ee5ddc3f14fe8a0b8d9886eeff2bc7bc2971d7f327212dadc1abe5618d9b2dbff4b40f54243c6346e0bed5ae7781f34d3dbad548b5d48ee2170202734548b3386b0ce911044bb456c39c5b72d573fde55f2099ad9d57df10ea0fcccbb936ebd29665e76cb5d964f2a3ed6dc83e3cb5da183d10101e873c178eecbfc2b9f2dc97e5e9ff76271a782814403c89eadc492849d761e783065ac26a73858d4fa26164bd0b6ac6803e4f65f959dfe4e95fd244f77e12ad7dda7bff8115b2e8ff1c89a21dd5da13560ab8de61c161eee40cfa70de67cd8b51810573093441d24aabfb489e3aa89cdb2dd2377e0d257de9b3e232101278beb994c7ceafaa4963ea4b79fccc5962260bcc042b3acb21aef84520f9b0dbaffa6f2f660dc8f84f0b161f3033ac93c0419a4c20a3f2ca4eb125986ccc8c86781e0b81ae21533799c980b92531b91db6815cf9a9852ebbc3081011e6ef842638ac7a3be6432a4f8a5aa5a25033856dfc883606e652e247d15e04b1f56bf984b56a7d24dfa21f575fdb1d516db41d191f2a202d4fa2a5efcdcc282e21e925690755873cc83d734d679312a3a735cf81b52afb0e440e60c63aeaac8aca7de82956b23be15d23a8ed67536831a8e1aa4f7c163d657dd2bebfed908e7d76524b941a90e47cd7c99e7aafacef43325ecf534249357fa7df702884240391b55cd4fd7bea6ce658c22804600f897b43437798bed0739c862e179efb3b0495271d1c76bb98f74e585ae5ecfd63889d88ae11d8f91c469f35b874f977e605e60ef299aac541e5ec621cc82c2a2e54fc77cd76700a2d4e57feff94cb1d71e8626aa100b525ea903b80090c1d5fb544785dda6183773233b4a86fab72d0b5d4009c82679b14ee5305c96596d22cf4090cacc352d35d410fc9e775fef0879699b02f24f031e9744d82eff5022bf1e45e38840a3043d4ec789839ade3a0ae526ef0fb4afbd32299e715fae9098424c8128d80652353f10535bda247ebd8af120c77da864836373668128f42c00250ab1781e2500a4d7ab35e15b2d2ac117186ea706f4b468d06b6d1d2bcfc46c604beeab6cd94d60cc85e67fb560404d660470eb35f8ccc06d7d3af39b556afb24b31c36063bba4a3606eacde1fd0d516f4d1c586f0dd3ad2bd1dd2402c8fb53983054c3e5fe34a7fa2da7c26931279115d2b2db3aea7e916810c614921fb66dc6780de93405c1a7185f5c9a09f5c894fcfea51700522bb86478c6fd3c3538a9bf2d8963fd871847b25e001c41fd5ec18da00385c261d71190957c336134ed4b9a09dd58f7c4ccc5d45776f230fa7558d0f5361131c0005040c86455b1405574199f9eb2b5db69ac7e18364b316d7bc2b95779d0839c2bbba6e968c23bb0e8f514297350a47669070ba192aa04ac23ab88e3b79d60c7ebd33e3f1a299d5c3c8527e3be62f93b8a44951974acce41b2df782982a2e048cd1de2b67deacf2337e4539c7b4d23437ef2688cb2f3ceb6ee7f83230f9a8a52b1220036b0890b9b601fcd7b936cad7cdfc06ea087123b3b90093508afd2824ae7d06678ab2b3f805466794ee4143036aed6330d5b37067fcca3ad6f5ed9de8f5d3eadb84daf5603fd2de98ad13e00e96c28acc14283d8a1c8f9f8da920fa0948362a9cc59b7bf0ddfddb3a048c55d900a590e388380fea091aed0c1616bbb087622d1c2e277b6ce61bffccd8295ebe3c056053767715f5504dbefe630b531828f72c6c191a70809d92a62e097fb525e324b595abf9a62d74227da7f1e379664382072931ad4e4c3ce0a5e5344a7cd404086b1fd107eb522e341c3896863b08573e84f84f1c1e3bb9d744ed550682579a280c80195982fe548171e79b0d3a902d04def056b5fb6d5f06914a33aa560bd986ca40643f164646f8ac82b437bfa84b707403167ae3f3dd093f5790ba38d1cc61ad6c8125c2d60a3cb28ee3c82900e9379ca36819c8d3499134f1bfae6401d4386671c14a784f58cfdef16e6a9d5521a5d710a084dc373b540c5a2b0def40250e9f1dc78e7f2af9cf395ea82e691307827458e2e49906356c3dd11791b562e5a5b511307be92fe125b4393d6caafe1bf006eb685fd7d4cbf3bf528d8b1a269a2ec25861e1fccacd55731496df1927b7d6260d76b0d3587ac52fc3f1b5d4eee024820d5032415d116b8a4c4ca722cb536595a60799b3eb50f758960b8813923f9075c73ef49ed725f132657d179a43b7d30ac6a46c3772486e71e80b997d6d5505bd691b0ae520e9ca0fc0325d7c72a8b2ba66bbaaea7295bb461507ce656549b5a73a37cc080264f93112ead9d60cd920c9e7e630df9429085d5a559424de6ea6d6fae31aa7832310625f1d98ea9d12a8c6b5d2d4fbb27082c582f7be37e2b510ce52f2edd8985c1da957c9c038f8f69aac12aa0cb83b10d890c97d8ef70d12314b3e6b52d78f176badc6032bf64e1f579e390fe31ed2816b37e93073465585025377670e81fb4a7fcde7f93da002f4d2b411864fd22871ca5776e563ce971f48b14b736e0bb1de31385ca755cdab6e568249bbfe54d7d33ca8fffc3375ad8cdbcfd5a205a1ebbcac8866593b64596b63517f502cc9effb23c2b87641a36ca07484551457ffc56db502dfc722905c27bf0099232fcef1d7d157df85145c0de99e75d7cc865458ff543c981e7d3faf865377331b0746caa17f0be9f93f58f1060cbef52711f1fceefe19c2f9e360bd9475169ffda3beb1ad28d6fb9c6c99f0c0615082c731526af54baa00f23a765d24915d938ecc3a85055b99b58577a68d94ed1f276b0a0a55f495c94aea5135cd315b4d9976b9b68d2dfdca896db2ab15fedf7221fa0e6317215aede5b93cce9c26957b11e9d2f03102a89b81eb75603b36f80be55319ba3f3f4ed9053331f13150ba589d1e309c188706b0d97bb613d321aff02db376fc97e4a3a1931369adf88cbc8441be58bf9b3f4847ab7c2894b2ac2f255593714daa4a97a9c6689ff5a98d7d6de2447bba2eac0f15fccf994ede646b73e2be056ffdbc7ee7b3c0e8fa81ba6d26cf91e0899e5da5a396ba89e1bfb3231d91434373f0b53f84272b99b85aedbee1a38aa2e07fe040f3111105215492ef6a8d7f4755442f9fd9ed1d6f485cb5e5f07124e42e9dd3b653cea7ef0e0d9f5b969ed6194f25d837c0951c8e1120b1789c7bb5f67c6bc76cd2a7dc6bbe6528426ed83e0639b3d6c14622303c781510f52fdd6cc682d5214835cbe9cf38e66acc20b44e560f103a8a873790aa3b8fdc1bff75291a446f7755070de755ad44c64b0c757f6ac8a655d2b5748498ba3072c060c6cd43c0eb5e0999e4cc01d7998b1969caa963b40c36926837a9cf68c07056b08b1dc70e51aaeb30a3c44f14c9dca6c0855b8a9083480a3677997180e53159131585810d544072a681b4bf283b3eaf5bd70e20e25af1bbe957053a852197103b1db2c80d9108b7722f951fe232df1492e18a3d20049c9ed415aff0b4a3581d750070ea1f6aa76009b1de0f147678c5ee4145542421f910098e8b8ec4f0e967ca2b6fa8cc96574088e85aa477a2f13148d37babfb46195f25b702fb7bfffbd73766947751acb4975227ac6253d8410e34430b3962b18db6583f9b4a0645014ec110f5d19ac895f540a98928767dbe3007a15f6d85d66ca71e853bcd018f7f083e96eed053a01f38d266697504593da9e31fbe60484bf932805682d9ea12f698d4a2475574d0b56756e78febf42067a3c6eff7b249b5ffeba100c06eb52764deb12fca0156086c5db2c0a0af3782b7753161a35d61b397bd2b252ab38ac98aaaa503747e15529bcc5839b72b096d81d427e0f5bfe74b9ae671c055632bf3578031ead837e605ecda9f123d99e65807ff494c8e31ea622d6617665d8ee7bd86d9c7b3772c0502cc3dd62505cdec67a0f3320df85e250939ba72351e865abcbef06013fe8d36c76ba361d622f3c8e49e882e2bdf7c8588486e43074eeec2aee257563e510e7cd1113eb7df74991bc7b9c5df51bddadce4a4e71014c4032243546077d6934c56b6c51f1dfc5c9b86384db260e24f4b4fd2a39b2f8acd03a831572313cdcc4fa4c40cd4a0e6cc52eacb0a6a2287de86dee4bc28f3b98f6c8bbbaaffffc24eff11427da6daafa852b46a7b58e477e67c55c79432b801cd7e96f67e903489e4814c148a44617cbfa49f54bd7fd4431361e36d14b4898958eaf38da6f667b9b41f9d0669cd4081bac84d102e3ef1a9671e24d0c241598269fb6b19c4fe5217de275bb9ffbdec7d86ec4e51dfd1539a9a349cb4eb11d08c3be69a9492ccaf686db630324f60e5e5417ed6cd3a16255a5127c4347d25cf3eb30fb0e0d0997f2147944a03431f867c126cc69de4111f50b0f51659efaca602fb4ad4a4583fcc45f49ea611667f17b88a1904286e1b998d1730e9131e8e8764614c9e527c7ffc740ffdaa9b1e9300e7f489f8e7bc5d0f02ddb35fc3e2e8cbcae44d87bc51c2eab2a39c34b5fe60d90732613cbda8b0d0099f7bc9d50fd22aa384800c41eb640ea98623a09b477ff821e14273f17f16c08a1b85d0355bbfcbe5508a7bf9be8893e4ed96d8457a635d4e49af91781dc325442a21823882579622c94ae3a12dd800f2b34b4a72b7fd31f17dc4480119ef619b996be864036a835f165ac0371694e1fa9ec9df66be8b8d26fdc30e73aa9d7e993018d3d721feba6ecec83d27f37987708a94e1e590165a1c3ca26ca931bb88009aebbc0284f57c05e855274dde4d2eca84f13c3f27067ca2e512c8f2dc4fffcded75afca4395c9c65f97ce22fff98d694f4df10f84fccbca75806ff4a46834ac1e8d956e4e6099980e30fb1dde0682c66248c37689c52ff9ee49b92245e57726104d28b6b89e6dd591660190674a49ed4c4834d5f66230bafefb6249763ffba32b987c5195ec72f6879298200fc32ac59681309387b49d2843911ea2258201844a14cade76cbf852a821ef6a8093e85dd9a5cedbaa0b4484f9e663779f4744db4506cfe9c066ebe1e4b37e61fd7513c722c9aa483e69639f9098aa0d8d67ad80575e707cd0d492cf3035a2d2c7b3cf35b2579d8dd12d02746f5c9c55f1f18e7e759b481c291de473d8ed7a9bed8fc26a995f1380c7b6f337510b52b319219a51ae068bacfac153e6df59527971bd1db8894b9bee5d24a5ef24dab9200c1a26c9537864980f3eb62dc88a216ce84526263b17791c45eb89bb9790dd856f1c46db08042bb3171294754758663c06561b6dc8ffed9e97110a5ad4e13659d75f76bb247a259e883454e555a21ee7a203abbd0cf94b671ca9374b8ffe0f8b2d4a001e285402f80a429b5bd677932b4e65c7afa9efa7a605f7a5ae1b4c1a8db675e14704c047d776cd9340fb9424e2f6af61140f0d03ff96047bebbc62e7db6a47a185d32dfca822344f7bad3215349a01cfe000524517aafd8ca5314ad700756d2d7f25c80c6838905f1425d49159b02a200752e5c760b89a8d86229a216e6df7c52fce053de4ba5acdb936c63aeca809205ed7a65be9a1e941f78dbe28fe5bea284b91fdefea92b7c22781ca9b843719764a0cb5917b6699937f77bc4d2b1ce70afbfa7aeae5b758683d2002f1e9540348c21748935c5e88fcab4b59037bcc7db134c35cab41be2b4d900258d59e5bb246d15162ef8eb652ad0acdff46a49c1d3b60e51f0bf63e39352b1cfc57a1e673c326114f914f676bfb05d174588cd259562e096f8317141116f76aeb6a05a492c393f5c6482399585e6a3a956c85f90d5c9f0c75832bb459b5b8d833dc41ac9e00474beda81cc930476ee62a1709b974af838ee3bb7999f8d3cb0ad85923e1260f645cf4729261bfac5d385e661ceee0135ba245c86490570e1def3278e940531d2ae2c163eab859c53355821aae9b9e0009e6f5e045510d461d9da2d5635d1e82e0f0a9733edee75a73fb99d1f6b71fe5375739189bcc703da56fbc71130c07ba504614bb25b196d1d630f293feb4aeaba41d775668cb91c02d635e2efad46666792af0a2eaffb43e1385299f06f91afd68852e4e62a53f5fac6bb0a0fc84d3b984b0d6da6de120a176ea8128c9f0e2bac1add269cb515147b0b280b7f226828d2c578a3599a7e7c316b433b12e3d58f4eb6611341fe173b1411882c28273cc2d35b8e9ccbcc9c14bd2a2fe07202a0913679c3eea433e869d8561cfc444ca93f3a5bb31948c30e80b60ef543c83756fc9b40d01c7894af1e3e96b55c4ca53f2a45d2fdec0d7d5c6031d3e7e55775e329b56edec6304ffa36c09dd2b39f2b18dcccb2dd4aad0cf44bda010f2661894a9dc4e192375f1d7618ac939ab9b774adc0fafbcca62500a77c54bff06783b48937536160cdc62bec7b0dc524eb67406015559a47ab65508032cf58ec7b993933072736133b79d1ec8985c8a7126f9e9c1c256f11e4722e62ac684b122257d22722fc2612dec4361052851938e5a034bae9573689227b56448af210b1286d7e55a15fb0b48c47ca3ff00b081a3653ed8e1562688217c44f9d9104d1c138a1c25fb188bf73411e1c37b9bbfbdcae9adb4f88999baa8af6ed7aa1952752ad2827622a8ccea43629e40d432884e6d6226df52f51f5b72c4fe10c144a9bd1144bbdb8ff9bd36a7ddb43862c7983ab21687cabee9d666f3f430d295573855a4b5109adb6cf627124eeca98c71d77841e2ba610860cc9a8e45738e7c2d1ca29bb1d944a7addaf489e978f979f3a661ac059b8c33da95af1d7d15b445c34ec6c5a87682c3498fd73862230fdaebf263165ba9567e1303d9683e40917945d240baa5863e7fb115e0d332a8c65c332f17cbda1d919030ed894d6d5354cb04da3a64ae78c7f167dc102811e631168204cce00ec578916a15c33e5b10386c458bb9b540652102e546c021c4df2e8dc6c1131d9457c2fe4d298c79ed5c23c0555f55ab84372312dcea9a4e223a1d706d9c4474919eb689f1fb1bf4acc3ec2b065184286ebc85030e036c941bb147b322e4f0780db04c13d434d32e94b29aad3a45a58d7160407349a2256cbeffa5de457c2423df162027b8c694f8926776f83f5059c39ff0daac263f7e0f2d02f23fdd24f0205b7837ed10434affb4d00a07b8ed90c8ec80b6810fe5e44c267aedde407f8ddd6820c3a12a75ce8cf89a9251f1a398276b869d345eb16c3529a6236bba36107aaa4bebe7984a496442a05fd847e7d1f2f58474510239972680b14b3b1612b37120fce054d7f63f52031dfe12c0ce927272ff7f8bacf2f3c606ba9a506c9cab65d4dc91a089a46fcae8373843979dbbd749853ec53318264254563157549e43fe5bc7b29dfe6b3b0770607692a907bf4f507a5e512170ccf1b38144d2ec527fb6328624b981cf26d35aab936292fb455e1c68ad2cae9a6e7fd68554342ab20ac30d2b35661348ff2af76c8b91e1dffdbe6f855f6c7199953f15315f4127e4b273850b3c069f159d5e636692e876c4b5fe9d7e8dd179a9ca5590af975896e6ec3f266ce5a56c5c5ee8755ab234f40ad2c2ed2d0d3429ac409fb0fd4f698681e166d37dfd51adfb578141bf87f5853b648cf19fc99efeebcd0f8e83c92e5f9a8b3c275d8a86fc87324bc742a16d223338d465d4b78d67a785f8f586a426a2552c21431c20f846d3e89a341c707e57a99886c5d0a4df9bc98f48124e5a265ba26fac58b749938781f0850508e113ee8b3cfd255f18120e5dd5ac9caa46a715a4fc3bd14dabfb66610972f68c30859413a833794640d7a150530d6e17c75bf2ea3a008711fc81c46e1f270e3072fb3c79ad8f3bd42fd03fc1bbd363df5c36eb72aab46e5902296e47ef8a374666c1c29656617c3949f8bb6cdd7c7f27819df1edc5ee50335008e7ce98a9bc3b3fd1f7dab50141528a707bce2a15e89089533c38eb96d83985270cf3c5463ee320a6bc369d4724a98cab852fc64db3991ab6d72ca357860e6be9fb5a57b65f7fd43863836aaa36f7e543461aab50c0719ee0c7006ed10a2cd3def4e406af3f1ba0657001a6805ac61b8504f5df31ddb77e155f59bf7ffde13c26b7399cc72b97c35d71140af881a7bcbaf337c2a8f9a59f3b2f4932c0abf2dd17938326fec8e3dc55898edc386508a1f2d255cb4c6abf693262826364c1fa2230391e01f9f82d62fa3e33777662cdef259c50c19c39fec81ad9493a73717af6f26d770b4a8b554356e4a9b2503f381ea4fdd8377f6ba8d38a97900ce39b3c7fc14db6b4a9bf39d0881cd96bf5f5ac15f7aa8e12ca9732ec786e4daedf7cd68035fcc0a13f42460c75a6cb7b8c8a395796097ab447fa4f729bad44933eadd336d1ccf2149d0cb4ffeea093069fffc269c88c171a0fb47621e74719910e089945b7589a39c4924ab20d5bdb968dace3f8b9fbdfac4c9794855e917d70301ce6a6a70a91ec42674379a15bb868d99760af3eb29f5ed645cb42b18bf96fc2c132324be09c5987dc8f6b8e5d6125e54c08edcaaff43922dffe1acdd4278c0cb04dca01b78692bb74947908f40e0e02b721596444be545c564bb1968132b4679a6dbcf5b5215231b0763799b52812afe9870db92a1ffd777dfa7f3ebd7eae837172f4e332f30119d1d72bdddf6e7e502f6e747110eebb405421dbfba7da2fd6fd0d7f7fd10937682ce8ba279d968e94eff7a2e5b68938360f5d1518c08f0b00ebc42949b85081f767e2b680be1a4f30b5b3d8c1ab0ec868dcb4601f97481e93677e7a4027ccbb60ed6f89a4a8bbe5e445dba7f5e853fb069d026685c310e5e1c3318cb67661113fb4b4a65b9837bf32ea4bc17a7ccc8e2c06c14b42f7868327bad3985cde667eff8d201d2d5da847c3d4d91a2802a374212d67be5be3a59ec5aa5e7f5573fa8eda00ad5643575b97dbc4e79c6782a9d5f69853285b8f0ebb746e08922c4361a01ced7371eb000adc127eb654437f84506d1b4d0e2fe6d8b6691473b4be1f824a31bb2a9cff93db279e3a3c0604479c92cf495ebfe4b7e2f2e49a1fced1613661a6b806241898f83825f9c0f4cd91ea880128af4c3879e975648cf32d80c2cdcbaa111b36d01acceb4449267d81b2167962b342a0482edcd6dac5ca4df14406a477bc8c22a76ba3b1404384d454fe5d333e401490c4d7accbf20a0b36493a10542cd9dab8fb542d23b4d0b57a2c07ff4b5e421205171fc11621177f168596e90b1075145af9cb7af364270b85a515784d6f3fd1b99711291cd7930d34612fced5e25bc54d2935e3792b357ff2572995c31dc220162297b49a6fcaf4acffac06bbe6195aae45e13fb3d9d185d5c921ea427f798c22286c49cceff88df8bd4e81d543ff4543308f0a85d0a06f93137ee28bd5187277c56c159bef47a957a288bf9cb976984b577e4e8cee7ae9482658f0006c804592400afdc285da099f9b7c61cb1a10204d63014ad50967e7d68e2f8b3a30ab8a03fa5e60c6cfb87699a8bc26a382b8a113fd6be83d618a002855beec5f62c73d36e3c77687cdae8bb644bca2ba7b6b3474d6e454e0288b63c89fe782b9b74a4e1ab1bd207061d9454a8298c0794c7f665be836f47e2cfb2fbeadf9e4482edbadbd01ce9e5af9921f8d8f4639c28a5e48549ced6efa41218df42b7dcfd1870410d9573b59b2b4c3d4a09b90e4c2e435a7d6edcc824deda78b3f901a126501df72e68060babf3f05ae72522d113aa6ed937142139cb8610b92d05bd76a4b5881b979b01f73348858daac786e233a34672b977361fefea4ae4e91053c66bc041eafac7bd45f461dae591c41e905ce02182fb4cb865abe95f7c23427c966125a6a7e974c56b2ba2a5f09481b3a94adfea77872229c43d519a10b4059503ef652def8a32a042362b7101cd22d970dec71d3e87439698b987548c21141bb99d275880ed48828f5df96deea362a5ebb7a1947c4a9da4aefc56d8fefd8b42dc5544df63f0da05f14395dcb4b7f7c9544a8df8263557f3e89e5430b9bd8b01809452260c23b222a4b3db17f430189d2c6227fcabb320e214717542872e50f3021667b97079f631951b123cd1d4ddfe4732aac57b4f7c0417c9ab5d3d0e6e7b089fc1063efcff04cde4dd1d021cfa285af1ccf7ce8054d112c2f27df0824ae44f953739e8a214c18e981d84b40cd996a7692c1b13589a786790047f6031d5d5c9b8889b4221534965cf1c3587c3434d88107ddff2a2d0f97a474043b49fbe54c437955b665111582d8bfdaed0ef862b04fb986301f86238036bb62d5821a26c6e658794a0f98a04857bbb00267f59574533022cf1325169ec3a2708beded1a27f017140fc99826a4d44c124ac06f10666c1fa8330926155a7b7e435411a247c3a1b0ae15d7035947e439473f3d23c5f1772a775d5adc4714194586d5dfe5bd6b16482a395a50184b8f3bb502538b659bd50bd3cf46ae5ed43fb74ea15e76e940a2a72e3cd9b827fb7b01e5bbb951ece9b62acf9fa4d2eac3372a601682d1cc5179a0389175f6ffc685a4f913b5922b87d899cb7fcd666475f7690664f7c0fbfcbc52363b42e601ad6537fa34e80b4d99a6e410ed8980dd8060f6193b9bb00b987dca135c95a0c225ed38eed286d7187a7ebd733f1335b6aabc404e47c2f8cd34cee769661bc3c7e3bef795299c0fb21570b929f6e174c577e49931abd84c37adebd70dd90e512e5471de20c7ad56f1071621158673b35dd893bfa4290d7ec8093eed6c6dbf6c9b0428836cc2c7ca3f54f2f21afccad187bd916dcc8d845fce3c83aa490bc74fd2952824ac06a58496e3cd4cb5e47927c12af8c9705e722284a799513b50151b5abe7403b8523e6717e04d7379d28f32d0bdd1939cbda14834860f4e6860b1027feebe336eea665aa94a032ae9e8f07e7e96e9bbe4beb14490b3d1d863d853371713dbd484f9bc448bc29396624c588300c665ec07ab7ac18184a90973adaf0f5ece919c160ca3c729f15e01cc6c0858bc44605d2f8728416c122aa1349f818675c98d2444921440733dc077eecd405c43de5082b6348d8f7f0e52f370f8d1b679f0b3a44b8d662cf4054dcdc80835f85121276b61cb8b08842d436f9754769151ae9ee84a3f3c57b9f0fc06b007f3b95742616d4ec7212484113d53017e903b57981828e53d4b4eb7531c81ad7641291ee0f9fe8067b79d5957e36593126316f1cd861be91406f6602fd22a2a5ac5be8342a542c88035f6505900170ffa0897c4dceca8bbdeda1adb259938f70da258cbda693594b101a10834e730d11aa28fbbba22f274d1530bf2cc2c056fe8e35ed97031857f92bee83a7c348859548b5bb99e763f4267ff07772f1e3c0b8ba9c50ad2006c31c087b02c507cc0195a8dc7eed7b3bce2ae061039952202e85295bd2551eac9e707c91e2512c5745724671027a406e5710db1977e228098e4683f751681b3bf6946060cd8d40055e4dc8f7457586563a18813fc3260592f4cc51675c60660be55ac3bfb658916767a225e161d7c8ddc6e865b9651e9bfc076dd6a87c09d7fd3ebc2b7589661bd967190031d4fb517fd40d9f50086b4ca24e0951b3ff64f7079833f166a0fffaf5760b30caaf9197eaff6abc9771c53a8c80af4a0337d30703da0b02e7e5b83a04bd83f94c7c186266f5c9ba3d185298b7d3c3215b81fe93a24a81471d6b38ec3f010dc1b7ab0ba350f6ee96ee5983c1770b2668b5c7e39def605b14548719bb5c90d49f4d4c448697418bbda2f8e72f06b7ad8ed75db9038cd9ff80189b00697d672d44707fe7916324350a851b0a640f710a7f67123459374ef7569666ebf24398cb970a537882523cb1384657e68dbd5e6b2079f6fa9a68f42a9f2d8cf82697b596a30b462065439f5496348a660ddcb4052aec980798c45c487c2dbb05485fa2bba34a60fb3bd5bcd5b2d47e507b36fe411b06eeb1ec9678886d30d32759aa63e678739a9c049a29ca170fde5845b9aac619bf2fc24ff6746ff7020fa3b4870fb295d4ee01d948a98a567a94c09b4336a7ab5d5a179a0b0ca8cdab2cf89b3c6721d4c96e984ab22c0ffd7dfeedec8c731916d487b3033a1f0ee93f79fb395e1e2d53c1d86b69fff952670b6ac6909065e7ca6fdddf0a3a8efd2135de940eb13567e4bf1084881297da7f5c6c501443dfac9459f87dcd15e67bc6f4fd7994ed0d9901e48d5d30a109ec26ebf469324ad5157a753f976974d49ee35e8392ccf16428ab5918bc348356bb83161719c9a910ff295c1d59c594ccf21ccb2c5b9a5e5db5666e3c5ec16d8ead73e9c8a1d4a7c1777f171da2d3b540e4f3c5de23dda0b2f7e37d3451ccf7f4e37863d7032adbe1a9a1e0a4f0003cccc7e0fbe20c2594796fe7af39041c4bb15c99fe26d776734541942d45c8cd47edc71793f1e0e034b0c17e6ed9b56e5455a3a576dae9f1176d7e6365ca6291a671b25dd124f3e3969ec91cff7da530cf0acffd27d5dfad96961cc41c7784ff6dcbaa255d5b6557eba261f98ea5254c9d642d95435f6bc737a4fd39f1c9a2ae9a36c75ce6c28166c6fa29a5541b23befdc4884b9bd52b3c5e9fa2b3660bfabcc17dd390d32c0c2bb371903ea9578dcfe4b34d24a5ad84348a455db8a077f6bd87598f57e9c02eaea5b2846c2d7c5157a71f8250f750649b21335f13d64c783883b3add7cb3510a8d4c6fe9c9bbb4b01fd37762cd7ecc7b790b9700f996c7a80068d8bebc244b16a3b369d9f7850f98685f47cc2d897b8c2f4fd278c40c4de970b1f6e4e734d731d99074eb421ac9b47ea714fcc53c147b4408bd082c9fa4f682d3f7169d4f10950f9fb7632a4c0c2d117d0f5d5c9223a216a8cfb7b52365c8b93887fcd5c5b790996a266f75df8db1b5ecfc0780ea9b653d045c3e9d7b0429b8dd33356989ce2f1a456ca73c2c76e49e26cd9bc4c000768b59b22fbb00a9e038026896043e79cda03f5846c331a1e555b4758c4b0fafde03d57b9deb1ad2caf5b70e40b5f26d94991f913c2cf9dbc68da6dda6d3eb03d3f246a8e06669a17311aecfc2e542699970f83394a201c8482e2a34f7886419aab805bf3eac099c38dd38548a031554ef24f335f613826d6fbdcb611514be53244753ca9558e24e4ead595b71b20de5252fbe7399d984aac97204df5bcd3e884db4b3951cc81fb43b512940b81009ef14586e6cb782d575ad8713620d220415879bdfebdc4cae2974c0ef22031abc7db73c2219c95458f62737640b700984cb28824a9cb8dd10e073ce4452882bb876d938cb393cb49a6e65c7194fc029b958e95107968623edc6ad40a78eba248590b20ebe20f63eca8abf04c1e217c36f0dfd6ab07811ba111ef31320c6638713af3e1cd763df41f0d9b53f9cca2d3d070afee1872a05fa44972a3bf5e1b7cd57aeed51054c629e0ec142d3700f9c9fc2e7834dac82660fe88b400bf19202bd22143031082a06b99185f575d64f77fea0d297b608ed66aaa9967a5d087f397efa89a01d871bd73ba049460b7e77da4069056d48751e09c08468a30dc8632451169777bd46f4c3fa20fe86d83f3c7bad444574c9465d2660be8e2af5d7916ffd6454878780582ec26bac97ad309b8cda1f3a500fe4b3e32aedf1ca6647b0791b50aa2fbd6ab009c0ec32daf878d54072ffb5232e293101f557793b86df438cd75159bc8d0d31e17a5a152b2759a781856f044413b493241a3d680027ba6f37e2e1646b2fe9d8aac9e930059ebacda41622a3fd10cd404309ac262d15b541f077c5c680bbc124993774c4db59520e13131acafa0b481b5f97337dbe131f37f83f9b33dc0f84b46d5d625657e8a04f1914f1b399f92661b60d1395f1756f41e7ff872c70b76e7f929080b71004c4966a8900b9e0962bfa421b1786403c8d59f3f7a84076597327f9a539428d0e03a04a41fcfcb964305c85d45dd1693d0b4df7a404abea2e894238754cec0271489eb139fa9e629030c66c048601aba0247275cf8866671f5870443f4d1d4e781afab5ba1862432d2b0f330fd1690722a12a56432c8d9581b11e49837df0ab941f45c42f947f4c61255385d18f32d59ef87e08c7bd6b77fdc9444021f8d3d196bf5ec635a700e3b796a9829b6fceda414bf179b58a3033a02468f375dc2ccaab3846e8b3ba33f2ae91d0b43a3c69e13d036a72493249e5fdbddec6359b2d810106ca00112705ef43c4525361a0d643fc16e1f058f16f5901b552f6dae55f4a948320a46d98250cc5001044a2d5a498e0bc43bd5c39374ae780fa23f446ff8c5405147b6eaead7070b5da2f2338b751cac23ef9f88769cb9a642e438e4fd5dbaa3ea8db46e947ddd70923cffeeab0410215229cf0e5915b81738b774ed446e20596058e49c675776811415b2423681029f85bd40f40fdaef5e515afaa21ecfcf3b0a8e8fd2baa03b8af643f60c358a1f92d9a559a077adbbe5211aa229824ccda6d33100d9d5c54e995cab534769ea26f63b647650cf6dd531f0507ae64a456463e355139c7199a206b5d8e013761a547ad53e86d18b76fe5acf510a9d2ea8df5342b362e7e7cd4d5c01c7e0953b4453f490f74d2ba97dbdf4b5e2a61a5fad46c1709f7221e097a683fa0770c37212f6f9d35a4c1dbf8cd63121e647e6a3324c2333336830f3e21483338b46fa09d7c8f0c17dd51bf8a1dd3f45d52d077f07065940b8730155e5f4aa1c6a0b5a5143f01291ff6a9e4a192111124dc9f588a622742ca147ecab34b4004cc6d06794c0fa0200ab840f0cad4d8e526bce09e6132079679994d8d1069ec603cf699022b8cfa1e66a61c0ab2c9e0eb60cef9f34b1f92684c83252dc2823b402f487dafff0ee1d5cea845c36b0b832c2a2300915d3d26e4de8600e8b80339ea3bfa3c84b046990f7e70deb1b7075211e1017a497de4917571508b9968b02962774c28f53fbc4b5c39cfcf3fcee7676d774ad78fda3057333017436e5f9b3b8f7e11ea88cdf58faf5357dac68cb18578d2e446cea91b987fbee2102c4c324c600f39c562a7bbbfee1240475f1298262d56f1e96df3ad3670cb3f80c30acca2396df087ec6dd6692b3d044f17ae9bd453d1fb3eede19a419a11a8b2a59ce80044f56cc5b8946ea9a95e12de265edc02b14ebf09bea72950f4b75ab414b8648b80bcd24a276c9660b16e1827d4e9ae7d0b213309d431a02e9a2b4fa2f24cafce46ce3d1403184b2f0a89bd740d0e8ceb0878b52969f2cc02a6b727f7365f6d485b032644d9c963a51015b345e17bc95b8be9fe4fae2d9b967a92f89a1cc348ad9320e44da9903460230c2e2296fa6c90756081386b7e334a5fcd721a49a1e8758433942cec0c4690bf1b4da4c27057d5a1cd2f2cf7ec27c3125c0a86ebe37b2c829978707726b76b6b9123c384c99777f92c1cb036ea7289b28195d9d2d7d4139bbe8b741c65840f05f8e7a4c2df53d2d409aea372c407ac311131fd08804fa8091cfe34c6bc10bf9270322291ae278f8e1e3f9de3ed79e02dcc12674d2948cad660b4e5ddf95ba14186f89c0a56d2371e3e834802f9a37c86c4cb81dc13856ebee04ee85ed1e0101048dfc1d45714c314384a219f48419f879cfcb4c92579e78faa9a4c99ddf3da0765c45e562ceebe7415f6ee7816303797ec4cd7e89cf53eb4460f4e25785c22256269a762446254e0205d23088344da2e648acaa82d7ee7a1eb35bae8e94677c79139b9e27f6a091d07c7abacc56ffe57aedd7c63d83783c19467dafc58959cb81d96aeb0e87adc7b445f11618f19f63066086a076d5a68ccbef58dc4030d5defa9b1592c21573186fdaa47f9aff497f90ef5bfdfa752c6949ff1ff3879f653fcc54ca85169ddd7f40b512a89410a3679fb66722b5c8330c6286794149c0c81ca91e22c9b759e087c5b7876b1876ea80818dbfa1a5396fafbe041316d2d52af0b03f1bc5a09018da63ebbd999651a653e5109dc0d5c6936af9e7d8eb8d04405e5913edf505fb561e2b1d8b963b86e71d490e60b2fa72c72817aad0990bdb75b2c071f45af230b40de1d88a143e62469a646f2232eb80025eb8309033488c0dec01a74b9d6e70b3732e3ea39fad68ead6b0c26404144695a6b775d408b98a9152ef1faec2ee702b5264cb5e3dd7b5c77e701513017c9b2781e5e9ab39fb9fe0bd6cdbeabae8744994e23b694ecbd8e045d396d6dd08181955d4bdb4c5dca61ad19d92416b2e0740d4c65be9ee694fb745282abafde9b0c74d7d25e1bf66f97da7c27555aca435465c3f2f0e50c6c307d3e11ff5f7162b66afc65c12fd383317a4ceec64aefd6d668b46a363e4a10ee4563faaa30120ee75d1321ff9ac60a554372a63b55b577e323d3063f0bfcdeeb0eef5eecfd36d754c3145c74722b1554b230a3711690ce25a9cc4b49361d89602183ad73475c65457be235037c0e41410fb1e08a234bbd554c24ab351fd91820e0a89e1e5b754b7679d3202cd55624bea445c739dda421332830373d657a8346fb52581b05a4c07a08aec9699f147189eacdcbdf5b044a696992e634dd6931e9121a6d6720fff3fdcd560e7209c2ca39090983a67a59e6240f2a42e3d3f0f1087174c9d9f77b1f203d8f2a2def5c4c48b114f6cf22c122fb41d63fe0614ef20d5d84e061bf71beef572146674ad7ba4a3a37891595dc2c96e0a038fc1e59fc29b9a86fe7ec57a422d924aff88229af95b1f5ae3ba4442192e442eb6107d8cb0e64f97244c66b1759d0a9b7502ba2b83029806516db5d8d40d8034bc7173c66876bb7742dbd3437bc821a42d96df4b139b3abec6c08fdcc3d36418f8baa1d5f58616217007d82da7eb4bbfc848b4971c5ad7bd4718c87a6a68d0f526c4bb71d52c22f942344c5773b3c858cb38ef364f3a96f93d005988f3ded236fc5ad0e7bb4a5a92f5a5c6c9276e901cdc310609c850120512809fd514823a56272bd444e621789fd344256525012144c2c969abb589b4276ad087a15a2c1802c0125ff02251ae594755200e967849c9b4b9577199cab2ec9afdfc819e23805723a131de9b0de9bc8cb959c0b95581d3bdd75ed3dd3333d0fd8774218fd2fedd2e27c69998d9c06fa80dc86132de381b622b4080c0e815243dd67acafa08d9b3fbfb53b124a451ab814383bfd591bb5f65a3ea8348fdbb272a4ee006b9635117d59925a356ee90434c81f48e40cbde959c51990b8dc58bde9e933c40a2318907ba84b1136dd2ddcc14910cbc79246f90f883b2e06366123f0e9b3ea6858dcc820324ba4b57026184c6d5ffbcbe0d5828d7b531f0ebdda63294b02162fd7b07e525b39a94979a4a3d72f2c80000991246242f0d59138e0a0c5c61dfac703423ec80eba894cf5423feb4734d7a5d6774094380058858b0aea23ebd25c0467d32078145182f31b7840dda732e4e86dea6abf85fd9ebfc89a8d5a94ab4eadaf263daf6a36ca71d0bc335e23f6da9abac8c15dde14791c3d622f38fa1ac1f53d8ea634bbf56a81c463456e83ed2c56cdb09d117aab10d50eb52112103fc9e042399db6237a0a325a81945b2079e1b41cfa3f61638b1e68422ab10c28049fc430274f09eedf7dd6d8bda694dc8d9e00d51f78ef6eef0dc46992ea7ac752f69689afc3492d9b826fd49340ec8e38f0b93218d8e89d31013e3787fb7bdb425a036bc6af06dd0ba97a79efe83b9c1224062cccef1439e98d927d1f102606cac03d31bd1748230086a16040b2b38f3e5cde06c1960f61a0f8ec337142f12f86344f1a0f267f6e92aad25cbf5e616a803812291e6a870635537c4b4c58fe0463351833e2208c8ebd876733c6bf4a999a456f717e7f09375a7c951b6328c34df325cc2418874ee80ac9459636fd6097e17fb601c4a550805ec2a9532baac7648f863b9cc9f056550d97516fa27b16ecdd3451084c15c029e5adab422ea39314404ca21582255b14db8dd6fff765439af3008bc7416dce1e439b977eda22c1f71a1e8db47c7eaf4d8106b126cb77567c77f23d309d434804c93bf1790fee08901f08aef850e7446807cf98a4172d4abce9cc3a185356b4b2999484cc71886d6e5a4b8e4c8a3d5a1e5fd073fdfd0c09436f93d3775b8dbb6aa9f11fca3ea56c2f565059bbcc4e05c50489721e116da3b8060871f4435d2ea0cf9426044d16a3671dbf257ee9ab46cfae0bdbaa14a30ba7d104f4539dae0f6ef574cb3e9b90aa98f7731f5479851227fb02b5ef95069f7ef79af302dea9653ac99d65ac1efb6c47256795a7e99302482e742197380e0bb90e287141fcd926ac683519e31326f50ac98619a40bfc392bb4695d4d7461706c9fe1737e0afa200e3b7abee5b0a1e7b75413265f3a25b71e959f874ded6ff20785e7a9bf3678fe69d3e4e00aa1755fd13f7bd88c2ce044ba1194e78f7e31a01c717053d0233c3b27fe15aea4a35d4972b80d06367f2c9e1dec3ffa9eea155dff2108f316cca03eef0e996718b122beef7c263fae41123fcab1a07d6b218e215a8a2cc09d22783bcc942e8057d9e37e1cec332306bc6f7bda2bf29fdca22f12f4fb2f2fcfbad5f0fae851cb4fef9efac4c590a99add26734b1f04a7b76f9b6165fe2fc5e9a42cb5220cbf27b58066b16a970b02ee275ff4ea8805f270ab727790a1f3c8e69e972db9c954e857f5325df76f6634de6be076f2192b3a50e584c61f556e6dc22a3c0733bc9963e72e87cd423176e9e84eeac1785b15e8e3a183052f29381a241948de5dc741cb4fec5dad85bf905210d1a1642d3a20ecb90d032384f622bdcc5df9ee86dd0b30654da1b6e5caa4584aae776e2678ae5984343fd70d7bbf8fc74f4af09482a1f121d937740220b5a471032a6b421d219e7f0bb827f72e2d37a63e8af8ed9e0c456c555f7a696f4dadb7b242969ad8cece2f07e99dcd22c4d8514224d0923d941c7df23a099530d3fb43b49679d1c514c9000ea67781c3d9b6a24dc472db76b85ec39b0455ff1cd3ab44c0e7024b751e853c7ca9457d3b262b6c660b0d6dfa79eb67e0b9e3e5a22f968040692bd073173a11fb88fb1b271732cac7e81571d6c67c4ad7de5ac38eb7d693e8de6e34d583d1d9648af5fa5b43fc0a7ca8a8f524ddcb86afc1eda927e5398cb25a018243ca39f37cf4bf1682eb91d6870625535d511511a48f7717d1adefba9c99c71cae33f25b71dee0fc65920977e13311405134603e071f43a1e204ae862c633621d2da32e361750d2a6882506b44af5da3c12423ffb4acb29a711405081589ed0e0c3b0bacdb55f737b1cbf379d642cf3036ea3db91c12256c2034851503344630bf8fa9042621c4ad390b46bf7e8e72456b4a4db301a785d9f43ba887b1a33f986f16ccc3e007a870a882c31ba406d6856c06a4fc4e29bb926607f382d26b0c3e53e8ba92e6c7ca3245d33ea35c5960578c8697785394cc6a9a874e8e588d5088ca4d6e3441b306d8f7aa06eadfa5ab0a7b1bd3990054b74f8771fc1edf6602e81c97e1f108155fb54a9e1e8f008816d22f476e83699ef7bb4778246d8f04deaffe0ba5d393f2354926e824c505f73f26de3cb9f8297c3f1bbf78ce530e8b2a9ef453a7ed1152ef138fbcf9842b1af28ca3802be6d0efa35b59471a4e1ef80de73bb50dec20b6fbe06aa0700ab70454705e3af30035453edc6f489a4276fb2d753b048624bc585b57e8eb86ad829a00f78fea7cb09a407a2ed7eab920923e25ca86f249eb2594689f0ee649a76debf85fff582fa41ef3c43aa68960b77cba4c426b77ff89f13f56efc19371cf6b83efaffa3fa8c3814b6ca304d8b4d7d2f0d1a457d21bad0408a8fcbe10546bd6d9e4bd62eebb76a935d49f3d2c1aa338f26376f0beb839fa575edc38cefc727b6ec5c2189415a5f65a3a4dd819f0465b4382bc71958b03bb655b559a599f8402038c366ac4963cde0e14cebfb50767dc170d457ba730e628d16515f261c2f80c0843147942e02c765e0eb3876a7238dc116c502b501b4e320562901102e839a2e9ad53dbb0e9be0bd6b625177f5fa116d34c2fdb6485fe6acfba937d98bbe746a31a414c89550e3abf1d341ec7a152fa51bedb7327d85d9bdef18dbc5d27e26218a81aca9da043e26b4d10d308f47b1e2b31099ef8ecb5ee12301a03ce74182256d571825d8815c4903e647ba1db31b637f324ed5af682516446d9ea15168340d7a2c358e5b4373ca6b6fd9fb8187e166c1b157f4d1d8586e1a5112d9ec2d3625167547553bd9592cb8c3dc49dbfb6a0d7c7b567807ddd3a54fb1064e12a9c402bce8042b89302378687fe91661014ca8643fa2accf8d7ab036e9bc0c68ed881e90ea62779d86334405bf6cdb93a4f954689953db96e7368ba3bb7b606ae1c959ebf9b309e0435cdb76503488bc5905b16426bc094c96daf546331f92631787fdf302222aad8ee7c20d81c40258bd29ccd503a6e4665fc4beadc3ceaf334defe605e77a6e404474fa525d781b5e535bf63781122ba2d599c4bc32be740a883644080f05694f0bd2843e6d7dd4e9fe24c8ebfca1cc4bb174b642b08b583d32f11b787d1fb320185fd9de2be8fe73d5d6f482a46cff64c8e72f745a7aa8c6d5f0957327e4911ae8578a0c61b3552ba4f7ccb732408587814a46d859a9066a7130020df03f26802fc5f52b883b699ee8452056d063bea9667ade2dcd1a9993cd46a5dcd402f089ef523c2e7524e39c6f1bc24343e3def3843994af79571bdf140a53c8c1527b6f42ae56ca5c86ba72149e6ba786e5877686e8cbde7eda3830da76fa4403048b502d07d6af25d674bf5ca98eb1811db666a6984c4104b8eaff2aec47f6ea71a0f4f8131b044dcf0efd6266b69143eee75aafac97a7b9e3beccb1761772ed042a060ed4479418c3265785590da483dc33ee80aed6a96fa5a4c07f9202f7466b1cb9d0ad069e854bd172d5175e453461e005f5a5ece6c9ee70041165667191b4f2949ebf4ba9fec86348ebe97036a760cf2e7ef46b4cc86b26dcdea57478897932675157eae06858d2270274cb15f18ec937f16943ec2883374be61eabb32627c4b38d02afbd17404f7234160dde5b01a0ac3ee48aa539d9f70de11602dcbd23596f2e31541e5219f24bcfbed3f78b5d386d866f513bf622de0d8067f55d462636b2df5b538385af9fa745b6820691fd5641d0fc52cef3c6e8f383ea2af32cb69a032868986749ecedeb865887401cc59f1b437df801fb0af68d69857b9656e42a7a26f242c2ce338db37ab98255df3d5dc8c3cd0b09d10d3b32109449fa739c4228f91c3444940b21c1bb9fc2070a41172f296c8d3aa898732ff86d965e351c980f49dc89f7deaa0d29e3c4178382a5acac664e700e8d8890ba5d841149a4591126cad0306574768abbccf9ce248b193278a90330914a4a794aa0d3b6045c77c3af7d74f601da9441365d08de4622cdeea12894f6a1ea7b5ae8901048db57c868f236f326b9a453dce04d7faa51b8900338bc50083269010e6e6bbdc9c93f8adc50dbc6aa04fe39cfa7083c44b1f36dcaefcd11e5cbd9b7279b09ad3fc58a8eb056c8502dc06af6b9f0a787aab18a86fc5c373b5647a87a653fdd8d8cbe7d908eaa5c3681ca3271e5186f51197a22797ffbf0ecedcb52370273cf1f90388fbe18913b9aaf56653826cff1bb7d020d5602c5d0009f4ed71dee7ec713abc0e379cb75714e3be8a4fc7e3f3838a165a4e919d89d0cc16904eae63a28e5f64f0a9c6c3f30f1d6310e16a169677040b209bf697a2626045fb625198a4d8fa22f63d29238f2486862d00bb083c6c58c9d11d3576ce726b73696e6f7bf11d8acbea61cb893b77c07efa622a7f30385045344d0f97ea5468d86fc8bff09fee78e0fd829151b385f7e3bcd0717776c04232c429361da4c15e3eafc326930b24992211e5f5c935d2f1f958d3edc3e5b667a57489d30e94f5a25221600ebf169bcc3e60c88edab3ce0ebb1b5efc07189aedcea4b242a4009bac95933d77505b3705b269045ff3707c3dfa2341879804df09900a5711cc53a0ec00e878eb5ae5dc413b0050d0beb891eda8c9830432f5cfe701db87d579b714a2dfdb9a6dc50de894af77705234cac200af68c4ba9095f9513820eeb11b26ac0ac15971ceb5c2baf2759a6754bb9e240c3ca73bc838500c4d87cf40c84349cdaf669822193bf7f4aa290b9ff840b5f47184f01e2e59f3f58575774948e54dc377b109bbe703507646fe31bea7bda23370789bb15dd26246d39452f1e3cef118d04eac369aab149b22043f0bef28c27a2df6a176cae8bf1e8e4134c560bca395e462be0fa67f36739f2aee7caf751323bec123675898ef7e16561e3c2d06951ee4ea5d7b4358452cc4b533d35e1d273ed2e4c2c0fa2ad4d6d47e25d315165d830532a141dde9fe6b4b3ccd6ffa176cb1864dd2c9e20a0638bb6c95cba232adcb373f5a4305fabf3535e43a75891a5f1fa742aa2271eb26baa523260149997319fc0349fa059e771413a39d5c46b676d552a01ac3bf0bf47a19acacfa6b061ffc19de82e87c2b0f4f45bf564979c8286cb9f0968e74e45213fd5166e22e3e769ed8b2a3b5eb74d3bf77fec8708ea9566111446993f5591dbae47bc62453f01989f36b60a6f4a4070972043680c61c4b9643f5c4a4baf429d92d6b7d9a92f4009432e5a32db16d8e62f6445f6be071e114e545686152f863e1fe1a58f4986703bbfadef839fb88fca64849e48f6ac405387acff1470224f605d3a96a7a4ce215494c4fd529c4d496eb708a4de0a11e4c01390b3122197340354b1526ddc9743e88f2a5faa0da4bb04dbc8f7b5f4764d27869525a35b24373ba7e9a69d89dcf66ec37e8dc552406d6b43177dde84c283fe8da937f04725ec17be08f90f00accffee77eefdb86b4cd7cf55d6a75eb0e5d8a1b208738c8251748855c825bade0729c6a1a7bc8b827c965d11841f8381eaca589cc6693067edd5af2f2a48d403a804280f19c260e3ffda8a15c0194ca194c5263e15f15a0dcff21e529c679ffbb26da17bfef2560f05f4b1f009c7b029aea41eb8107453c1b11efd70755712522eaf99aa5d3f24126346c7d1b84a76beb7cf5ca5d91a59cbc4deac8e024250d7f5bb61ec4448502084dc7134cb4049b368b91212a7ddd8da975c0141338293a328414f146bad330399fdf3b8dd1171372a06d6634aa71e254d27d051f16380c9bfa8f38ce69096fdae687e398a793f02a7fb2272ecc02cb1cd7ce02ffcf608bbceeb56683a99513013a6973ec2d71bf60de88efdef4cbe9900bd3923e23b17b539af646eb8a5fd6ff40bb4555d6b6cd72330f23e503f189e4d16a4d14378f8c78b4f74d4422abf1140ad1bbf91dfc31f1ab92100da460711bacb2c6b923f110859b77efbe35b38d43bd5c806f24247a3638c8d8aa65621ea74be23a18065c3a65968de5d8bd552050431bc48e2b7a12439db3035859c00adf6823592623bcc4c90ca3fb3eaf8e93927e0d755e25b4805a61ef313eb90020f5d85ddb0c6fd2ad47267446f9c3dd0f24164d6b7af9e866912573f515cd86afa481e2a8ec638658dd1a12c2ea6c8e909a40f7c8ef79d0147fd6cf3c2558bfdb6bdc56d0722a8f9c8f35cc2a86b215863385f948f6075c57de43df3356e75516343c05800fa2843853681b40e8eeef09626d88224a53115c02b9f5e37d5fb39b4c2258fba101db5ce32602f1566d45bdbc38df1ef7cf0ea63766b42146de9cf14c0ccaab8187992162a17635f3f81d4ff22ece76eca9c7d4bcfaca0a9a22056905e184172686888222d28320d965989fcf199228d8e241004602e98dbf4a7e824a34d167de409662e07de205f54cd92fb6f9f8e34a0412b39870454b2becf7ad73a64c91a616a46dc77bfc992f7d4148f6a47038fa99c4dc332355b33788aa485391c55e72173fcb2a168735a9e76e1e6d0345c3d432ee92da33797f3d75adde5b6bf132b34db67eceb313e8855a23ac0b23ab7083357d84211b39c55bba2f67000a8d1644f5026fa4d711753db1290ebc2577d8d75ea2d71e6fff8a81ed0517d92a3bd7d9d0427c393026825a7a4ca086986887fffdf19136bffc995e070d0f6727f42c6b971affa6b0bb933fc99eaf18d024b0fdd85423e4f8ed9f784df36fc29a44e592f29765e473f0d05fcca3487b7cbb734fe65fdb99648b6164a036fc2aa4441f8c75b89f68960869be2e32292b8c65ab6cefc907ed368bbf4a2474826cf432e3d9e4580f5c74b4f250e64d680f1f7059c6ac65f8ea0b213482f44e7f6acc2b070c4540a2f8070824f54490f294a05e3bf3554857e12e316a18d30f2b8d8c8e14c0570e64fd92faa74b4a9937c6b72aa9d57a19782044dc1a510a212d1e6e5171c435cc41d981b8cf70ac3eb1dfdbb54da664df42ab1e0118a08e1aa9f1f65f5dd291691ca7b6e2eabf8f1197593609c0572c597429f7705a2cfc71ed41cf03cd2072de59b10d456c2193e27fba5416945614ad51efbc4338fc4c9a7c7a06e65b375d2e11c9b3624d60507c4536a6b2b4141fbbb7a485352c72cb126661b61044e695ad08148e62f3c1c6005a66a1a7300e303992b4d972830f9f43e2f18fe04c47faee6c0f95a5e70c84b4efa218985dd8d4d3a7f010cf20b61b7de3b6eef12f5ed5c5c24b1d4934b341e7e7eed6e791f31105bee3a864a46220453f993512ab9f738eea37c834692f3b321d127eb2d2587688f5224e552a456d2eefc649602c57d3a98cf647654199cb1e2dde3a033162caf142100ff93e0a0c43372f68584b84c447bf5a338576531a2c2b294c13978a8668935ba0431c27860d5bd3549bb7bb43b22b76f534c9206f3cf71ebc354e9e491573802f6c1be79c953047f15f740ff97000e77592765f9ff53f3d2e49ba6bf25caddcc07d1cd058c289941cdd092c45a8f7195b67f955f5dcbe9ce0453cd2be62c521d195b6b7ca108ffa6156c9552559f8b0a219f6ba85c92b6da0316f6ede476181c4a522567024329726dd29f8b714705c1e262456219ffc7ed8951f4b2a016076b990f6ea5dc55b39e90a19c9120746630386c02612685c48912b84689a91a386bbe2152df8c03aa02e90c0c6d28e8fce707892235f5b89aad0f41c64ced3f419afca1ebbc9770cc8e72540d73eb7ca78d9043cd511ef712ed720979773dd27a8c2a60e8c925111660be41b73a623d306f629d42658567b7cd58f7f06fb92ba277a44f3ee17aa00d6bb684c82c6922acedca7dc9ef65e0673c9f7334d51be91439d93613d0fbf2283e1ef0855a2f8da2fff13162a7194b6778e733811685b5656856915dde54fde6c11866da697dcec80d60a06f9077193fc87fb29df75d51a7a3bcb01b1efc681766f29a63da414787e7809efc2b9cbef4c3ed102c6c826c383c39f89de8d75e72b47b85e1f5db51988126b30a81af4f491011417b25ba539414e14dbb003df518d2e4fd05e70920cdb17c1059af382bdfa281e4f80b37069cfc38f67aa2adcf93786ecd0627910bcf8352c3328edf063a499f16a54be99890e3f8e7462ff0681312cec7d9a0466a8a2b7c220359fc774a726742823972d6ba2a8b32d59eb15cd10c9a26928765c005dcf03b2a597d691baff767d7280d9b8f10e1fe3226a1a957a3effe14964e96791652ce8ddc84db56e4967b2a2348200b35329e79cc749f157b1880160392ebac70326a94f66adee40524d4e8e2e3c5561c63464bf41be00e381c3e1ae51d19459b2e61743bf0d0ac32057b684feb6ea9c8d0a05488fff0a915eacce09f71c0ac27c143d59fa5a7927016a74f7a88b94bfce16f68c2c9647c5bab94de9166c990516726634438399edae99f758284f46aacc6077800fa2413981fbd59a55044d9821002958e15e4a1b1b426420c93d83d51c0807f7a5a3e41a91f9ded694effaea252ce246671f392e4174b80359472b53d01413ba79b46d18ecd39963fbd270e282a23e447dac07cc69baa1933866d40afa1dd08752c315e54105958e053e398aa1c2f4d702d8274664b47684e4a66af6e48278d9a06bb1641886eaf05aaad6d8a79962feee94afe05dc9cf4099a3162fc193f2d25a0b941501693c6f516b39f744e931c84a4f1bd9f425276293622c9bae504497523515338a68cff751b852094ff5abae112736f5e58d97f2e01b95b597bdcb07e562193acedde31863072bd3d2e02031034388e4c20e000045192437532cee7b7870a4d1f9f3cb1e230fca9addcc55aa83cbb13a05da4e89e11c0788a333fad8f9a640872627e9771318bc505e0f6bfafcc56d231b6472d897ea2dcbb34f5fe206d3cbe3f0dea9914b6fd054cdb8db0bfe4a9fd565b079e7a19a3d84c5fec87eae45f538784fa42ed3729932eca4b94849fe06005096aafd9889100fd9f173dd06dbf7f796f4a5e0c65ef77f9e61035edbdccbde71140ae388e38667dcc60997c41ebaee7ed12ff3f124c7ef5090dd424024d8f0cf4ee38264acf21b392063091549f5f0e40994a8123f651079fbc5ec5eaa57d2793187ff74bac28ad71bb8e8e89d435fa5cf30a49406f617d95a2f3da04e5f77e35767c74f4677890203265a623d0c5c7825e297ce51991cde4f32b71adf4d56c55f9654f7276723fddc5550967fe66b9563c9bb6151b4993b81dc9f46e66f7f1bf30b2b92c2d3a8deb8a1fbb2a0540cbc3f9213b68fad80f82d5b5746a725bda7a7da92fa3b18ee3fea86100691972929e90d0836a56ce43893193cbb0f7c97b89f761fa76230067d03c6173c85aa26cafd2ab8305c82acc51545557f97a7562ccf2e779025397996bfbcafcfbd8a0b2935b3e445f551ed1358c57f6f0df9172b2aead7fdd2fbde4def05f1ad8fd833f889bc333cdf76b1dcc40e740bd52835279390319f831f4a74fe36991598b5f298ef7e8eb7e21c5f807753d77a3f9febc18839f3939897bcbe4b276587b2d6c5c899be5eac04afb3e70d87916024c798681ad37af6c3b53be322baf9df3f27cfb5542c5df25cbc7b3d9000bb0bb83ebe21cf99e7d0758906bbc98eb5eb2c49e40955fbcbd08ec4b0a62fe28cadee782ea84229c3362e745c2b553e28e6e6e786e35e393052f5889699b9beb31efa10c258d4bb11e696e29041a00751045456db40be471a80d4e97daa4c86c3b4fb06a8cf2655e244feb43a10229a7a82e0ac9ff12106f1541cf30b099aaed14f39b14c32e08b8ab2a3b225ee39ab30098b809078c2659d427bb4b01eba99bd33289889041dda4ba3790bd68e40a03caa0ca572b7ac91a143f35a0d1dee45c65f6792fa40a965064775dbf279ab1232395cb71c9c9c45e860cfa52b4f37e2dc0cc44bea684940dff4cf0e331919396fafcda83e96c6b995f0f7cc7273841bd66c20d53f29e64894c2d8623db805b5a3ff33de58a8e9a03ca63a217ef5000d5fcfbe96653fc6060e72d390722d3bb17e8e811bbb5299724a36b1e78aa58b6078f701165d993aa98f509dd4a90e5bc1a7966c89e9ded8855d59dd362a50f2ae36267868ae1ad2e1fe119c77bcdf66da49092c4f3389ce7a2a7368ad2669e53866d6f39b582186092863fdd927c70e7bf3895e8e55942cbf6b33c550813ddf30562251cc74eb4b9989e04dc6869cafa46b32275100a84ee4904601b3e96eaa0d2b63199a1db75cc434455b12ee44e3d6f53a01231a255adf8336f9d29b85af93d28a53c694f248193f54544a3f1e43ac74dc28d8c25118a41875f79dc498983c82a1be6526cae74fbad3753dfd9b4443558b22d7b9dd76a506c34ea9b12a5637986882ab417e9b6a4980e42236dedf2c7987d1532a6d24d19f10383247536a5ec921c6bf050370526c942d314cba30168ecf960743fb70427780983b771915842d8a205b7532d6a0ea2659dbc3db918c86ae1cadcfcdb2b7e1120ba6cfb59b71f749c9aaf06d5fce9b24831228e9439c90444bf1c94a1cddf2ef6a1ec8419ca49b98ee2f73ea0c8c936c339e318ef6cdd54396edf2e39c8437876b6aefe543c630fdd0bf5e4f7147ed9d5e79584d3df0cd6b1b50b547368e32a860554fc73c7ca4be0184ad8de8554c67f5632fc909c7deb543d397c64c11e551fd6e0c5c9a0cbb70cc0030d6df904564f89ea4fc41413b6928164f8e0cb22d69965aea60b5487d05986a72ded79ff30e8609c70ade20ac9d4136fb7c131f6f52cb2ccde20711d1463eb03ef91098cb55c4cde774c846e5c3507c29e1de5daf61b35ed0dcffe68cac3845854c8fd4024dc2be338261123413bd4b0a131d81ab45707d19bc9bb2c58e31f721cc96b81b9ecf6534092a0d2526b7eb73ba45bc5f945c4b0f44272ed7104adc78b99a987bd9dbd8b45200dd938b0954db1a20b25900cb4f95575750316216f9471b43168080dd30ecef38d897b0d9ca6327dba58cb77fbc2285be68bdb39c9e8d188a708ca34287f3410dae4b87552757996b3480536d2a330d06f992f063c858ec005af6ac155c2aaccb8fc0a5c063a27817983fb6d11aff665944cac4ab8a595aba3ecb71f4529e8888e8d0960a6caf44d956d742f6858af1ef207244088f6982d7b65e06e350682d1ed8e8353d027ae98ba7918d0c1ac68a2a33b9e074774896e73b28740a380a332e01e891510426c036ee2677c36770911128e713d0a7d30732ba1a7ab0e8c8bb969015761a062814ba2a6fa8505302b8379a2283aa57e2e215c00f64a0bf7f5fbcd1d9a32397d225aaff1144d7efe9420b56b2cdfc2de3aa8e204891d209969d6605e3abb874d29c9db32dcbb4afd408dc65a3749a455b38634e479f720ca395c5c0e6153cc09a6714f24480ab2c371d21f259cc34e0f9c53b5bafce974cd329b0363f6eb48c3cbb6c005cfbad1bd467dde5fe2bb69550a625e2002010531185fabaeffc700d618a579aa21574cef4bbc1e796360cb38baf93357ef3d5fafce45fe338de5d54a8edb8c90a7794e899e334605884e375fdc043edace937d59ce6b88c871cdf99c819af5a19b14e4fa51329f6ac2e96fca7a2c31a16901487e4624b3a0c94324126f74d7d2fc2ce604656b1d3707cec68403ca6f2f87441bcb97546791469b4441a9041c98c475a1d6ceb0d78e8c899fd5b17bb6c08b49ccf87ac073e3979d0432a3431291b8f8e76385bce3072bf04742e5bde5163e5ca27725640c27b22851d7e7a7fefb7f538762e5e8f82cd101fda8c53802fe874c313e382c74a9d2dccc433f17330d15d6e27e078ebcc089bc540785edcb8f116c3ebf24a5442a04839fb886ac2d678a471c8ebac22893bbaa1dd96a0eac45b4412b0b9311efaa718b226a5cee41841ebc5a0e117cd627f7bb7d62db73971048e9a052b9861f2e57d51a122a37afa5021badebd606943739b0b28ec9037bdf160b61031eaa8dd427461660e4200f49543273cbad1188f6ee1df3a8453b72c4b42c871a03aca6a92221d03320e1efb9a92d87a4f8116e1383d8fdc3cf8cd57c9da9cb2129a7296d7ebc3ce87d1b008359d7fa7f32d67dd3034e1bfb8e954d07504681059c4ad9336305684db4880a4ec21bab295a076af2973efa05f3b59553425610b7f70a32733ab5895f1cba5b262bdbfc7a2a81fa8e55dd6c0064dd784a879d78cc30f39022c07e46091c5ce62ba72803fac3f731924eb0578f052fdfcb07a17f7b74e46fa90abae4a65654f5f26eda932e7910ba6273322caa9c7e3f432425ac6e3849d9d1c3305fa8f42989752a020cac4309a57a86846f235dd9dfe6b5b931b5db38e2ed96e9572c186f97103ae71bdadee9ddc660fe2802d2ea4fb9ec031122d79b98fe3692e634e01f85590c79341757eda7d87616472772d933ab4bc91addc1011426d0b8bd9beb3c5e2b0e9185227f6a01818925eb3b93f0e93427eb04c50c961e613d206946cf3e31ce6121f65aa2ebf5fff94c165764af2aed2fc4a11e13db85fcb041bc1d880e36a7907c6f4bc32196726b765a29ad62e9a52ea3f1238f4a3c3d639095f99e959e29444113dbd943556e116b02d37c1e08b42628994f2135555a77906d2048dc6066cb47e0bc4a6b29557cbc5e4116d80ae7c3338c2cb70d5f638c276ecf92fe4e362b5416b788759555ce7b5df4a9b785ed9f994619d60b6d8b8b4a6c52fb2cf1d07ec50cd96e20fda3b17139d4666cd0c1f2d2feee5d9e008350e7411b1f706f97e12114e33be07817472666b6833dd6cf85030c28a01c1f79ac63e53cd5ce52033724aa797fb687f1c1151e544616836d3dd653c5feb6dbdb970094ee49ee73905803608283ebe20b7bd51c42c7953c0c5d9beac45896a6ac04f3c5eab20e2b3e28e00fb21080a37e99e04b8995424938b2395d155f61a4a39cae8c6fe0b2b3523f331f8df62862944eac3553b042405548b26e81f6db12c1726527bc14bdac887bcf4c405336739d6f89eef2b9d4291b70db506fe0d6b1a11631e18cbeca35191720d4097d39f4ae99d2414aa7abd4cbcc428f8234940ffa27ba3db8a71f008f7193ffc1267df16d2c6c4a59cacea302652c4c8d233160ebd2180096005dc1e1297a16f2e2975ff37076ac04e2cf0cb03565dadc91e81a706034e84a436ec553c316b15ddfb3b759b885ea43b77b4688fc3bbd08ec8634ec2b52d212257c93d5747d5770411a46ea3b73573a56887c8b36d336129c837e672ee54df251bbbe7d7b69cb1c17d1798ec06ec921becd888bd666dabafb561d2eca449ec62601d0ac6400a0ceba6baf64ec2b113da285b33eee788a644deaa68ae139412b462efd633e9a50f4beb2a69fb2970c6d9419a9f61e6ddc847df1eb96a605154ff1577ab6774a3204c513f30024a7422b2ef11afd1d9cd3091b5b60eaa72767cef5915c150a9558ab9c1e089fdde07a703bd6061ecc1f1ff8b141e80f9307cde834c32ab8587f1a51ab282fc05b5147b06456cb399979667b2738c66f639900b3ef8b893986fa820e84422e0247e0228f134cc63bdfa998299a397ab922db37416fc477bdd237031081e880c1f10ceb5b6d2484d464ff57e3b02745eedfd07475c5fab413bdeb3bb6d8a7b7a316a5a68751ffb48a2226381dd8ebb485e44e463b9f3472457471093d13a445ee25b54cc9df1f5c0604c188ebc3778a28031b3c473168ee7f256db5d4d0e9646e0d66f124e508f23f7c53de880ab32e2af432643af961b9263b6a0b61a85a729374062c895065ee6e67c02c691114c2f39ee281f381ef16a181f5276a2139ccec72002d9bdf1ed73f5e57edebd782fa20043c610b717d4eebab3359e43105776946e83cf2f47e4edb966adf7c2a83b1aa68aba47e109d0c0ca783ce584b0e7c913fe9179a831398c78b0aa0a7e08f03c0d6c9ac7a33dbbf33d30bbdc11d8424848ab6c4b54ef3b02cc7657b6b9644557a217b40c7a1bfb6f9801aeac409bc240e4e61c5f47c55e6c7a571a517756fec667381e9a6b099f0f82e25a5ff96ace4ba828ab2f33ed7a3ae682f5ef6983b8a58a88820a8425d70c1f3affb40cd65ee32e88d42a31c296c9d17eab7e2e3adc63265fbb606c76f26207f04d636fd676eb3d3d92f851ffe50fde466e4431a544a62b894008ac0a783e8f8eb26be08afb86b131a39d4c90bedc43bcaaae401553b7cc3cc7acda98b6ba6c3551177511531e12233db4d8a63999dbcf4e0cd081f37809de922a95fec6662f6d105d4af033a09b15591c08ba5d548a6b8ee3a7f64fea8b9b043d03e06c3ae990298399ddeca2570f5ff6dfd5ceae4c3472e3ce3f39a356d2c6756f24349809d5cf9cd9133d88da97543a209900c1b3fb3529c1141ac146c7f947e7fd8b585c5657f49f2bce30b0c91877002c641d49b673cdd1486c9496fd61123775a43d51a8a86b22281fd9141cfdb5b7a5aee4747fac79870c46a9b51f8e065449a4ec38f41771baeb2fff5464cf7e976fa94f5e78bb500d74f7317e584017fabb8ae09d47959c7532fe5a7eccadda0bf0fa831f5b110ae9dbaf2be1f58cdbe9c8d0d0c15397a92b830ca2593b80be7083943f9944f6ef292e3b72eb951a22aa49a26d0bc4d39a6c4bb374a4484c98c89bb016221dab6cf3f571aa84a0b6cd3ffd8c68c1d303834588b36472dbb56ebc38c15b0b0c833a5a7570213127d73dca3ffb1534eed197fd113ef6fd962e4f05d3788bbdad637915519febfa345968ea84097aefd315c0bbf2e8c43924473af5e1397a85976a2541407232cf6ae73d20acb1906bba3fb38e9924263befb5456e1f5459c0e4adbd9de243d07093f0a315a08eb187d0a4da7b5ed65fe3d7cb14035b3a854cd7607a6e75c4fede6253ee4c7f9630d58d9a004fd511930a8ff8b23ba7daffdb8bb13af1e7ec96c3fe95ebe292ee5cd8c10f34af12820d407fc6b0c5eb8f550a5ec8f14e0ce8437bc0c3b2043a98eadeb8609957b36b819576d84ee3ce11e354979d7bf567bb81b26f89533596c3be2e53f7546ffd8d4683d014a92b6b8ad215f4c1efaddac7287a395705c33518817abd6c995748bfa96853b1db0073f9e8177a93e10dd256b0f69b02bc29c7d7e90131140f878997a524c3555ce9cd0fe0c29805af85236bb6663aa1dac3e2437bf0d01f28bc589b1a2971850e6520934e1dddd92e39d2af86feaefc32e50d6a46bc72d9d2056a4d0e89b709dd3f282a7a8e8c5f7ed0c5c59dc5dcdc0dfcb87d4727836aea9f04cfda49312c14b957a4998484ff8bd7cad4174863d3a81c44c85b704276c76f5e7169d4b390011b0161b253843b5ff29797fc91f5f4a00a8566be5e641268ece0092484e1f10ae4ef9cbf8789bc8265bedac23c4e5b07b004906dfd5503241c18e0f88e606ecf014a8b3980878b81db0c501860f920c54e6f8be911e1a74dd31e8cb4acb5056db027b62ce538e8a7b38a2fde87bd7b601e54034c6025adce22f5af5f4f90d5621ba63fc74b962325da16f4f55436fc3c21abd4734fde6cd7e6a7e741099fdd38bcabea691ec639dfe7742e9cfa18306148557cad93e531d2cb916af1413c9546c37fda2fe061a32fcf35fa7d6f458883bfbb753852d1005ecb716047f642e73d62b1d00aa198590cedd39dd9f46b9a7606f81d5390d202ef7788654364f1f2b555f712dd404e8899aa376505762ae3cb3fbdbe00066bc6d09161e73def79915b3a0dff12528834192d28988fb641b0726e97a768d6330d36d728a388676b12049f0b7aa16df63e77cd8c65e541f16a08979f38d5406193d5d3f092c30d9480614aade7a085177e20fff0526afb3ef34e651a8e810b15eb0ef11a92d48fa2d23a490c7bfd49f78a442574c4278979dc6bd3d3f7a55f8e5be259973c4e3d54ec1c178dd67d3b5ac6a3a2a088b3fa273818c437cf2999201bf2e31ce3552fb8fb659cae3cbfed3fe678c8dbb7b9655f039bca4b7cddc85b901663fc75bcda8785df16cfe91a2c60d78ac2f9f3a1590496e404db9b3c1722a71266418d5a272beed16d1df1f141363464657dc084f4b2e6d8ee9adf0c4e18a27920c4ab9122a4e9c6940a0623565b8fec72abcbd138c899580de6ba82b284c212f6999cf2f6fd7f3dd61de8aed1e7c1077cbb5ad85e984a1cf4396305f3d1af631a3a5f32bbc3b8d2362885fd6c377475bc2334203f071800ba47dce690513ee9cbd255c6b1f15b6b2fc3c48080844a57fc41f8b813eae2baf8d494ea6c438d6919043e935ad96549f58dcb57d350934db6590e918168d52b93bcb52caa413774ab11d5c10bed624105bfe54e7fa5d0517f1de3ab490542d7ea8ef76279a69b499c5d4132fb3671170a4bec61652b3ddfab444650aa4eb7f6c3a43d14eb4723c4a33f4b1dbaa27e9bb2fd048f0939e0c2e7333b8c809bfc320d28ed25597dd634ff9c218cf2ae1ba4d1a6eeca5d78b1fa8618d60bc633b0089bb0c736f6302c4b69142bc8ce0ac033f6494ee3a1f1bc9eb1483f899cfd6280d11271ec67267b74947143af3a2491077aaabc885bb98bef10e527ff5c78280b43e3a41c4806cb4f2e15aa98c087bc1244c6543e3fb6672f03c6f3037d79488704e673cfa0ec6f61444488ada993bc94b0031599e7eb45c4c60805c37932c7b297a27ebafa811e38f414dcf532ea650da24ed7c0afb9879ec8c7bdd7b1fedf321ae15221114db8dc2a6ede40ff2f3dee12c0027e6a98bd827d164f4781c964cf60e3947055b011c29c6afa00e669b6fb7287e301e414621903e3c592c39a0a82222257745d9ffdbe2574d54220c242f5897424f54aadb7f18c2d9b8afa0c3237a2df486549c37272a99600c207071783d1646af25c68f06ca7e5d1428136e69547e669dd784b465e8ea0e5b427b2be54db8f8b3c134863f62c31894677e2551947200a8c84f019c1405ff182cdf152556e3666ea81fa858ccd1f7f845db72c2538c734b84bb6357d8cc1af1d992581b27a4d67c72402b53922834045c21e994d395dead64de41f284f2d38ec9b30d4d952c59ceaadc79d376ee7f50442dee925eba24ca799edb27b2c78e533e35d28e5e473adb84c077e91f97d40a44dbffc6535664c4a1071909b54179bb05198e63a2f9cf7b7306f488b55fc647e098f2890388de4fb2a512dffbe6c233ed48b254221be76442b39b37385ce6f7f7f040629b78fb06c3db562de5291a6055e22772e836bc706ec85c3d0560272f2e4bd3fda44f2cd7dea9820f89dd90f33300d7028547c2e88d6c1e60bce2f1c9d1f6c8b1f66d5ca28533225902285b0aba538a103cb1e90cd2d7c5e131e8a130491bc982e9d0d47e1560cab77eb486285b256d0789ca7c4cccea5beca04a50f7289dd749b8b4089fd96d079bd2d0010e6620e5e134b00b0913f749a3430901c95ea65aaa2c629fe03e673d9a7dd9e7ad3b60a5cd1cc75dee931099c3002e9e878021dde82b6977d6b6912ebf94648f50a0ae4b6cb8e1140ba14b1b77c38a32b4ce0fcc88ffbb62fee6fdab7b2e5a443ed3880d56d1d920ec55f1e2125798dd22363721cdb43e0f27f59f0b0a4b45e7e620731c592be6d13f01c38afa8112f4b1eb152b94dd1f233eed4d5139f94c8a50a8c9174eda75faff9d43fcba0f5ba42b7f9e36c2451387e8f57f70160eba837dc59ffc88b18af71557fa47c2870ed372b18fc1f16ed0335b204306f3b50d9d6b55b61a41ea220b0eecb91aca0c4fabcba42904456c65fbd76f03478c087cff8fe5bb91577de9eb6cbd022188a9f16fafa5c38b2b3f267beb933308dc4a6f57de78fe7b41ea7cdf04f24fe1c076b654ab1f2c9957f7e3a9863183457c00ee97ef40e9d97f81ce865d7041968d94064c499a5bf9b433e776141fdf52e20f87bf83240b8a171a65baf342abc25fc89e99f4d770e7ccc1042bc1f93660949687e45b84b4eca894f88bb7ddb351bdbbff0596ac466d75aeabd37d767b8eb25e6db7f0d89167b1b6d85afa0ccac65adf6d0c9b67ad408b9b535b92738d7edfbb4a6fa4db5ec9e4dc3e01c0583a41af6b867fcc989fdeb8c80404028d7341eae360a7f8d288ff6a41c06023b13c6826b2dd78adfcfe8535768b3c96d27258a85b0fcb12882cfaec95d25583c2a51b2b509668177fb363454a35308fe3cd34a467cd83c64e3fd05553c80622eaac2b45ea44d81809e4e7166693f7635d2f463ca9957f36bd823d227c9c315f757471d89d521543be485d96441f3fe8596a7b0ef8bef92f0519f7cb89b685c72f250a33976654d17a58437f76eec83bef2e34a0ed5b59efcdba5d78a06c01bc59faf1b048b098a3d6d2d9a36378a252dc4868967d461d8ea9b0ca1e8810c591b22902e0c9c748c6fabc05810e6bac54335909c61aaeef2550fd86628013d8ba72874ab2f985095ec1f045f01ba4259e7c67b13f3bc92c76b99120d1f8d93e9b25086640a9823afdfe6e85f09c1745e7b79268d976be2a4eaab88b68b1f37e5e2452a901fc9ab37e5bde34ad2c917ea62235dd3063ee3d4c3e32b9473f0365a2bd37ad6ebf328a7cac95281c3d6f16404eca5b1cca54fc0fbd22963e6e7ac9f9f71567b1210fe9a8381de53e876540b64d533319d6a6f7425828012ba968639e81311b4d3b38fe826a770a0929c85e3f6345277f293d5c3df5c14714b1577b356323385717390546bcc657a7409ce5d77088f6c060695a20ef716f30be904eb3997745db2e9ec249979c124ef61651911905250545d00355d3220385a29e6aae708bd6d4b946f98e5981f1fcf40cf7c1e4156a47ebf3c6079982f10e3d8ffb721de3ce8ad42c4f5fe3803f5d4f1e06ba94306e50e94c5061188bfcd1f10eb2e4a3c84bf35b9b84047c3aa00c544629da6a7264ec8fb6d1432480851f97835f667b86b476f082e21b20a28393711a500cceca3d1b46453862f2cce91a84cddf4cfad76bce2ab9666460ab9454c74779bd105c5981d9d623cef8afd7b82ed88e6df45aa4002a726e5b6fe3905484f05dda87aa54ce4a571e8b3ad0af27421f60c9c8a82b70bef351a0c73e4c64605e54359163ba8f0fb23d8cd4979967eb25ed91641f92d98f148f601aca568d9c87b89858ec3b35b621a6301d8b3c09b20831c7259e0d86313b84e03e99c4fee4cd5a81a9cef4d22710c78a2192c16b3e18549557b4a5f3ff70d8e2800a85cc2df5e9e7537b6cded70c97d3181bdc7aa2ccc394882ab085141459db3dfa50bc352b378e936c79185a494c0414e034ea4f03c1460396cbddb8ff4e7f8b77e0e4b80a084bf6ef0d959dbba34355009f21a093718046b8dbcd64400ef4c059be819abc213a1b4ac48382312c49bf60c7afbce3c0c815fb9bab65aa084efb11c731de0e4662090b3323270182b7857c65e99d63dae749e4acae6f7afecf0fcd58dfcbc5c7ead529688a27abf5b2899ef660e572b0ce38aa78c975106e312c0cb568b1270923d32b5269fabe9dc9f4c4c98f6b1a078891494f4921ddbd13f922aee99506ffe56500c3582244ed02cce833b6134e9f821453561758788a65e0e6fbd59cb017aa428917ed895bfc4da846355b318eb48b08ba631d1de964edf0fd254724b68220f3c2d37a6590425716005cb080d256fa4f6f909a794a86cf6148909d7ca8a45994a43e4177bd9c973b8a064d2a801a7ce9a727644d469bc9746e24c4ea965d4cdd81b432500f56b324b3720d0248365f99a6004f8b42bf7bf82190157723d89960b67a578cc4ef4250c5df95cb2ca07f5dcd5bc55e1eb311d8cc9197fc533b9691cff84365b16e7bafc26782b99af39b9b1687a2524e1ef9bbd3a339622f5201c4a7389041683a925e4a78deb221d2c9ae0be4319f68ca29aff06397443f1209c8abf7afc7fa9598e7e4510940fc694d6e21431c11ba617ae45786f1e4ab7396985b3c3e24ef3b74ad528d52c48271d9eeda83be6f982ea327395cf993732fd18d39759b62638a9fd771e1ba88834352c1f0e3cff69d7d69d6cc3331e966b2f6350c09290c3e0937f8381a3f4f3fecfa291a2fc6fef7a879d290218fa3f60e745fda9c4b1d6e979cbd2db840df27a8297e0441835cc834731cef8705d2b5a55dad8d32eb446be6cb234eea3c562c7ead870d55aef587b4f5150710fe2b8257faf1e7613629e622397789576ca45523c1c355eddaa19c0b3d6dfffac77f9162ac3eb95c817b764ba925a7257abb2cbe1a44b16072473df5134dea70e445fe13331adfe93eaf862374b7a4811af905f84a810da88f946c1be1af369102b403529cd6f60f19e21150f42e348eb6e2dde816e81380bac712d73bf38461b17301ab14ab4c1b195806f73871f273d08de470090e3815464f365040aae63d43cf46c31fee0c5812e67f6ae846c83a9b8ae8f5ee90d7a498c5a690e8a413c8299a895e25c99539a035df7d1fdae975c352bd69bf7b4acf2fd72060f1fb0c7b8d73372f49bfc97cec643c2f095b313c3914d45608090579ba42f531b08c826c7b59f7a6982204980402ae5e9b560448d15501fb413ac02421f6d3a883f9de50bb7e44a4e6430f36f48cacf2d4d03c4d97b53642883d6a82c1ad5e45e91510da6a9079c6c1a5597852691e4b9d85c99facbc0f6e97c4c1b8eb34c475e0e3d400e48c5e1e3ba6f868f58b129a41e2d867ad6ad5b848896f25eaab029b318b770670743154cfcdac473f03316f6216ae175c2838cf82f510e729b6286265c08bd37bcc80be0098f42281ca4bf7f601ced199972a204aa977841fd120368b51898259cac5ffb0dbb17c88a25396dcb2eb7803307c0585e84b052b1ddb28893214e924d585235e2c1b5bb6a7f721cfa55e66898203ac0219feae63cd0a8d462c0fa0c24f23f6571c24aa76561c0e57d240efb31983d29c2fcff66ecda3f6d6cd51b2fedc7aacc6f6643f41afd454ba63ae2f60dfaf6ed80e256ef084f9f203c5ec5f645337cd0f9a5d29b71a190bd3fb6477cbf92828652a4c64ed353e08e6b9993862d10b49946f631f89c771228a7926b80d358ec1ca74712afebba02446b35afaa44c9f0d2933e9bd684b0b757555689d0cb95c92203828852d14608bd0acd3395e95782d0bed2054a14f6e92c0b4eb935f677ef5c2865ed147e3c362c352b7265fa588bc4beb8ef53c7b5e97e71926c21ebf0eaea55cfc916202b0de32a93c96cb20ba7e63e2075530cac2cbc7ec671c37672615e966bae2d7947205b65237b834cfa7d5f49dbac02ad20dc24a8a9f57f8bc0ac4be6b2f9fef697e1c18b96cd03686ed6b3a0f76191a4c22b357fb375df9d99b099ad6ebb9bb1661878e8530a3757c982930814282abab0317091fcfbd8dd5261b0df7138baa4596f7915f68d8600f89f9aca8db3e162c6be520728bc5c42425f27112cff5bcf60e50a07b688daf7a2fcc65d0c0327f8436e763c00fcf3d6f533a4ac1863a4dc65a2693132a563165ccf89521b30d418f2bb85a0ba1afd02d62755e489c1ac50e369e29fef445aa1f5a656b409050313de2b7214bdafeb4c5f71d7ac642ff3a500812a13f5b522c5726e03904ef7e4a98972574657beda541ab0a6da8c4f5ffecdf76498b8c612232628e045d25f874d63bb1351ede717665d26e4c62857e59adcbc7317fb8414fe8c40bced86370da4fdc15a53184df1895eb7d10bc3f1d222aff62f48e400d5a6945c26e0481604eac2b71f6e321312bb8e0fe99220adebe9d6fd6d40180fe7a13c1970153427629e181206af1aedba331ae8e2b6b3bd6078327fc98205ac187ca5c853e73f68662039273c68d3b50b35bd4a4f8a223d2c452994018c7479af80d343f2519d9209de4d45ea950c89b2f084dea9eb24b3afced03c3c379cc79d7c4bf536a81fab59e3f796bea5f2e279bc4e4b4c5cbcc187190b3d68ee7a196ea16a1050dc27b3a13e666a445a9b10ebed9c27e06db3a1242029284cb6ffa1064b8f135546315568d4c687fa8a758c96535bafa1ea21432a2035b7786259dc8f6b478ae7ec50e7e2fb19507bfff582c9fc4a84e27d1b561699e7f70d2856cf56c3cac67ff8454417baf5dcb1f5f006f3b7d26cb187130e7ca8272b4f497dbbc67379b76eae8bc2ab7e2e020e2a80e3aa24210398fd233b312771f88f49a6bc45540f4b6c8bd7e79fb85ff49346d3299a429d91210b0eba66aa40435ea9160131e918901bf9fa133e919a057fd075638abbc1d4403f88e72074b898502006c399b1a60cee4dcaa98e1ecb82008a77d6fa009e289b59b4493e212c2e85de8bb32e7d83466ee06173ef52adc73be15b857b62d8076d19b245fab1a306b186319d084dbe760d90f65813326498655ff2b51d115404c8c3c0f99e10a254b99eebbe9389ce4f2fb932a414cffd87cd1d0a6f49aa991bf10142e7a32256bb38f4261b2085b207f451770cf1cd93690df7fc018083f0da9049fcb696f8535ab1f00320163963c3efc327b4ecbec3481721957d61a8b3565ddc87bddc76da1683f2a075468a6539d20ce3f55a6989679f169755b2f8251897f2e761fe434116d0821a6791b6263c56dff8a2074f0c86aa3c7a2124a7369a4f55d32efcdf26e92512e8894bb30966ce47468207788bb6a52a7afc58c8e8a5b143232f988f15167af985f08819cb778f510ff0ef57a61cfb3ab2acdcb4eb4968a3bb078c8ba7bf74507e0acbb7c37dfcec3d17264be29cc33852d929beaf7d28fdeb7eb28425fc4b07fb46df95f0cfb37d7ef6d50e01b06bbeb10e4a2811db5bdd51fdf234e0a7393f7252d720eea89556174db7127ff33b313780317bf7de45dc8d93b278f182c2b0b15eb0c94c4715b9eab5ea7b308d621a6a3b4a46f8847b3f36e863d6a1de79b260e99630ea8d3a3992bc1132c4cfa2140dc4d8c4b63fa74846bb105587ea94f2bb9597b9bbcbef11a2b762af3420e2ed585731d71ecdf2dc55dcc805573c21fdcbd6add43d0cffb98fca8b82bae2adf24c4197bcec543a2c9d322b262ac8bd0b1fee960ad4fa57928a062296c1635617384ff5b299a3ed6ec6e9f3231954d87dd9bf78d47724ee3162e6db10de457f97d5ad3c2b59665a72077287b219b875d96fa3dc74cd3a4eb90b00594a81576537b02b3ffe5dd0d3816f3132a582ddc72275daea1d1711f92323ce79135a4eb8caf7a920c9858bd52ec2ff4cb41ded5f6534ea2b7560b1065ac7e23a7aac135043337140c966f94d7f52144b6e0e67742b4f1daa14569b93a6553ff91ae37b3ee075661641ada252526fc436c719c1b910b26452263dac50d9b2001b91f44cec1cb720cd0793f50ab7b576b0ab59a614e230315bb12d7c755bef7b4ddfa05cdea245c83323eec218fee05c0fc33045caee601eb8ac93f731c5a833b88e2d3b8e1272f635cd1798c58c90177644fa67695b844d3fa87ebd8f1d4e5228ca33a2941438688875815801d8064c321d0b72dbb89ce6d5e3bdf637894d579578fccd8600d42f1ea74b7b6360ba05baf368c1a9f85886d83a45e25000a2724f1c0b011b4fefb8508484683e8f5615f2320e5acd524d86da368faac6e827308f4137ce2dbadf9f08d47facdeb3114ad682b6803f420437320628d81b8ab9bb57cbeccf0c3b633ac6bd9fa80b75c659106b5bca650f2b323c4d8071d9e2c614e19ca7566fe964daf48e4688b73efdfaaf5ce482e0ea60d5c20a9970d99e5fbbb6a705e960a0f80bccdb9758e31238426b8d6ce24701fb35bdab3703967b45b1e5f863a4480978ea7da907c82199a55b7e5eccac49651cfae8efb9e07cc002101e66375eefb38c49e67f41e2fe85a2166257abef06b6f3d3ee474ffd98243b3133c556d6d98fd8c4c6e1ad683217df1dd95e0cfb842f416f7130e6ad8380fc7731e72e3f21213c66fd2993bab7c53fdb37959fada8c8dcb913e4e51f38999f64563466f5ff0ea19976a761ab3ff969c2078298174b644744f63119c0410682e6b71fff5c7e668efa82444ed8be9df7ae286f6be044c2ef5ef0bbcb1bb75bc31389b11ce6848d305922438e9b9078a795ed05c5128d1b57b6bd373bd9f2c068f9e8121ba086ab5d65fa421290da85c1859ec27d0981cb920952d139a429a77cf45d8ecbf76a0930203fadeb7d9e701ec97e57d9a1002dca242d5651dffe373e94a6458648e39d36c730cd2801cf0fefce676e819b6a00bf52f94ac1161dd5b8f15d9e696f516edb6e5ecc947c8d0a6d9d831824258a6483b9753a3756541ed8210a705c42f8a6fbf4932938f3abf1379f65c5f7cce6c3e41546aa39dc76e98cf637b23e86791faecb47e567b724a3d05eb6cded407335fa2a6c38c7e40204fe248a637f497f29a6a2f08798b8335834674fab1c103afcd7e6f3709e819a8621c7bcb8dfb161b6991269a213f1fafded818240c15f1f35ce3f8c681e81e2920e5ae69571cf8974b3aab11f3c09c22560fec868981fdd78bb70fc2bae4810e0327608824cf447482012284413a27bcbb2e4fc91119668e3f28d7349f263b5961eeb51ca710b7801a4a427ac53afc3e35fc91d253d454153e299481189ecd3639f1182fd0c7ebf49df2006f40bb2e158dc830ca03bb9910df9fde085451242ef721a11caf1c84ba679f6bbcf8d45bf3008c61058bab87bdbc79b4b9892968c372f31a5647c586ec445788bf8ad88f5962cab3885af73a30234ed1ddf012fa673f027be91433bc074b67746f45ced3dc9beb9e58339808e2ff7da1acd68d69ee41792595ad46233a71a2d68d0600864fd28074b6f2bcb53790a685f8ec972858f2ae52f6d129746959de7bc99b3b404b39ac0dea78826bd0e86ab62cf325d4c893893e2f16826f0b0a343c235ebb001bcb4f76544ec1f428a8a7fcbd9e7fcb12366e9315a724190e69d4c2019dfdaa54f790c55b10d259ce78b94b04243b72d00c25652ddcbba5b5604f88d87eaaea11e32d18d50835f97f669836971a8f2752cbfe2d44951866d123de4846ed4bbdbc98406b421100335918525a38a51c6c724df5515d4bc198359fdc1df2610f2f7f8f4f90eaafeb11e0e96819882906b3aa3b888096f87dd75887617ce039b393a8548ee95c852b1cc88cd1860c1560387fff11580665915ff227c215a27ff023d3bc7919ff070ad27b6aec2a4057130ce0f1c2d80bc883e80289ca9e3227c039e6c137d7c698d8932193f29d6e68025cb7717a642ddb86ca3e545ecb457ec8514d0f9baf706b1b6a36f19dc5a23f62b6916782366daa1e28789ad2204fb0be8a5cbca8ed1818501a51d855418cc0704f49557150869b86c495501f9048d60519fe759b8cec8d921ac1fbb65d920fb95fbeff5e5a7b8c11a9792447e0de979553c1b8edebbb9a7e7cdd404d6e854b3b339b91c818ac3f1b13560b2b4f7b7b4660bda023b773d9d51ffcb22498bfd0b08c8402e403f2dea1416c6546fd735ed70b90dfa68c3e07e29e68ff90d6ae1f6f440078d53b913ed4d7869eb784689fb8a0040b520a64ef090350164d6e41d425c97e62e1e70d533435d7e104d73320362872df7f508c3af4873bd5343a6bb6d4a7680bae0943a9e83bc8a48362887901d5a0be1521746f8c22b8befc84508eb87da8cf74e9ee48556f984fa0514923ff53d163b0e45027985ca95325dfc788735bd28dc64a237387c5514f191294c45d1e7c84020a3f0bd75bd403e70c8eec15b8cff58772b1e00fd24d035ee6c0409efc3c113540b2a3ab8ab7e3553966db71c4be89341d1ab0dac6d5d1a21c29c58c1c24685aa9b437695d48dd6d35aa2178ebaa6e6b078b23a8a90c4f4451750f682e272451301fc721f38188b3be4010ad33b88b736fb98f6b2b8e712444f465af1b33703242d2382819af36e0c6efd0e7ec4d1864fcbeddeef89ed70632ff1d9c5fe764afce2cc41ee57a3b5638c231a9b14dfdfa7edcd0906b38f16ddb8cdccc7cde2af62e3870ec5901aba3bed548e7fe60711d52faec744e2b42bf0cc761cecebf468ef847e8dfc577c4e7781dde145ffd713228db137d4212c1f4c34cc84e863803792e010193834724ecc262114a71c0cbec9ecaa768fbf00d42e65431d59375918903eb78acfd8a24b114a255b301ecc5697dbecd637a6a19c596a42f6e2df1b0173db5b135f4cd260b42dd8518f6f8d9a3e9e262ae3123e3b097a87f112049ff4bb0ba7953c202a44473b4310ee4a9b9966078c3b637de5cdca9f81459faa1b9c31185f629e217b789217daef232854aa868b76b7f9918bf70d5c40f8b43f7bf79f045518f7f4d2304b5428b92eae041543558d08290e98a47e410adda25131b6d788704562740b3d6d532d77cb4ada4a9c2bd1f6fcfa85339f5c123987f4f5a120f5dd81f161e3aed1690479d09675e201fc7b8e30dfb6854b53d03bf7032c5ee2b367df42a3c09e5a72351181876d0889eff3df792731c4eb1d8063242da59a4842e79237fa7e8ff9cafc222945949b752aef6f3c9c877c193f74e20d1c1f787d9d2469475bce34034e2af944bde8c71b8f73499b82a3841a76dd07d1a1955a7271549d8b59f8441f6248afa3a58c91346980ae1eaf37f5d42c3551333ed87322f358487d13c6f4652ce2ef3f61cbc572c1f4268b8377eb920139ee8518295057a92c3e6b066a5ff44b77fa20a7e39c241d040eb8beaef99a31de9d3fcd5d37e838bbd27d3b9f8617ed360523424bda2cd8d313fea57ab9ced863ccf303300a4f0509295b77b2626453ca5320892903867cf5953d7cecf6de45efdb36e276b4f6782241efb00aa112f2fccf23a00fd5d3371e02fa11d3bd4c1103573f00c27ea29c079b40db0f396a0b816921465c7b8101ed4a41511b0fa1b6d2208ac432a49547b32fc069a0519f501bb9e97c9b48e722e54c4237a912259ec259eb3ab8d4bd06a8da1a2986f4056343f563c55d59e591382e2babfbc347dc0a8ad620e965f3c31e1ce96f55855f3bda35a6c8c69169c6f3b0a0a182b4777dfd79c2e8ada19196b9e2411223f86e5eb5b14109afd5d369b4f3054dd09e0d1d21c14f7c11636497f86830273cd6f5c44639abd076833a10c11a9e527f018b7d54ce98b5223666eba6d785d7e64129255ceedd032426461a17e5c88335b28bff667dca482207a0a59a23faf5b3c9f4bd617c2435701abb40c24cd5152ffbadf1c674021b3c30a73300bf363c63b7f6d5684542531c60b1f43316bab2b2b2664169f35a2bd8b7d45aaab3c493561dc209b24d6a5facd6bffd6ad1094af7791f0d0cf0bf747607b9ea9d3fc68320aeb15013977be7e78567b887b9e2aa138e25e255d0734d761131ce1727e552f38518af98a82619a2877bd9796b05d4b39a252c4f8b3a93277c685dc401de09dd60da8f9a5891001034054cb438342f7e16faccd6294ca0eb1f2ac05076092db21c8ad4c6a897fc9a6eabc7cf3ce1af78e15da170151c8025eee97ef7c3d046e82944bdaa9b4bb0c73931a95876fdf983d353a6897df0bc399589c5e8eb83453e3f50ef993e8aac5f0a1285f7000de5739d23b185963a2f98a02c16f6c3639c5c5eee8103a24228fd3656b2e9f9674ad8a2fb6c573a430f7a8f9ea2a4b5bc70a8042be4d5abcb939aad54e3554cb2babe3e1a1d1bf238493e9e1f3b9b43ca67f3ecdefc6e410b3b5d970688031ff9aa9b1674cfc4609487cbbc889121709ccfedf71661b253e3b9bce12db9b613d365597051c27f8964bf766b16c2348e252d46d340d6b18f365003fd520d8e2202a74da5b5ff6ccc3a01c674f5bfb9c75deae302bbb64e94d05627cdd13dbdb52779acd6d8f22781817c49298e137fbeb8133d3b52eccbef24dca39dc45d5bda45c6f2c6be9cb841545d98089760f7434a1f2d43b871bbafbff5eaba40b1b619c4ee08a609f15bc3861bc1b140a51f81645f3debdb3ca5d6f15882e066bbb2ac3d0304e8daf91ff271ea6a48bd327b7774e2a0ccc0871d9f7b6d61cb572ad6fb4e3aee10499289c7b4cf2e4e4b72e136da492a6087f510a5bd4e78a1d01971ffdbb863cfa2e399457f9f1662ed80c7c64f36863316bc66b37f72ca13c84dc54e028210d85230562bb0a628afa51c2dbb35c494e04643f1b7b31ee819055e62c2b0d0bde71937a62b039134d5441144738ffefd79674a1a959aa2a6e063d3d15abf610ee8967e4f57c7f984ebcb26e733e33156eccd5bb177b9ad3d93664974e5fcd688265f7746020df74f7d3bd4bebd25f3777e3a51477ece4fc2090d9eaa11417469e9278dfa258a44effc0640a19725f5410b56b4b5570d2592671548176a49f76b42f8fa603c26faeec092c8c3c1bc1465adad88b30420d9392562345bbd378aeaa240ca98da8d73537c7871ccd3073b8d05da998aeabacbfdbab2e97d36614e62e281235355d1192b16e5f503b45f7c3cc10865aba7cfcc64c3d1e7cec9795957cb75f605073d611bd40e2a3e65731dbc4ce05846fcb1cb039830e480faf673e9cc6eddc5bebdce0f07a1487a4df35e9b7e09e7c9a8c05884d0bac664e3e9b61cf0e3ab10ad6aeca218a3cc0a2de685e7e6645396976abed0455343989384d2d1867527349fcc101e88dd68a7fb6b47a9150a8211336230e6f80cf79d42f8a1c59a41acf2dd361cd0abdf5f14b29e3dc042e15e369b0a2aa20045b53c07cea3fd8dca79cb4fa94c5e5d41981167df039368ea36f671144632262c4e2f8e1f0c047de98465e1c7e8226ff22ac68849d3537087b35107c8e25a7db31691adefb58c53d7f8c4de5d30a7aa030823eead006868f89271ffefae3f4491b73f93d1850bd773f8b9d59f0ed8bfe9ddffbc5ce04543dbf4ae1797ac741412aaf57e93d9592845a0c66314ab91038994a509226b306fd67af7c001a1f4d654ac8b13e1df21575d6e5b4c209e2e9ebc9d6eda1bcc120247bc881646f7ef37f7d4f0a425f970145a309778838d96ff25549fe2956ffd76c4470bb18d6b14da2775b0becf2713ab3e8a6ecfa3c0e35dc560a44f463debca31006e42a385ee677325ef8178711f149d9d418866b34b70ac907765949a3aaded00f46b100f78d57d64909f76cef4c3eeb542bc2cafdb45b5e0ae6f1abc135149970554a38f054d73625f251fd3c5b2ffa161b80c5f42767941bb0477ca8e32952ce3c4cac50873115123c021b503fa41f536b7593340161d99e75c4967d3ff2a8792f0d5afcb5484dbdf3b9476f9aad4b0b299ca08181a76d383b6409bc703507647d3703a5e2b670ff9b237d2675de061f3ee099db768f7949780f7a42270ec88c14eae3b7b1eb0ee492762f4814e64a92ea9700091f84dbf77e604c55315975a3641b5aa66f97361784fbb2447c707f8414ac07a8e0b654025f25acf5dd32e8427f369c29b8491801855bc661073ce86d469876579129a63fc1e1953d75777d7e5a36fbed80aadd064e0808e1ff9eafc5d5fce79e8b6aad21dfa03e338536e01d31ae0ea4f4ef3f7a7c7e719815d1968c782a2e7029435bcfffe2c6ec7724b6134e6d8e172927bf5dabd41bb4c821ae2af1c10fb4bc4e4ceaa7de8641c95bd41ac49df08b53ed0319882249cd6b33c83f4c731cf4864d7a4e2eebcc9dbc7246121f9a540a9b25f61c91f70d6139f0f0b96c7adbf73b076b037a00bb9136022c49ff1bc81d184a68391a14187b23a79e03625d78940dc0d9f067d090fe11910340f310c42515cdb184714889c25a2b5fd5631181c2bd523a5737aeb4df34007b1536442144d78e7147004d2fa64b2f071243f38fa636d6182906e0067fb35d707239a21f61293255598cc5923dc5a25f54a3ae05d6a01fdceb6d5c5a4da197ebb1bb28c3b2d9bc30e6d5054e18778ecd8c35b5cdcdbdd47e2871accd8e58fd006104606a7c35f68834916cf8d6e2a8e274418f7671fdeae140b3d117e1470a9e732a1e3376ac745fc4215100259c498112b38d17f2b740d33e9834ef1bd80c7f9d5e8dc6c6938c7a829a3d61c1e0ff052ef3148122839f4d6be140cb5d6e12510147ab5bc9f264098dcf14df90f61ed215b6a403e5b04fdbf651ac169252532a53d29ac0068d689aa881f8efbffb35e51e3876307aea4a89bba4a13ad868e8a49be3a556f4656379becfa40b090855e27ca2a12df47becc011326b9c10b8e789fd290525aaedf7118bf1e7541264994fbe48966f652879c2352f4feffcc973d4bc0238a0089daf4677199f4eb24cfbd931034edd290ec5c421ae550ca3f0d5b76160d0577dcfe8c4c283f30856233213535fbeae658ff975174cf4d7e3aadeab6606130c4168373e02a9a3b09c846675b3b90c0dc17bf241041e968fe4748fe7c504d99c26d7219d9dc92061edf59e0fc0b2b41edaea91294e8f9658f600d5bfa9b5f9e35a3f4236f435d01f7f00cf27e3260ead438a03d8f19f7c0cf69adc5be9ccbbea2206ae06cc39811af2f77af61fcb087c9389ceb4ee7bcf51a15478bca813be6c82ef36077052fda1a5582206a649ab81b7aa622b228426a30759c104798caf4d76ff57773e036f42bf03c0467e1dea9452b3034b31aba039f9d6aed4655e443eae35b71b8f39be3b96606f752865578658bc31ebaf1db0df12d760d8bb25ba4332003fbe30bb189fdeaebf5d4aa6ffdba30c6e11c676f87eb9a4a24f771a4996b48fb47e3cfa4ed7f8c4dd9571432b256a821540f087d0753a48450ec6ba86d791b4abc943e38829b62938e348d24749c3064ec0109e19255637c1b3a254ca9c6ce8c34184aa6c382e814d5bb5f476379113e3c5573438fc21963754937cc7082ed74b56ee706f7c547a07ab8b3f7e392fd8a33100dcebd039a2ee747cd840b1315acb1e56f9765066deddd40af90d13d27ef0e34f83e063b06a9c1baba81799f606f50639ce8633b10ad77f9f97da3b0ec9220f41df2af5fdbc912978e48113825e440ab5657845a2b084db19ac8843877e287daa1483984e07178f77e526d89a091bcf07ea6d424a9c4a60ed69ee0d0da95ad150360e53c4bc0c20de50728b9d3f247c81fd849f7eabfe4e2edec5e954a5cef7bd1d98259e05adb767f4fc76b808ad658fd27a0a79ddfb84b0e7a0f715827bad2a2f0f0e81a424f8dc801b7d73992340f39859a586e0704ed6d558ae62a025a251f897126ac53ed4126d9dcc79b297fd32511d9aa1a73f67030f9d5e71f1e083f956b9e0c03dec9d1ea40edea151c01bca72db1b5e6745a6b722a854fc6e75a3260e6ea0fd839b80b1ad07b34d4d81ad583a9765c9776d340ed1e21dce7dc4de0621d7d86782e15342e9d39d4b237c0f74eccb76f075e619cbb758edb2f173a8d50b16cbe8890039edf314c129ce330e41d89151f6349273cfa872c0feb2cac7c7893e1ee4d532801aec71b39c1f680d924dabcfaf757b6620d3111ec7bd19429dc32b1a3c438f7f8c9e27c5e766a0f8feccfdd93194002063b6d4f41d622a20f51ea0f2f59d476b8191ce5f31934b6863d1778671f8d5b79cf4b44c3de28ded83608a0d54b59deb25d6a2a19faf086caad59e1328e43db659974088c9f479b084f40f0c732c201a09d8422ed29e4272abcda3227f6ceef3f9623f4e8ab028325d5bdfbe8eb8c78687c0a7113ee6349123b03c2cb75c0077249c4b0485ea1ea9a47f427266bdcaab5b937fe5c6c7c6484a3bcc936c838e7dd5b9c2f2613e0d8ef1c8547d4869df02be579ad5982030626f1bb97db74a5740afcd6dd68adf16512060fd8900c4189be02d4a502e20d11a9f3ca865c78f35a7587a04a18eaddd071b4a2eabde7aa280476487afc12681787d51f251085091a5888c34d4e9add132e5c3bc829b3dad7a7710f16355318656de03bbf3caf6c397329e2b2e0c8a3909a81c633821898e37125ce3dfa90d701faf3a53082cb4144561259a50ddf2c7c039fb229df9160467942520e7cd354a2180e6cadac3a463725975734ab931fe301874d550214de5eeeedb439ff13cc2af1d84fd373b74dab6721570454289ad62d5d654299351e07c119ad3a32021e2166a56b6e5620928aba4ee3d3a960cf33e98f813424daef626597a1f7ef7a44ccd8aaae281cfc4ee585053beaae8716ecc0688cbceac28c520d838c0936e96e65a19fd142892e1a3832c46ed11425473c51d4fac4b62e281dee361999aeaca84fdc89f5ac5de96f3ceb996767e1a74ff1c9a047d226e9dd3209822394274e31556fef8987fc36c029ab4990996356955f8b39003214dbbf0e9f2098b13e4186bf3b55282327c21eeee0688b018d9e81c1b50937249bc531dbc1d4b5e340856533267e5887e061cb2af638400d28d80ef0630e74bff8cd403e81361bcf0f39afcfc964e474b1da5baaff1bdd0ec56330b1f5c72249156d85c2bc7e93e1d1d9aa10e6146cfdd910cf0115ad1c27a19c35daf333cc9b4b731f0e09a69577da2dc13a3fc50a5b0436cd4c54c12d8c2203c50e17c617b483d6ef5439484ada5ef56556b92537c9c3d9a27a9eae09f28510439dbb07a94305862f9a2971c85bfd197d66eb8eefc13c6425e6297a5458921bca343a71dda25f2d916722e2229fecbe5005abb73d7d15b15be2c9eaa1deb1a417e4223257db73892c1110faa65b695bb113fefdfd5676587ed1996d197da18b4e8c7e9ba0ba1fa5436b3f1a4c1f737a1b078e350a5f159e10e3c957b6199085a22de3d34ad9e1355d39222a9180bd0e9a8382a6bebc7bec0d869a8407ae904462162fb3ecbf493c30d21b60c1c8ea1b2df2808ebcc58842b95dc05f103667d60213d234791ebf2c34d5fa72971eb527e131cb02b61129e1af1fc7b3db0139e5d7617cab26df910a7d8b73e0e49e0cae66f60d0b762d2f4e60fad1f3ca8b3a3e824704f2a9c539767a49936fa3e79961ace7beb9546a8766b6ff357afa8dc7e3d47cb08f6b655b1a8b743c20bcac175e7510941496fecdc87e40f05b045b1b19720f5580baeb44284e54b9b6a93a921e71bd728d1db1d16ffcdecfa82ed7cdb306c79a1bdb3de3ac6f041da87b45ff19a7f10d9f277916f52823e12a8ac49e76e7aa2ae4596307e89d3b7b6d03bd621e0c51ac9da184b24c73d57e4c828f7c31531f7c41c340eabb4c73a1f306815e0d2674e78c4b660d09e21ba4a576b042f4f6cc66e6cdf8a0be493575b72994c6689f3db35db3d7b801cf4dee71f5e7496ce745f0937b122a2781e53a3f31822d53eb404d744570bd4148e7159fef0b09f91f650437c8714f6cb1e34cb8f022c5503d3fbe24f27703d226af233ec2e5390bfa473e2dfdbf2deea222f66f085a3229ac3107657cea6f9d122671a9dbcdf48c977caad7441c85ac03cca0f7b59861b9efa2c81240c93b3617502e6bc3ebd511d870098aebbd6c0549759692f17c5913fbd3d13338c0548f01358051b5690de3b5d6d70c586cc478832e75a361eb07d727c5de3c8cdb8de6352e9f314e100692f47e865f664c12655d6725e778af09d01e82318c0e5624ce55ffd5a5f7725f2f310f0f5a73dc39e41762092a1a493290d2b0394faec2479effe9e7e6cdd96c8a7253210291c0deeaeaf121a7b126298a1936d5c1e3190cfb3fbcc97500ccc917757adfe3aa99c19d15ae8bbcf6b4ee980456ab9c7f4091c5e5ad037a09673a70ad277294030440cc17c1bc1da920c61757b3f9e53c123a4fc9393c98010ee75d24616d45864eb360db3444ea6a4bc71622ec2deb22f9d5cb183d9b526f486f06965f904c2eead05503c53a27642b30af83348224b8508c505df164ad96bb6a904c8817e7e4756dd0c602369e951b60c4d2c61dae0cb2ee27b4fc4901a87619950c3cf0a409c6e8a63ecc2833b0a5da8c6f23650e05298fa93e7585e0d548e19918e30e4ec565e2c314757c01d311539963fd33e48c103dfb6ca9a15332a0f2b9e5cdf6ec763e22cda6c814126b0f471e74c4f8ea4b3e98ca192ba55bf49995da670da715e41c5ef886c4fb38e028fa01b369aa22d15a9fca80495547b497d0db9152ce7c886b5d8d065772056d55b53114220607d63689310c38a4dbb9df24e60bf33f89fca7f926415b62ed7bb8718814b718ed0443e62c91ad28a1463df68521fb27821487a3be7a8340be4f40c1425ae061c7072f99b330ec17745fbf718527140e3af6a74bd333deac94da5521c4552406437283d63b9f14d596ec7fbac8ae4a639b3bd704942fd0f406914d7e2989d6f7ba61158a556e6b9a8270e189d0d2b66ca1b1c30c0e326aec273a400145b101d80969c8581f2c27a7b3abe5c1d32d9e1c6dba5394f312b4588ce25e744d9af318f3baa0279d028cf20bb192329bc42c1132e05298f38c80d353d48cb4c2513a4e1baa9528ca24ae02a9cd3c9ac8bf0eb318ebb3371c4c46fd5188a55c80e547618e974508358b28a103e188e4ef0cbe6f6b3481287bbed407c17fefd57c647524cb28d8f80ca1611cafb3347ee0422a146dc4b67799c0fa086565cecad186a44eae3375577d0d8aca23355b77198d9fbd1c2295b7597821434e00aed97be6f926d24610093c75b93a8699722c831379197a97b6c13a016471e27f05cd9f34c14d76e4fea1d00a837125b653b699bc42045f12cf8c7a1a3d5c36313c7e817f064a23f73bb0c39a773e3beba2e5a36e8669da2e4ef246bcc942097255b82bb3070d2f6ab2dd4530603bd03453b6b618f1eec90104a8a9a26563b57e8e663faa6c232961dd28035dc954b8ecec10d480f70b59b04ef6a18ff1983c097966e8d0a666683a573859d2b70f30cc8ceee34e4e415343889931da3aa715759de7ba8101e1fddb248d15ab93d63817dd1d5d9ae4c6437fbca79a02d74b36cc197d66b1f6cc5974190dd64864b7321df0c605a6a6454cc305ffc7a4d06c4803b5a896970867c12ecc76b02122096a6bc0ba3f1a99745f52641bcc77b33496e004b2d8bb15108826673e2c5d2123c3d8fd6f0394b0ca65be93427b1b1d8120cf066d6579c7a4aa696f2534d4bd47a34897e1ba3cd2848c3628b23c47af0d7dba8b580dcc6161f95ec2431cd86d8d535accb20ede1c7f80cb14cb052d6d6f1016fc3c7d77e80dbe73fbcf8850ad5dfadf1c9a9a6e588dc59bfd34c6c4bc7339e5a57f6e3d254048e6467a34580337ac723511796efeb52a12bdb8af53af167bf7ba07ebb4489f865fd4ca79f82eddfe6b9ae757887a3461c6d87baa95e89593109d63328420917ad187fc2634329fbb11c1acb5bdfec6c03e2a865058794ee2dff841b8fbdbb9a3c8fefb9ec60fa4d4fb330b59c2a8e8340b3a69ef823fa29d12b549333fd0318d9ac37974456561699ffecff56f1c91d86eb2147e73e3f8b45fc754ec8aebd5d47c0efc7334572c9d1df26e7eb72fff44e911e98c59318092a56b49dfb3221f2cb10520c419c4b627ebce27d6ed461dd6624ecf14f8749f4d4817664f4db394b763e446cfaae6e9894ce3fb44b5bf9182d3186cae6e9d288f2d4e7b902a7677192fe1d7833367b03d561a07162e956b4b99f3a7240d80af40e24f94c2a4792041b20c129e3727b19ec157432923f18a6e4b22f58d299bcae55ab8549cb870b807c71cebf3f31697eef68ab7cbff437d98753f8801930653516a6232be9b1612a51899f96ecb485ee7b3e036cb835ec094deea491ce91ed131a3801cc862f17bb5c97fae352b0008fbb7f33eb47fe0a68b5e7bd0b494eaf27402b0170be700c933d82b87e50b9de05bdb0859f5ffe32465e17caa39871efbfea6ad18dbd8334b22e774f5dccf78c31afb81bc55db4960c012a43285d5810fe52713b3bdc3ed68e2f6e77132b9b8b68091dc43f2161f02caed2d14041fbba541077a4b6857723cece2d2838a12c7666df6b5626d3f47d94bd22f56166b7e8bddd739e567904d47fdf62bbdff57764f5ef753204e452eeca5f57cb1e01a65e8c098825ee19a512198eb8b37b79394dfde3ea91e59fa017bb44c6b7e6b795394954d3dd81419ae63e6bbf39bee16fe32a9341158aa96fd201691abfc5e8b332e8b2f7cc603c943530feea351096e7ec155ee3f592702a4d577524e60fe566275d6c7a1d8648b1f801e5f192a7ec71adda4efbde13f02c252b8d50773ef9422924139dffebe0093e1b66c11f86c2e407fc4fbc56b2006f181647aeb91e9395d9437b78acc638889b3764febb57a24458f18676179b77a5d5b4f761097ce28b2d98a13a20fd522e4c98c52e640109faebd91d8a43c7111fded3a04b15b09107606099b7b9d95866ba37aea39fdfb0cd50bceabaf046b7e00f43d4874a05e22fa4aa66bb3fbeab2a5d30c4637b3b8208e34378f6f626e18b446f533d2de056709b6400cb5af0e088ac4740dd23915d2f3faf5c63bb373772016ac4be012d934ffd604735fcad52d2068cd71e35a1bba5e7f0649fb557ef700132608b34bab050688388e6eb1619406fefa1004d5a24fe1cd79248d33ee90e85db25c1746ea3cc8d9c8b44a9bf65ae2e79a557550098180eea267dbee468258ca0bb042bbb41098112871aeefefda4ddb8407a3ea6ab55166d6c9f8826817aa131ed2c881b7cb542c4de937a7f0e6c08957cb113f6fcf2e45bddab072a276a90138ab22657f1ff10d9485882e19b4fecf2ff39d427032f27b42273a8a302b163090796990ec1cc30bb700370483f294dd12e090bd1795a29ba629d4b0054226b7f8e3d0e5bb50cc25c86d327d0b0a82911671a8ba5d1368602d14e1dfed5d78268fc041b94cd1362bbfa8ad405c6b12aede7ca9ddc8322ee7075b595677dc2dc7d4028457b54b9a7d4cdd3530012c762cb2445da92a00976ff4150146ff4def8d7fac31e7c700b4ea33c439d0c56a3731e707a8e9afba9c7a7f397217dce96af8e11f106d6fede5095766411620164788bbf1f4fbba6a1dd50576ce0149fee424d0d266be1c2dc43ab5aaca44df1f301d2561972c4a48e04e49d242093a9f1b109b415eb21f0a4ce71a9ad25ca32672fb87a7c61249394d3392e878408fe47112e20a65daeaffc72c462c1e56cdc6c2063feb2f5828f9e6bcf1c3fdf17181b199d7c6e2ed1caf34b7b0e73f26e22f26f05dcc4b9c9a5e6e8c4abdeea6d7b4a755c878b21b2f0aa786ac7309a17cc76721b87e47afd912840768a875473649925fa3de50a10fb99f75e1f59cd041f4130591ee404f677f2ed5653a38338a2c826943de93ed9158c04226685136200a570c9c5e735f3ca7330f254429b27911c34aa5d3aa72e473c4f70ca2f282c44e4ed74c104714cc7d6324ceb531b69c1966b6f07eb3639eab7f3e0c154c897cfd043c63e022e9bfc6c3245ce636c2317aadda72ac43559cf6a3a36eb0e1bdd6a82a4d2f737bbe5cd8c9a9c664241072ef94ef36b3befd7adba0cea9cfbbd8b4b1a3e6e16e55e78683636123ecaf4231a5f37c896edb74f41913400855c5b07ce9ec8f0ac27bbfbca4fbec84a90c5030e288626ba7ca0cf778539cfd6939de8467d6d39f347f115a0477cb63027d98dd158890e1e20de226cb50a5b9437cffb3cac3564b2964e691b9e2aa4d88634922b4e004d328858fdeb3292c8564d451898fe5477ba3a81d9691f6c7c2c1d7c79336bd4186727c2730e5242931f28ca122dc93bda3dd9dd32a4e4c7355d065d3cbebc6035c6ba41557db1642afc413f883a702150a6165faeecbdee81f9c74d05eab815ada5e0a46c3a1ca251fddace15ace8134cc9802e36bb816325963408301c52cc2fb407fe051eeb764f6b516fac8b0d2b040fa1e81f95eaa4e493367c352b141fafef6cac09d4e805d7e022d4fe0635328071deef9495ef2ad5d8e318637db7064b3bcf9aa8e002cdcb4c8bc2505cf95465351a2ae62c443e33998b45394ce0308385fde4eef88ecddc66d524104e2a38f89b89a64bffffcf4b80d2ca00990fa0d83d18204b954d3c1a195440f78a9d6095112cdd95e48282de086abde53fdd5470f906ab42fcf26130ec63bce23e57d50e1344ad346e92d3c93714111aa744dc8fe0c4296d914d1f624187c18400906856c546b8963cc852482ae448db476f357a00b172a0c4d071d80ce7daf95539ba23d2c25129b334bd533c7b325f9779e7a4acb4fe00f5c6149ddf6fa08b2b1d563cb283a9af3e073410f692e0ff5143c9adfa3b0fb1b1ce955ac0fd53c1ed13cf71f2c6b462c3f7486e5911b3dad826c71db834ad5037c8e9688ac4ab29a0154dc7ce3cd3dc93985c81909185ea839ed9c7cd5eeed73133cfb6b691fcd548b805bc10d01678e575c1ba3159182b7590860d055e8c14cacb99df39a0e26349ba783222a57eb24846daa51adac801594810660e465c8ea66b06cc5f56acbf6057c6a5127a1160d4841389ea1dff51f95da528b3a4eac239dcde69771159bf4c946ac3c248ab946072b6a1490557daa99ca1c1da490e7c7bc6ec516a60db510d798f0a71ec90c08d4eb313fc1df257322d26d4db837a7c89cb7d69f9e7bb626ec27a3d043d1aff88518eb3300bb091a8f40f363133799724c4a6ae54fb081158fbcac791714e7e135c944875369a28eaff3d7dd53b78c2b72af1b2c9d69021930277d23e4d13e81c01878ac78f735b2b66e4651718cf9967c6e7c6d4169b966734cc2a4dca1089ad98e36ec769283409ab2c3d803130811a45bff7f28f9bbbb6d61e1d9ea4e576f786d6cc4fa6ad50f2ae18209dc869b8fec22fe212c1dffbcb615716817bf0248031582f53541f57be9c6db65955d665d032e47380def92d70773809861b6bce3781cb30533893cdfaa1bbdc76cd9f0251ca390fe46d123ad990efacda3fba3d46d7b6845c53684090d493498231ab5bf35e542df38c0760e24d5eafcb5565a1144169fbc476bc86b8977df650bdd3d1abe3b2573cec5c73aaa5f7719346e74660972cf00f319d082cb1acb439759ce6b7183f1a09c946e7aa51542dcdb63517eff8e80308555c4f81743ab95afee1986828d8e389c82090ec97b8781017f25803ada887795258c068d99192920d006c7feeded73180f77a44943b92d13b611e96ee7dc3aeaa0c9e243223aa17e799a848333324decb34db599ccd85b99d2f42c7933ad4cd6a119d184e0bfc049a5c123b7e77128b9357f76451174fe6255c54e3bdb23433b6ea6196250f13b249fa1075cff331fdc89e35e1d6c5e1e421448485dee9aaeb43ffe338f3feaaa877edf86e9031dfb3c61fe055384af40993ff19b9126bb2b81d4200d2dfcd272a5491a3bbda817a3ceb4927f4468a29240511fa40eb2d6ece3a4b4495cde67263b7f75b3ada34f1879e135d033c2b7fe208a9930d99db635c5e9c8079f8a1e4e38d4bd7893f0a76d51cf2612b7bfb876b6d7854f4ff96814a1dd2750395fcd8e1110248b081e0ae281ebe77f021358886e78904e31ebbbf59145f6f60cd65753ba70e0f3ce5f458f6de7e3e2d752e8bffefde972ecdc44806081e8e4abb60f37b0b9a1272430e505b41b04548e32128e34a9cf5f6ade9bf5b215e3d47868d630fbd22eb9aa138a0fb6c6a40c3ab0bf113cac517f4734697cf104898adc22e8bf7a9d5505f66f7b77b4ce99ac08b0036c5a5860eeeb35db26839a618c196bee9455f0784ea2812bce1fc5a98b7d0a73bfb76432ce1a5776b9ff6a0ddb9bfa1709e58969025305276042587bd490f4198cc0ad5a9fca4c4d8270ea6024759dbc51b536f407e2575eaf68cc82cdbd91a40836092fcbb51126b780cadf0d239c841502f9a8b65c5c20ab3dde110baeb53e46e0b4d402d7e49baffcfa2027487d4bef7ef9f38448e10e441883cad8ac498df1c8a4213b1d59424a177d7ba7c414d446ea75ec8d693874f6d651734bb9270599338812db0cd519d82e5ba8633dfa04b8f0d44f54642bb17b1d35fb0a3709b1a00a4dd998e054a8d1df8386a668ca3b34860dc367e9679c208a6ce5448d314dda760ddc8097369708111b529fe7796eb14cd53dceb0fe25a5631cfe01332f7bdde2c42ad5568bb70ef1e8359f5470174dcb8439330eb975abb4edea6cf007958f3290b54fa7c700edf3aad926e1c6561da78f224bd47d8c2be72eb8f05636c34b0b3334df5198cc57f504e14c90671568e2c04fb36f11c7b164d4286f207552e6d2c2c4dec6a383a25ec80d54ed0d3b1c16fc6e39da569478d7ba9410657bce1d2f84cdbe0b0ceedbdd7ef933550911e0246806d6c57c2b1b5ef0ed2de55772b62440fb3c36676330de08ccd10d37ad78640b8be63f1841d7a6b8b0a6b5d4c698122c10ea36a23c20f73619634f824d106dbf1789a9012580c587c4778653e01a5c40527ead06af634b334404891a7d8d6be49cfda1262be6ee0099faed3bf05626f42ce1882b7ec76de75b058ef009fafc847f4fa49243c199247314b243b2e9f447f772ca9c6f79646397a33ca3b7905ae692258270fe450d449a7b6049a8ab0431bb2d374256f9c42c3d0634890998cdf5bacdfc496485d3e82d575755eb4de4710aecd849de9183aed76e66c8e418c5ecd738c6b5c31c48f6238ad80ffe1d63af7230f3182aa8f1ef97548ea271526d005c4f5fea66f147a3bf2679c3c9735e20a0b9735d1121ca05ba4193712e5016120f5af05f8348b00fa662815aac1011817911bf14886fb978d302f4b256fcd58dccd38b1567e018a4fec97471e5209477e3c76f2b95815d473dbbeb687ea38898b43d9ff531973bc08213689eddc765c1d56f30e76408f9e5559ad6b7d5d34cc3960cbf7e0ba5304b30a5b7e2ca7630d8c280175898157f12de6963a6b208c74aac3392f2c7753ee6814dc2228a047b073adb01d8b729c4e3cab32b55af638d09fb70bb6eed5bfcd79b9e7e4237a1eec947e3859ff2d1ee0a21c2417c038ed11963f9a272803f98fc52f6319348ab0d58b4495fb8f8e37759fe7479a3e0b7a9fb63603505ca4c6d3608b34847404776d04f8ad9022c4b4789bc5c4286f81788e35abe1172c77410402f7ba9a008695bbade4afe50c9a141603074d28656341af3fc9eb1e68a046ab32e90cb4687ae48cb78cd0a481d518a9787064f654cc375ca8acc25b24238aedc28924124e4968ca9ffb6eaf1f783b0fccda346c7b8ada294486fac79ecb35f5f1b4b60d4b5b17668d9ef654a7d69f70ac79bd6bb5f11c41ebeac3d0d1bfd9a5c85c3d2f48ce3ee090758aab4d31394d53bb1bbb2b761a3e12755f777b49df883112ecce1f882694c2f9586900a413367d62957d4933f2df45807db915ce2d57864e357e91a1aacbd153dc1a9feb390b6e9fd6868b12eec573d3bd80004e28cde8f7f24c403a4b0ea6e9fbd1d7cd9bb33e99d442812e3c6d662cbb51550cb40d7b514192687ddd841a738ac8528f26fed03048895cae59d404dcc828b8758c0f987d1418695b6c648dc9442f2c01963bf8c56e231b13b1df072b3e79af215b9f18dcfed43e51fa4712cfdb2523d1528ba3d79959a4bccb4e990bd72c4c704563d05f76e601bd5e3fdc5f73fb516f87fba9349d0ea31f04ed3700fe6b1eb8c597ccd860a4e2ff2c7f817d856d7ed5c50c94fca6abd51e31abf0de87c40167f61c1d16ab5865cec84a42ea9b688aa814f140f7bb5e27d0c331ab229062900f464b2ab34c4a804b12d4357bd90b0fe488d0130b5832dc971ca4908d713ad314237b72d72e235bc232d169a35faf1297493c87eeefe34d11a4b6bb12a13bd062af237c2f3c35166dce169801301153f606362ee91da1671ed38bac942f18029153358a42d570014f4942b37663745b4dc88c8045420b8243ae5764553e51a178ee514e60ac7ed51a53410346cbab88776e9629caaeaaf1650e17551ef80129bd556e4bce7a1e7d0553a78b57f3f3e111398a10f52c6750a72a4529897bb867b8e65052c152dd42dc746d5f87141dd97010a3900d910c211261b90466df029c5c8dcaefc4689477b427999947b46523abe67362951b8b8d8c8d692d4ae8bef626e40d870cf04e11d665f7131340ad29b076861b03832b19b2e47e9d1c94625585ff432b1036fa7456437168bbd24812979b9b48e35c2c2afd9e56578fdf0a580b0abe2d2f87e13969a046eb51e6a7a0a3ab5cc562566abd826ace848790dda48c395e59a2bf2c300d8ee2c0cfd9df8258c0e01af292aab7d3c270c469a33350204241da23f3bb3621036fc0e742beff54e7fe8e45da8a80b2871f6c06694f701877f12f1a3d9f2bf46a215450b39da042c3228836507e4e145bcda9768178ef044a2bf200ea790c160a6ec929e2675668f04646190247fcf87f263688fc34648be3ffe85b38b43fe93be797979c1008d4f36f4ff723c4f7d6ea8d9415c83025ca1518e5ae365385c3168f60acdd6e6f77b4a7769e89da8592f7dbc9909df37c5d7b818a4b2b583c1554fa402160e998df60af2f05ee6484b35199e5b477cba614794401942c8d48a53ddc46ca11e691824dca511eb87b1250e2e310ddf1835b40fb35d72cb8ed6a0664048cd12c78f98ab195f4861c167099db77adde681ffa121a4cd26af6ecf4e7bdf22da0250de49a9f53177b226bade8b55b256a399c44d8d52db99271695ef79a89442e7419dc34fb7f51c27b635fa428bf05bc2a3e2af21784e105d5bef178c54937972e6269f6abe66f0b1060bd94b4bc962c3936d7c4deee621a71d53e634f1b556a436e55a7a3e3ac47515f0a1e207b001eebac02e3cf2556de8ae14f9a52f50a8910e58eed2e94772b30462ec353c4263c47fa66cb4222e130ce24314bf2354e5064eaa9db983b6f9cd5adcfac729aeac0290ecae6eb3233d5ada0ba62f7943d8838afdb5467494324863d890383d36a23f0b2ed3aecce4021f51d00bc172a2be0bcea4dd5c596235246dcb3a344db5f6b988c72ed0a06dd445bf9e4c1ab2deb21f68989a105e9449a29cc6839ebd9a597a2ea2ebe101452b574880bc4362fe7bd0521b46296ccdb3941b9329727f532f8c8041fea33b2119efe68cc9e852f1b8a7ed0b6d42b30151f2aa80676b3e33a1b5db05a907a35fbfd746747e30ffec693b3e6db5a42be4bf9a93c1cd064727073878b65e587fd2d7f0b2bd74d461068dd95e9ea52fa539037415817dda4788d0e7bc871e208110d1b0e130dd9aab5adb38dbc09cb01b7db4853b80e05867aca5d1caa450e486d0d80f98f28c3ad3f2fda43df06f87e69d66ae7cf1a987290a78589288c70fcb3dd3c8c0273be587bd5dfdb8286ceaa0a7794ddb975c9d48211ada8d34c73c2caaf400b73c2f16411c50bd1706a48ad51a2d9a4aad22831708597a8878f5775d1695651800c853ff8d2d5f553bdb47d341cd09439d17f22b61956a49fdc44ad3affa823b852b2a803a16a53d4638d0499011c6959fa7a72e68c02fb20ef8c4174aa5536fb56bee2f0c84ef0ea15c73d6ba672dd8ef8b9526acc93aa9b0e94abd05594e66f82cde03f8142fc6bb69843454b02214b32125c11115b9e16efaaa6cf9d7043a93c9502e60ae2c28dd8d7c6a4abcb4af84ff4f1edc6ca74a2b7545a26b17c551805fcc42ddebf6627a57d53c5cdccfda792ebd2bda180398aaa2846cbdee92e464ca3ea94e4989bf71cf28308d342ac102bafc9653495c0a0dab0456cab78ce3faffaad7b4e64eb9f8d8104a803e919085abe3ecd16c42a2e2edb4454030b590941b5eed62bd04556d41b790bd7d7553f4eb7f4262570e61fe25b46ff65834dd750ad9421f2ddf1bf8438bc0f1769f27eb1c44bf95d6f8fb70bc52cd987e2d15e4cc5eb5ac579405608b0eed625f1931029b3d2f1dfea82ea7faea268d1d0494ed1f3d21e778287150336cf68b5b109ca3a4d731faf13f29bf60e39302c59e8b845ef0aa3fe22547e0b83d87de8af6bc82382e4cc638a9f2322eee95658e325ff6e847b73d28c0b608083e8111f819c02a110c3869479639535f234d9d80f4bdb4ecd39f635b25b1913d452dda69afbb3386410dc5cb651f61c242ba5553454f53657d4c41ced9b7fc2f8d932247547cac277a159a391bb67bee225ad319f23150216b1d531e572b8580152a5cc2daa544cde748a8157d218a8e8a3704e36be278929d43f506559b65aeb9f443e8c743c2a78e7633126963edff7734178dc158a702fc324ebaaeacb3782833069207e9d130421ad88a30617dee0fc0594b006897842af0c2c55ac7303be727a2520a4b1d775cbd62fb6095d35e271e0288d7c9d7cb4913e85230ac96a65c5bb0b651e790f448ebff6bad31ca09c6e386aca37123b1656cea128b44f572fca9e7ad4440545dc462b9b17e6fc2566fdad83012fe3013eb1cb5ef87913cd8ca0df1c9d6044b696fe77a04b5ed960af8eab0e8059d10b5df9d7cd15ec2bcfc5b91b824ad219f0ca961fb0d4ce4f6cedf545ed4a4fc148f6b9ef05432670fc18d355927ce51bf1497a3308e261b1555a0a054b2cfdf0b3ab1c85cfaedbb8485e43103f47562de7e778f11fd02ac78c37627073e35d2b431a1ea80e84c790943a7f7025481cc876ef25120396716c921cd2493bec91ad68a318725ea157179a3b012702d7578d185c08cd5762062672ff29c14991c4e136e336f05e7926fd02cc26d40af9732839d557955f097b8e1853b3fbe2555a9887e73d50e79c2cf16b18df9f41b8681aa1adcd426c61d4a4e5e0be909675dc523b99f28d5c5fd7ea54261c024ff5f30a0db2e982072a783a0061414d0a4d2a812294b8b2dd979c25b8f6f553df7bd132e6e58cbd04699c865a6220762493b615182e09bd046e0aa70f695903c3660360658f913b5c6131bdfe2a7a9b4fdc445acaa6e147c6a78cc97bf6451ea4bed00d7fd1456c63f96fc2259b4ce774ab9b31395aef5be9413baa9c7d79ef8ee3a5e5c198b7beb3463719938938738da582e6b74fbe5018ad5a7839bf8f332251073ce3885ff5b51d7a3dbb73b9460adc4aed42092f5c7a368fed6b0e417fb6b2bff3b7194d40edfb7cc098a9aef7d1b6c04c349a01e44264e5b7cc6e0fe8f0eb842bc7b02a5b196cb630f3669195374a3dda2dd8c2c11d2d1d00a8d75210ec7dbfd70356fab1c33b42fb87568399272831cb064ed53b9ada4039706ac94ea7c94a9f5b9c28da9a45ed959255897413a3137b00dcc6e16ece16e94309a48ee25860ec01b2f4f38973e4a15c7b8cad1cdc576ea2f32e402e928731193bdcee776f215881abc7d247ba43940f948ec8679df0ae1cdc71cab814f0b0247a6a87351910c82bab42968a800c110453c90e1d0d1bd881b04ce087939868fae0e8010d179e8f9209f3975b35bf99d53a49ad20b27bed55d26f58e1fc6c7212f47cb688f2d398cfcb0c771dbe69161aee513a95b03ea3ad9e4049d81295b248e96ec2e9cc3e17b0cfc2094c69728f9d6d5a8dda3f2a497adb81192062d837c77d9636622738d6b5096a9eb5081769eb87ff9302d53edc1246759c94c7ada5d6edd14e48e3fbadfa2a5830074fa7e3edf64b4f6833457f07e55459adf90594694168b0aef4ebe68d470f9fab8d599e4e1869306cee4839a99ef389d967df95cd46072ce50b23deee7dcdce64416fecde97b4acb2a6dc1b64db83c3c700287660f04c4aef49747d8f9233e230044ace0f668a22248aa3e0ab9a2a50f878565afcf4f4c1e73ae96f8ec0e2462d71081a5c5fc946d46de40e03e30e1414fda882a16c63f22c0a9fbb83e8ca7f46c5d116fc97ae77298fedc1e56be0eedc8ceb701700a6cf09136c31a3a6c691bbfd77330e0889151ca15fbb60cd3ef422e22213af963d83887db1a09258caae5ec21945219557581ff5d499235a394dabad138ddbb46fc6612cc305930d13a3e319335e30d95601a4a73b424f3016da6634fbeca06ec11a930891f4a1a8eff24eaf9ad2fac395d2d1ca5bbcc8fdf3ba7607287351e7179701106cce9347cc373410bc16cea04899012322f06d680033be2c901357ed0b25ce460fb1426cf1200286420a14473eb824462d70c91fadb1db440abdc16379c61e75f0a78590273a09bb46fd3e725f6ee805c164027eea01ba7265cb1a5970ee30314c8f2cbd3201fb4d7d6b7c5732e988444d037988a3aaf01cea015a1ea51c57b0ce9753bd9a4b372179b1cc1456ff141bffe31bc55ebd5f9df0a461bc357124acc7fa0355033d359af0189c66b34a4652016d2becdc721d497c43bbf9b6825386542b4923b90c52cc349d3ddd6fb4d39464ae5cf5b77e5f7ead9312c4ac58d25ec99494fbaa3b35128e7a4d91979b94b186dc8b47ab9a5f5064562c96f2db6fa33e499f987ab62e6b1319a72f121c44af641135ea54de41f73824994c37bd3cf8f9039cf144c13361bd734b8f07fa98a42fbae48ff6fb585d915202e0f5b6f2476c992f3ae997a0636d0f6d6d8b60c42c448c14e20bc9b4522a40f14767d975959f05ed66db397ae2224841d4ed6e3f9c432e92f1bdf19c6f39441b4aee1fef44c9898a1e834c1645265118021ae0782090940261b2c4d7d689caf51cdd54fa70e28b081c7982c8a80036675a3313a3911183ab106d2b9230be427c8f0acd2138c1626e660f0a46560c198ab055fef51eca1a62da327afab6b21ad9d1db327630a89b5a68757799b4cb712d373956e1d01b0a79b57937fbea44110e487203d081f25852143f61d58d90e3e0bba81537699686661cb28cdbc2bfed35070e1db25a0a5b81af33e81caa46f770c4ea0a101cef2d22fefb162426f4fb4279f7ebca15d0db5cfccd0d6b841e9f461dfc8e99f4b67a2c92116ef5503e05e1bffe773124eabd32a1badce280d514fa8a2606156070ee92fee6caec328ac514a492716427d26763df4ea41c3534f46495f4a7837c50ad5088cd0f8686a11e59c392243f38995c865597cdccb6ad454dfecbecd1949adadfcb6b4913cc16edfa653bfb5212cc861be0bfaf0dbf49374bdf3b445ef5144855d15d732c54344e8c82e7adbc0b3986aa48719865c1d5fc6c8af79772d2fe292d929be118af51212c65d7fd8051ad12b4e5d12023451df535d794ea016a7636427f4504a56ac08003c5ed641f58656d0b119ffd690a1dedbb839584714fdd5fea75c67b42470821b08e9daaa0d63bdef41abb17a9dd850e0a5a0a355a91381350bbd15f2924f96eb5e3338caf3383d0845db6e55936643879dd10901338491685e6f1d16d6ed6b54a7c850d3ef748e49cc54e6f980f53481b4076c92118488458ebc1d4756524402493bc08676365fab25084651a70a871aece1deee1e1779ff68783e47cb2b07419ce3b57ec48d1d7e55326e29375b3ccc4016a5f80a5d11073308673cdc09ec9d1afdc61b94a32a3baf907558f6d230f1028e50af1f3fd7c412e33b10c102b5968fe4411da271d9056082552aa09063c33ba1abf79c49af828763b8b9b5990696ad21739e2b48e157a7ba03ff29db65a4b5734bf0c78ead8a8572e52bf1daa4e31dd213944eeaf6780635275ada823687a2799988e8c74605ced1082c2619f2242d5f0cc50e85266757c6f641d9f228a8eae920220b3afc2337a5891ddb2ca5b38030a8bbc385145abf17f5a7ef06e24d9b9a0d43d24d87b2d0fcda505e85e8e196b8716d0fcc3fe5c5aed6d0d3ba45fa5c9c9b2ba9ceec9d3ae424e08c1fbbe638bc52b58d30cdfc6c5f513afd0bb3ea8ecd6c7c823146331a651e9a0007f59de3ccfdb9f3de8c01f26943a4df14fc60c55e3c4df0939050093b8576e3bafc7ef4038e9dad176bdfb4ca454517bde753168a82846fed048313e49e981ee8e2b4d409f7137805727106b7723882278f87e03d0adeb3e05843052d710472b7342f666acc4218fcae1236eb0d926fe727e61f6c4cda6b781f72f0d5ecc7b32d293925cb81d15ac3c9de2f160560c8c3ac8ad0efe78c59776686aed2fa4b06fbf482e22090116a86768f049c8d833146ac9f76e516ded53eb9f5bfe434e9cd3d85e7af93bd62e42fd60f2c4c997c6ed8ce0adbe8494faeb262cd2a89fb0b757874ddc0e05178c2057d804f06b6b2a2150f35a24e3949930ab9330984f3c59afc25645d8f96f3f70e84e2b58d615d09ee7a1ae7229042c6323a252e4638dca3266e62d8d24d1c97aac6eb0e4181424090189ec7d03934e16e4222daa2b12dbc339872f9ee7021ef07202388bee55aad81b6d14476c7d3a614848d9296cf29c887f749926a28b4b2afd6b5c60be24021a49b4bc746223f42098043965b6394260f0a4e8db9df69536c3be8e0ceeba5f22820fbd648d96954e93449ad8a3faf65c2abb40cb1090c4cdac35dd8998346413f4e2d3bb867042e2ea315299104104d529572a9ecd7c2de8f43e9408652db49392b6cebbe1366573d8580654d2015dc3f829ffb568fee307a18e9dfae14caaa008ea29233a9466a8dd6754607e0de2f47bbc75a34a7ec9dcb51b3dc9c3d21661e471ee21d3061e0ad14301a4b5969ae2974c94489a87482b422907243e4cfcf8a3f1ddf5fc62a78d36225f2ec990bbfff136daf18442022a9139253d83411eafaa0f31d9af32ccb3096056d5ad1b5a50080eaba95574e95c99f3cc73cb40d2af35a2e31a8427faf0d3cb2088ccc52db93f497ea350f61e3d8245535de3b7a255373b9c516f3feccc0c18199e6d4558c5504b8ef90f90b7c817d2a6fc2314eeeada8439fc6337a4823e784ee71eee699612470a6c8998abd518e1d76c5f594ccd01cd112c49bfb3b30a85d5fdacb17540888ffa3d97659533e3b075e5f80deef2cf8764512a6a25aad69a214d15f36ea554bc3ee9d0250a2df99078f74680ca33ab9e593a56a7b8a8dd2b437d79f83211bdfbacb2f58b19a53c815c2eb2e835f6764e16c86aafa9724be067b3f73a3b8545bd3f58504fd81623e75479f6ec037aa97a492d6c38237410f76e5e55868996699d364b9a0f99fb3739964b0557520338884c45bff48dc8fc4e3dd0491660da82dfb65766fc1bd95e8d9052ae8bb0c1643ad62f3f44b9abfe0f876fd46a1f2dab134d9c985fb7dd2042f171e69a6f59d903899e8901d7fc451b32008950bb44bd3d133309a493a1193edf1c1df6704418cdf8dda5d3087a3b5c1f8edca57596f60ea85e6bc5fd310d43f930a72e0685abae8cc32cdc5db0a189746821820e053c0785b83b55250fd7171a7166bb5df487b031b2d875986132746a7a942c648d01e8f3b1406d1abc4de9fd23ca4504d19e9ee39f707fdac57eec10aa89b11dc21b173883ce04ff3eb7e54eb7cb17ab86d0d46495591b20cb940c1cb4f501631403ed6f8d7e7255ee3ab87c047ed0e2831c36f6ef992c8574edd010d6b55651019b1751b61512c92a1f391abd93cbb4a93376f5a121f4f7143f117ef538705b3d275ca15d2ffa803baa6091e446fce5803228aae4f7f96af5c43d2d507401bdec10ec53c6221ef959083d9878128f4200679095e2333bd981b0c68bcd1f3c2ee78dd4655a4cd297d6ae745b7f3257ddaaa59c5da50db54930d7cd673779f97606e57e04b85abfd16bbf92feb599d62a556db016dc4c1e9a78992c266ed2ad6cfc3828522cf3add947e303550b7f59bfc3d3ba56cda03e6a8db1a66320c31fdf1c9dbfa08e3ba1e358014fd142a2ba2bb3ca85daf21ddc04da91dd4cc64ce9be5b7807b5e7103f3416fc7a64991910af3902131c035c62462ed55825f79442a33cfaa9e00acc7cc5f22b38510a6e2afa25439aba112b140db31a2d657dd37593726c4026b48ec4cc8cab1aeb9dcb387048dc79f70ef314c8f00a865173e7c6c61e121596d6b9d374dd54c3d74e7cadd5cb03ad7150469bdecaf6a1e5f3c017d10f3adc03b7679de5dde586af7293f050ce23d8bddc30802550f62168cbdd883a5833192e8f14eefd65327e45b679e50e182360ee499635d13df5af799ba14311dce7a6fb1bb6bf1187ff3f985aba4c811bcb0140d1784f78c1419a240215be8a62c7deb605fcde4132d0f7a5ed403692e889cbff47a4c50a07c37d26528ef71dc467acec9be06b2e7524aaf98964e59c8c9b55b2c562d412dfcf7c32c3b8d14781a807ff87dc05a3e0a10897ec8cef415fa2c32624a0ad3582d5b649a04ffa4aab2b18d9a44d69a444d37498a802d6037e515cf6e55404859699583d27f532ad43d4b6a41220ea71cdee50a94b839a8fec96b0b0d906c4729bb62d19be3ce5dd19b9b00e6c3cd774757d5de4e36668389a9f681247224033ee62de005a930e85489e56a583d55365e1dcd5242d1d5b37ea4b49e6e6fc656529b7050914889123a8d963f071a5f9c5e3e52e50a8772743da197f89bd3cfa00e178576a96e1b2b2f54f9b0be9141bb449e94682017eb865a6fac708cee1cd99f3610a0274b7c867460d23e9d512211d3c16d966b7286c1be74ca52a2a61cdc4a90a8b39bbacd6d6edc993ec2f4aecad075ceb018760772a3e280107708673812b59f1335463aad2f9517bca8c8e185892d2eb7ef3a49ca15ed3016968755a10450c1460ec54b5e3409336b30b949ab6d69099a6ba700b95a00b756a37798706701a3a2c2eccc685e7196a837b8c69d6d1e0edcd371b3f124daa2140eddf1bd93d74e43dd87db3b2ac8fe980bc9f1aea73dd8428360e1262014e12a7bc54f6b3bb69757f4bb1be9ae6c02d2d24266c8e344e3ec819cdc8600ad566f0c9c9f6b1b1d81d5a49fc1843ed6c4d3980a5df76b496b3cb8c884bf16c3837b58d1594024e4c28205be4f11bbc5a9d3d53859bed43af39c779fb1079b128e037e570b4333151ab2d977d2e8b7a99aa7e8ec96914efd135819193d01e27d2c509440cc5a90922aa8607def3201b9390b0d18f9af103de76f1db00839deaa0870ddabb34cf27497519bd283d08ab4565bbaafe8f8efd4585b5887cbcc108cdc3d6258c6480e596eb15f1605e3d5f3be9154f26299133157bb5632570b989df908c3acac48231797b3f8c0afc8e50b1c3c7bb1cc9540b4fab1744b839414f711da269411c9880ce36a0176695dfa39ecb477ec75762f61a6ab1126cd63a35f6f979b07eeaf01184fa6bedff1c182c7d282e23a86f510f9ec6e6d94b6bb46002da0ea9135bf74ad7e1d6d33489f75757530ec706d491c21d3abaf59c0e5128d1d5748e2dd28d30b11a44ade5fcc677fd2c3fa241c975f9ff65801e8e197addc14b10926067f28740914cb15e6b2a8edd83ce7ddc85446e89f7c34deb51b70803c5b1f4ed5c15a8f947198211e07bc27f4a584b1fda358ef6261359ce53dd0d8bd600e47b46581791318cc86e5afa1a7087b98472f75bf991d27b8cf95a73977833159602142b9bd809232df5fa30d5fde85a136447b08f4f3f9d03a859836a38dd9573efcfb78ca5e8283e81d0b96137e21b2801c0015f0bb4e7f4246b95969dd226a8b5f576f3acfd6f6c5bfd2482510ce70be7f280a4bfab7be64b77ed8b3d213d6a922f7095504d1ab63f5fb4d2d1f6da548276f73f0b3ad51c6302b534325ea2692b200afa7aad759d8d11cab4e5897d6f0e18a963de809fb2d4b7708aa2f2fea60f9ecbdd3ae2444ae9aad064b7003526148e56c57ee521a784d1122a0b9b2ce523d03015cf0163337d9437e4352289a006130f362aafa9fac819d66df6fcb394b4fe12f445cec2be8137ab539d012e6c92609e996225f3d5438bbfe224aee3d586cbd9d27f596e504e35f6ed0cc4d16f7bf45d5268cbede02793e5a08a9797a3796bfa8b6e6187a33f29c79287749542d02bf56581334893b8069a1f6c591ab53f370765d5a520a6e69c511870922746bfd76e89329e94977d0e65b7eaf4885771095d3b343c8c39c46465e5260a88a6dc180941c22960fe2ccf065d5061faf1bcea856a533e6baa3ff552c7389c284bbd364673ebea32a24b83356a19662e65323b0b77bf3055a4bee916362e38e651b85d496e0290505ca7fe1ea0b80374df6adb1e342d122560f3f8ced915d685a773de0dcf164412cc8b5a469eea4e48595b558fe5738b8e1f3cd43cb8ddc7507539dc45063cf6f41fb57faa849466c0a8f1283a68cd1201dba7d75a03ae6f5376e12271b85228e84add5b1e383485bdb26dab42432df9521644d05adab6216fac66f82c060afa5f2841267fff748fc9fcc62c8cca16f93847caed5efcd20de09e1ecdc7e47c2450448c1b70c8a75472ab3427d2825ca9c81b810d1ba3ab01952ad729523876f1a66ff0bc3c788a31b1b80dfec7ee287438ef8b3d747d01190ade31ccdfacf7cb1d378de29009dce9dcb930370e04c0ad82537d51c809cc1090078a0bc63577d67d751c56834f93fd13ec7d80634b604a3f66ef904373d055edcba79fc5829dd45e566aa09de2b0872de85edb08dce2c8f819cc95031d505eb06fd686533feb948b1029bba9809f2fee4a07183a34ec2b31b31f0d9075d2e1b9db397d8b0bce25a8958c0a0b498295452be12da6874ec04ffd7d2ac482fabae1fda928263c9cc927c25bea97c2270776be98213e94eddd4156a4106cf12774e50fb3009fcdc7d6dda48576b702054975bb361f0ffc874f888a74bead585cc903ba78f05cb8689ff13de121d607d5fa206ddce95543cce11198256eb2d24d50e4a1a08da012f87b1eecc936d8f0fa9c34c674913f42b5a01935f9075008c2881361c8880bc03f30fe7497c2fad9ae228816c27f8ce6c66346e4407317c1a8dfd4e7fcf0ecc8ed96192a054c094ec4dc3ce3b7975afa2e24ed08967f92439868d810ef734eeb20046b2a435b66f896f83f21f8c82ed1e86f41bfaa017b6d25b97bc5430a24a49947ecd2ec0148fa5f70eac791cb42cddf4f14e4d57cac68b0d94630bcd63ce211ca5cfde486ef6bdefbecb24a4cc40f3a5774e061d74c4f806f8879c4564a8567f301994a99e2c6a7b9684fc84916b82255a2b124263acd166d8633099f568bae8ac75829e48a7936ea5e90376dabab4ecb7dea68e0c8491c469da877209dc3655ac63f543d5b202f339dde79f745923d8890c468a67c174e67c1e838c86b02ab31d0df69c7b4be77c006c14337d98838c44ab698bfe07d006912e3eeb765d24e06518c442bfed8c6a473135cd60444b53a07af85a509286c294c3477f67e9eeb461cceb1ecc6c2541a510db47ea5d347a900e6ead6c7781adf6ce569bd5ff33d2fed22cbc52126026dcca7f32827fe2d3c0762f81db13e2389b26b47019227d9c5da4d6b53a99dffc651ded42b37c812782c215177388c031f33aaf7f989134665ffeb386571bb564b312003a8802ce44710ba1ee65c48193a990791741e686113ba38241f212ff415a1f6acc7b162840a088fc47008133273678292c704e2dfbc507e277d03915ba09f7c0b17709a6881cc25a5f84d20e1f7a9acc4910ece3269029208f3329dd60d4b7b63f64b92087f5bf5d802653334bc2af126a45ab8d621b8c86e8b464d283038de9326ed44831ba41c695da444195dff5abb898646816d6a25bfaf65205adac9dd12461bf44a0e1680be75e754675d4bef49c9f0d318808b76fb295c20fd6e3d7c12fccb2e8fb0d267a85706e663f9ec988f4ea462c70d0d30f0709419e182197678b8ea82d6700724be9ec6a1a8f955e6b1fafd53a3f77b7cb3cf469777dc5b17891d4aa6c8ab55807c1f5e70c820c4be8aef7c3729a8aa131285cac075cfc802c106db8b1400553150f6323fc9a9d67102089ef3928aca6972251517665828d21079ddaee7d70c9590ba41243556233e6858f89b51e7b4179536b4b7f440b53282719eb7bace5425ddc1f47155b348ca1b78fa91096ba2d678b8e1dfe7550b7c13e777087495cea37e6e9ff2615c04c0824c111b581edebebd6169d6d95d823475670c71960272d91cdcc316ff65f89b8a2918050c5edcac58f0bd33a91942c80ee61910abab92f611484d2e011c6cf076732aff7152273cd47ef803ff38905cadd13697b81525f892ae490ce02f3aaf1875c54fb33ad48b3ca415be1749ad92dc7527b1d10df502eb1d4fd5873819553b1fa92b3a158400e844642efa2a6d8eb6e2f988083a66404380384111ded00a395c90ce8642cb0b1e3e91bca2b49fff30ec5bc24453b8527ecda7cccc9e0c15f8baf4029bb9656ec3b5d6a663d998fcd479b17b1e0233ad22aa441aee3979459fab24599eb8e061817d06f844c3e3f1257c84d4ea53b2fa46c8a994c73652f95a77bddb1ca56de1893020aa36b6acd81b03fde7d975247519d3ed1dd90d77f4ce8e0a6da1e299c4f3458bb27c1dd8ea4e325c880d41efdea30fe4d09671a111c19eae57d4dbfb4004d95a8a6cae73961d6255b6270d37d0176f1fa695a3916270b695a7d7efcc2eede21a2c75925c664cb3bbf5eb1059526bd1b136a1f17cddf35bfc77e1351434e04a94604d7f7c6d1456457cdd146e83d5f93260ba48d2d0014d684e0ec8898846866bc904dc2e76610f45b2abc43108e1cb96819c3201fe4e66d58fd871c80f54c0b73645865acb2a267d6a689a525cb5a7fd7c1ffe1e20af0f8fdb80a29f9999e14e13d3240bb8085918e657adb7770385e6041720af7380a9b88364b7633e680543693d93d0561c7805bd6945636aac1da5a558fb894fdafeeebf13333fb7d7fafbe3b44c95f68ef47d69f30b0bc66b9807c04101ab6aa52af01a35d3cf8159bd34033a1a718d20be141f2af501109e4e22fcb717774380d004d30764fd5970399e672de73752710b2850e3176432d6a1b32071d5191d473f02f9f87ce9d9118c6226d796fac1c7446eba1ae61bef9d649b820acf4a081391c00f3535dc93ab6074bfb374b0243b63b3ec0f2d1beb9517d83ffc8742f91d157b49e730b982f6c340b02a8971cf1c1b54ee5cf9050796b952b042f3ca1659956d94cbed2837d842e31c4d9c42563dbdf3d4555e0b05e4d556ce9e12cee00906b274ec0de1dcafa163ac8f1ef3006694cb876c2303b3f6e982c12a6805a64caeb5fe4834931c0244c4d7a6c127e91f1ae3cca8873dd64443ac6e79ecc21fe78d40a25c5343481175124c6604eb93416fdb9802d655e9f28e020a349dd31bb7d132863f708227c126a27e02fecf15d493c6ce204236cb23892b7beecd7f6299a98b28d596513e5e9eaf743801e582df54cfb3bfd918b101e1c93b99d94396732fe0892dfa6a251690f5b979d82b6eb4d2fc3c476e9b950f2c68189cd639528eacf28bbd820f26d924dd1afcb50a3043141767131f4b3030f239cc3add427f499be15db19abcdff3b0fd3c0dbe6b787e1d65f7aa72d49b11093e812f3dfb366f033c4bc3356878bde3bca87d66af2028da8badba5b580e6ccf5066f49593fc78b7c32fde7920fbe40ddec13ebd11b2613e41c9c4f9b27509599621c71180b8ed22dbce2de52222094a601c37bdfc674c452c8d85b8129b0a75b9bc6be980f92cda6124538c5b4f4b1017e1cac5113fbf23abe8441ecc35cac6ac67024fb6836d7f891d35501c0ddaff7925252d6f1960a84765416c420ed596015b46c1ac7a488598750413567e8282d3ddbbf6931c40b4a482faaf451d46a732035e69f9c285c8727860c7aad6771fba17ab994cbd925dc41ab7783e33dec1b0085c1d04bdab4384f2765a6af41f31f536abff2127be90b8a4cdd609ead26b0cd4fd5b54697ab81e9669691f60d1cb60e84de07801d4788b8fe29937c954c92d8f6aec8e6c1ab5f46284d12f76094d77c179948c1d39dae08563ba9bbc068a2be0a5d99e0bd35d0a2ec1a9fa386a5df670ba0a95e4ed4816b6b369677e318e6867f317bf90376d121f495e0ac946cd8fd4061d2715ae08c4388aa140c7451d1ea7dd2442c71627fcf4feb9e61bf43a57114fc9d2cbdc685eb4ed646d696a926f1e2831bb68318cdf142ebc43455f381fbd4e139031ec915072227232920bccec62d23ee55329a720fdad3adb98b0a272d8d51b88ab6e13306982d343a60525fd920cc9d4ed36870e082394e69eb13ea0bbf83e7336d6165850c573eeb4768c655c44d3dd6699384c59203b47c8634e2a5ef12282635591177db1552b268e60344f07d5462f1a865e88c06179fc0eba54af254af6bf4fbc63eb394d4bf53a08603895a650a04b5f389f247c83a9a78979eeae4950334bc3fdc30f2b718ac4a915ea65e63ca3b994926a563c102b39fa45fdd9d5febac3639981ef4be56547e42e0d9e1dad92a692a0c3ad986b93a34b7092e36fa9025a74412965a700775bf3e6b68655ae41a2bb556d4bff581b8bf05fb7033ba38f76147f7033bd055a3f69c9a2beb0666681e929ade17abeabfc5f0ad66eeb6b05754e367a3d213506ffe735aee61074fba58884193901e772339667501a3f1a9b576229f852985924c3558920bfff1f19cc29f3238ac766a21e86ef3c1c2fac454ff191b3264a6e47736054199f1d29d91b49f38cb310450424a6e85bf11378d49c40e5315a5f18c0fe7753a1036b8eeac835647460f9187694bf150a47aa077c0024215e98932079ed2ed08e88d80e5356cf09e398935b26ab4739268f28c3dfa792acc2bac2f4576a63df50dc16eab4e0eeb9ce2ce4138956fed830816c3397213bb60563ea5e6f6459d040cc320bc12044df07e71eee89ba04b3be4552c01c51b2f9a6d07517f460df3ec02fe55e34a3e4f5e5fd20b2340fa080bded0d2d49d7b4585a9b074af50d2f4bf6342d0ff30c4a3770a1abdbf97d13b3d3bb7846715b872840b1d67e61dabd93ee07974b092ea6cf2f559f99f79887edecc68d841fcbade383dcc4146985bc0b3a493bb4e8133cdb91a8e46ffdd8ce183a3184dd857031cb0f305525ea0b1f81bcecc0ee150b0cecca6aaece1adf50d297d405dd46aa4026e77d5019807c359cb518ddf43d5f10c25eaaecc7e1df5b149ed35c92130728f56a8280d329945bc5801068c055cb44cb459591dac3324c78ceb0dbd3bc9f27f567687f65b2a8f8d72125d310f27d0c9d532093e1dbd6070866128a16b9e10783f37b8282ff5572a465af45e970edc674007423804ee0dc2f956fc86ae2e25378a0fa673b83f15b6fbdc5cbdbf6efd6a94221a9b244e1c83a8812926efe42822f2ed1cab5a9172371a063012b8254ca3769b9c5169471da8c7bab36304473abe277de1a7ae9384296fd22e8dba78569f1c192cf045ded04337fba09bca232890216ac7e289c7303981d13be445a489a1402fe3ed39e9f842cc48a15fa3a9d86eabfa86e202e1fd9b4a32275228da755cc88fbb32e5a6adc423126e6383f768aed5aca066f7753b7f9690500861953fcd1e151cf7d5adddbaa0cdb22f83ef9dc9bca2a785e4ad307197019483070a0588d4282f23f341ad67fe53b21fc1ab76434c64cefb8b3b79f972d05fffc572e4c4d07fe4bb3f496b86746e13e1da214afdc289bfb639b725cb5ad6bc58d8cb18ca45564b0c5924b75885b89193eada910ed1ce7ec968bda545dfc4aff86f0144c6180fb82b9b30f1d040606d4d9cf78544c151d042eed8b5e1046fa0a32e774fbf10a865b307bcb3b71d1f50dc4b65a5e38bf40009169d509ed7e332d336693cf9772cf307ca36bbee7a50c9a46df99dc40be9c2d7849afd54523a115ac65e7b72b7e3f6aa1dffce7be217a4293a63a9c335de41a1b3503e5f583edb8a2ef334a96547bd8971a8ee45c7dbc7981b4efa545a0982106e1fcf8e70fffadc012cf646b36832bd6657e782ec269a320e44c328215e63de410510635c5f719e2efa0872c5c7132b05b02254056f74c2da21ff12d5650b46a0435e97ff706656b62e769c7316e0146c4a418bd191212ba536e8835c5fda727e37c52120433f65b8871b55d3961ac94b09631f6cdaf95bfb7fcefa285532021eb0a66bb91d68193a7902964a7808dc7f4b13674893533d055f712df9d8fe218ab870b5475db12b1526457f1d64b8d935a8647103a90a928e92a627cd9c028783abc8c7012de9b3f92984b3acaaa97d8f62b9fb9d3214bbd5d7cd1191d07881be1324d30471a1da383255c14b6bacf00f31ff6e77ad76e3247990d571771036945fb070790e7fd5899ac4e4514d432e6d53f0e366d9c2f7f0ea7ac147f26d692bf18d3c80ba74fb79ee7b1155ef4a0e00fa5ec8f60093d1d6293d7944bf2570cbb3494b16786399e3b74636cd9aa193540e160dfa3ab9b3e0209b2d8ce47e2f257a1c17e4fabd7a544195441e29cda83e74515d6dd958a14921c03c0b0b5de732f296f9b2fcd0bda7ae185e00948b1d5b22210dca36f1e943dfbbe414fac4b7acb8edfdeb842ac66b3e7b5b43163104776ed76845cbc867294ee373cb742265c395515640adfcc47150646e4505d638a753bd600b6eb65a390c464fe2f31ba51334602ea245c88a7dce4d242850693fb7faeea8846040a9adf744453323c4733dfa83c4ac1f1efa8c6b7fcb266b7bcb9d60223f7c32a78f502c68de40f7844a9b75b014e95a5e1813d21146758e3d79b34156d0064609d392fa64c3f1203f515386f12d76c5fe38199a1c5a962be50c55eee12480df4224170dab4d1465afe7db6ed5b624844797cf08528ee0dcf5230e1295c8034ade00c9c15000fca3b9305eebfe1783c8389de183bf3acab2b6d7a446d3455b7f23b742c8f17de2433f4f84df865f78a1aed54a9b7342cc209d6c32207f6bc068697b6afc42ee66f700c285cc4fcab04a00dde4717c2632db38154085ff10919e7e302b963a72569199ab38dc9a22531da1d65baa1533c98aff21890b2168a8e337cd0b70035c6b5615d3ecaa245e2478a8a98cb4f301ecf1fbc8f015bb8a8a609fcd702da5a1876f90ab899ae6b047d2313335ce13928e6c08ffe2d65f61d7305774aacdf38455e611551f0653efca997a4a80a2d3b299e19b5811d90f063813a493fcfa3753195a7a8c3f74de9c8f0e9a057310d1baaf656a1cd240202bca5464bda37a14172898f5c7d1ad93d843cb657b20affeaacf9c404aadd7e73d00321ef13fd81a69b828292d6c915794e7b8d9d2cd3c203cc84d5485c78a7d465c3332af19038f245c8c78d780bfed5bf2b4fe54c67a7f50013b764b1a2aa0689a667eb13567d6360437af13aa68aa7f7400711dfd8d2a8893455241e8b52906abe05291add9fe88179f2987581a01ac2d6211f300a6ee7d825653cdcd0ec9fa168f5f9ddbf22fbbf8a17b1fd9a61257b26f5532b59dd03014019529f168fa4cb9caae54f403e6f87c7bd51561c8daa1ccffc0998dbf5f8f7efdf39e001d539e7e0f22ec0afa2134c5e49f2f0d68ec68405569f67e0f3327b4dfc71b00a2c4ff0ee1f7007d7854ad9b8ec9b40fc3215cddabe20093f2e5e282c3f375b93db4630d8cb756f704e09bc701a5b39f8469e6f8b074d32aa441b4bb7a1539d2b564d7d5f33026721ed608e87941f56490fc9d470a41464f6dc5bf172d0ffc5b5bf667c63392d90a55df1d452f55d487dbc3811e67ebb3e659c0e4e71cdb5d4c00c1cd4971f0e399ebad9846b39d17af997ced1e2ef51a7553b0ade82796fc5fc03684323da78f110fa3952e28eccc7110ce33fdcfd95364c574a96860858493d0d9bdaf486a327a3f9e14276e11d439534a100044e6c8a263c78359309d75825c35f312b05190e5de5fdb9de753d811d26bae286231a3e3b10f0e78edc037d139655f9735f7b2f49f8ff62a2895655d608bef8a031239644071cb813f4babb6e50f1cabd3c400243026498a9b93f6ced50cdebe543368e20d5159f188ed2327c226d447d8a9d0dbca04bcd90ddf6795d4429cd4b2a4516160452b5495babf5ed4305e26cad37dd52e97e27aaeae4591ce9583a9d7dea664e9809291d1e4b8dffb63933f6c9f3c0b5ad7368d5d389273651a22e0f9ffe6a6c9365240f4ef6d7f164a8595cb2dba4046e95057fa1ca81992b0694431cd8f526b9a3c711dbc7535741ab3b6033a836ed9f65df6fbf27710d585a6de61a054589d171277e98ff40aae428e2b5e5fe37e2b4a84eab01df9fb99a8a9b07dae2550147ed6e0260329e3677fad27a8215c199bed64b3c7dba2111e71325e3b7baff2305d5de47bc741753c59d170e50df92481bcc3ade962d3a18fb2042cb230793fd67c3efdbf11948f5ae9646c7323986b67039f347590929c8d8dfeb86c6d620a397eb52d175d3f065649a60c9d91db36b62b18b600d314007bc4fa8754132f1cda9bee665aca860a37fa59d713921d924aef3ed3601ee2f6fcf3b0c391199aca4b46f712e13ff408847060c2a99ae57e50d44ee5effe26d5ddc7183d4651476361614ba36951200fbef72202ed2e3dd600248cf445b6521194f5725b82ff953f6a6df45876a60021c452c8f33d24fba300c80de0b45acb0db5de4e05b58dca886cc1c4ce4f52b5f6e47d1d921c4d82ffd04624e09948c01ef5098dd56e5d58465c1f8eb4a90e7845d11ae152a9a83b25c885262cae02af789c7b13968715fd4d241885e3ce6dca542d60427c65bbec5f892e271f62d7220484f39173dfea9c850fe8a9f9d301992e1cebd1ad2ad88a6434350a2a5dc8b0a785fece3cb0e24cd502422afd58d4eda56f3ad6f80f868d85026a2553eb42e1afccc796ff66f17f79ede0d84b11eb3f1dedef5e02fd1126169d0ed7d935c5fcd6e14bf0bcaf29fcd240318bb90497cd25abc26acc7ce1637e483dbac2882e54c15d0ccfe043dbcb0146395d48a80de5c6e7d78f7da806e13c02539afbefe988141427a904be4decd2c5401cee07cfa7b5ef30e092a960a4afd8ea3eb023a1c3d04991defa6d2e0e95f261e4849f75546e715df7dd51f6988a624866a95e9be1624c9ea3fd64fb9bbcc3644a81682c00d0187994a52a8d01fb13e68901d5660582de489a0bca72ef6c902108ac8cbe59ad41ed0db391ccc732df5ea8697c1f557aabb03533c16506e151216e1f5bd221549ee565c8b487848f627cfbe3254da1bf363ac2709771e6da8dca610bc8f010d7722619e1efc5262df993d79d2c43eff92a94aaf26af78a9eacee9505d78755a42157d47e3f8fb91bf9b9b5c44e12c58422c2136a5a8e96c9e29e5b408823b8cf888e627c97f45f9ad42ec5e88ed0213b7c6de723441a8e25026f5cd1cdc6753de739764940e190d55547f6de49a9264c4f0d4cebf8aafc82f00f5e228ab09a2569ad29dadceabe7683d41a99de2e1fe324495412396da5c6fafe7d497ba08e7487bffedd097b8c994d0574b6dff391b1457838f0c51cf715764b906bc85f8489db10fe5954a185e3a01154609b004df8262818b70e00d643f583f54149545eebeba25db804670eb90eb720e0c6d936a82dffcb1b56f72783cb086cf2e39379247bd90d6901aa1c4331310e0249234ce1e281e95da9161ad89b0c06e8dd8b3014c515799f4af8af85b2260c4d8483c370e4baef645a68acdd09656806a6f5e87778e958e9d4bc70d60f08fb861d0a16fee104c1c8fe6f31a0a8b001e009284f2e95e710ab70abdc8e852c722493ebf0db8f816d55854f631a2e342e9c472db058ebf288b9ce452d058f6d5682faf26e11072530486f2e04f19f78c6d0b168d8530acdd61c595340e964675e4ed5a432eab0d37f3aa2cb5734880833a92e19b57fb5f575265513eb8f8b9a899ffb4fdac9b96b4e3ac663cb911da769485d5db72eea5bb5c7b7c19c739690682a686997f1b8844261e1f6e792601969a3b504a7a5290dfeefd41e4fdb2836406c64df27bfa3999164a7c32238a82382a4fb32635fb7e36e0d7ab9355ab9d8434e2463924dbbebced49595d7ec1e194ed961ade7d53d7b1614a7a0f085e1dccb056fbc9267d4c0741a66dd802dd97cec4375de9191d27edf1c851aa24a8824f74c7bedb4719e1196425b7e031c2603bec8c7b0bbf51d278fe30ef033800ffec31640e82e35be8db8fc90c5834c7388cd13e9a474cff3fdf9b91b4e5919f6004d986d76344ce3c1104836248d13c5bcd93395aa4ae2a2ec95110b79f80dcbd04c54adcdf4380c88406b4e2f721189db297925b1fb8bec8840502c567f251a372db440353347ae4b443fae491aea3fcda3e2617b0898340cc7c291b60cf2afba057d27f83a9a3507f6a0ddcaf799acddc818727f78c569cded669a0625835baab33c78da9188c48f43a32fba14360cc3838af7849b7d7a7c196a0e06916a4c5863145eea8c8dc28aaa3952f70ddce85799a09ff41e85fa447251215ae2b0cd95f77d1cecf45ee94a6fbde6929fcb61e229fe10ba5cd1f648821b071bd48057aeba1069f1cbb396a89d547e5293836ee02e1099d668ee40d2a2279ab17fe9e6452b6774a304a591e89bb61b945da0421ae57a184571e7075db5fbc11792234a7633a3be84e9a35bdf8732edb50c7682a6ac35c9d67e1b804541f04da89f985c400c1f240ba2453f690cffa4f5e3290a4736dbff5d4fae4c60ed5b8a393c5e95fcbafb2f5ce95e5126cf8a9efed5dfe563659036c969b6bb9b5fa12fda3a0d89ea87bf07c9505f9760036abdbe422cbc6df48cd2874345a76a65aceebfc6e066bb03bba218f82ccc0c6c03e4bc5508c67215f145029dd8a4ef2533f6f1a0a40dc92f3ea14e355b3d98494d92f593a2675939ec77ed768ca48b13c441fa139696b16ee06773881a48cd2ac7a0de3cbd95ac957ab770fd61bfcf0a2b9efd83d7755967fa4aecd7b37edc573b1344fcf8ab29e978a2058908c5a052c1948d5b5b3a8e3908f92133daa4e5a99ac26edd67c786c7712cb4dac9995e514d05a4fb45c2cea4add8c1d325270b2289bb4451549d8594558cd7e5b87643729cd36f13641bd46e1f651d5666d46be0967ebff2b0bbaf25f19d27c5643be26b284450a20d2a24088ae181962c31063fd563fbc431eacaabb54c0596264738835d44162d7ed04798f081448511b147acac835c306578f2c72469fe301450d31732c5ed1c5f917c259ccd56670d6be85ce180811eddbbbc7a7549d783984a293f767d5cdf64496e03602f09edb3ab471bc9bf2a5ef8f17a10d610d42397144c18d22d67943c13ca964f289c44ba093c3d5767e07910dedec8279a6b2cd0c2a9ff2605bbe35235bffe99c9da80e0d66788e07d06eb3d475c7a3c20bd171b9ec6e3f944923d816679bd61bdfa330f017028c00c92feff2b15ebcb95e887249f5846d21f832d8722cca96515dfe25bd428b48823e41c703c599cbce8273939fa78a88b3e1f375f323a64596b58152acff2c55c28e2ad4d50df0a65e4ad14baaaa1b8c4dab84d3905277bebbea04e492a6c71e56e68c23377ecc787ad7ac02ad28f6e88b14f163dd50119c90395a0c4772da3ac7cc17e8a8de9367d8380936f3986b582802953db3966cb3a4ad4cbe814a7afa746b2de73de6eec84879f40c1bf84e5042e271a4179e71f0b66cb11b5bcdaaf9eba7d7f56adc51a03a958de1e7a7b832979da202c07a6c61b8b6d6465eaf78ba026347b05d9a1129a7eecedd9a7e8bd1c3e48385c38eda6056ef775f807538fb4074435ab6f4b21805c265af1e7ba38f14a194e853d732876bf9d736532b5dffcb09b0f2c2dcbd05363dabe83888e2cc109c6dde8347d135097ed81795ab393c1f519d4ae479b1c211a993565cef93048ac3edcaea1d2275bb23dd9ee8ce0bb98049908339a666a1c841596d9aba92f17c4a25c969ac9642620d272a42dedc985edc5239fd1f2b6ff17443bee7b29a6fd667216454892b7a00e03d6554059ad92f69bca7d9971843ab1be5c6b61181b5a110eb9a593a53286c7e8e09b8b06788dbeba6ef3b33a19e04a2ec69857c56f7cc0d9be025735ad3e8f8f785572b35c2e0c4a06429e51ca67aa996423107c16b22be4f75a86f9966d27f6a2157bdf941d5d24a2c987c3062104de1482c130ac29898fdb1bd89abe2299b04633ed44c25fcb24b79f9cf2dcb3fcfb3809deeab74cbe7149fe9ca8690463c580306af760a625fac2ebcfe367e9ba2f99eed0210f06080a73cb203af4eb7029db2aceecf04a35467bf292fa9d55faec306b1916db527356e7ab0bf69c2db05a93ecaccd8f94d94261b98408caedce8930b5037d511969c8e0f1919576477d147d9a54bac539cb0a113c5af911f203ba0e6fe317fd61f2e412449ae0c208f338d27bdaaab074303a963003bb344bf159ebaf3d13989452a8324763189072dc639eab8514c3ae2173cf4aa556ea925ba4930184edc20306c651b796b1fe8501e000c3d11c674b46a703de50071de38884dfe70a88779461bc6b396b46a0e3ff0e3475b67e3a0162e04a38d8b2a33e12cae4c72193820e217f2af33a5e71083e6f2633bb2784917a1d24d16da524cbfb38c72d102678815e790c6507ab84fefda478f89dda34bd4149adc3a1e1142cba43c7e66b3bd4a8316b65787a82881da6c506264829e3fa2dcd00df9e01cadb4e845dafe813ed5df26e7a0444e2a68dd511b158b8401923e8e6dd4ede65d35aa2060deadfdbc785e6555f608439fb230cd7c4a0195ef7ba83280a51f8d27424cabd0a9d660afec2fdd0dbce134a5f39fb5cbbff006b60b99f3c8badd517b5596f819c332ef1f9e76a9756424e49cd03bf49c5b02668a4338dea2308a536c7c60472e01953728ab00c4487de4bec95b4bd88f7a635326cab08ae4fa9d1e26715c1f185451d3317c37552aee16e4f1d0fef499635ec3929f829606b7b586b9d487f9ea6865e8fa89dc6565ae04382f3ccb96d1376ab3d3c15c896d47f52fa7a089d8329e1e5816ce1292d820aa238abd7aa58705bf4a1352da0a7ecfa4f11634c820ab0a30377529d2d5c9127322a474f9d2f211377dfb9dead22e85797e4bab481c81495a20a3f7f640edff0510e1809dc7c7173dfd174f62e0fb01daef5e2da1287a52d62b424688f3a7e771028edbf9f2dd4300c3859c53bee561b2cc3b0a95b72a192d375ca53ce816b195b49c5b84323a2ba9466c49c0e1067e44d9f7558099554fc94d1cdd13f2b3fd74f9e1e7d7949c3b764c8faf27c3d8a840a62c1dcdd641c53a7b987ec8d09bfdd58098352b5f17141dc6162be55962c94d9842e9eb10b8c173beda95a6440c80475e4f75fda6fd2ec41357f66039f8eecd9783c7ab1acc60fa7a6ab6251097b44bd3cf35640e281eca00bd46866534ea35adbf2bccf6ecce239b6bc514a57aae8708b3f249be4584501c528d4778433b80b86fb2f9d42b68eb75e35ad02da7527b66d109775b03273cc9240c7d867aa75c388b3ec3885ad8c355b73dff685f44aa4b5812a5963deb42f5f55ebbb962da1f5938497648599f1d93ecc9e7e94df450bd3d7834eeda6bc2796639271c12cf21450544d54e14369f8570a3109448100f7aa59976809bcdbfa459a386f8427d65d80727adba7a55d24c88c91e614113a79abc937e04781465f4155055842080d71d3de2228243b58f2e0c9f37c646f340d72bce53b99419579cfacb1366db5a0fa89ade0a516b7ef8fd98e766d884ff1520938bbca8583a957c7afd238cc3e7e06fec2f4793a717ac7619393ef6feed5d2ca989a5ce3cb0c851469b2ffc569293207d16cdb8652848c4d68ae56eba012df817f28d5c1d59d8f15fd6da70b4aed95ad1e327befa0386a59726d384e338f32ccdf79d992c1b9d9b41dd5ee6930a78744f5c0de3e2539a5b998a39019126d9b84d9c712c05744602c45a08392785d5ce4734393969abcba0cbd064ab37fa12fa88e08cfafc69df7394dcb27ebe8a7bc8590bda7e0b66f55766fb71769289b21c1e52fda6a218a38eac1e9ace013720d5e6bb4e84a97b79a3261484e359ac8c89582c2ff8cc3f7ceb7c0c1a49670b49c4501ec4ec355e8c67c7b5a670dcd381a4f1864e244a1eec0e95b5f95e2a0f4ac5a33560e00bf3e39032c6542696404a0e492d68f7c0d4f81337bfa904186cd9777b38b9474ff6f552ceac8ba2d840431782ca98a4bf321cc9fd33255c894746c4dca3b4c25b2f03d13ed6b6923a8f012e7e8adef4785b8365d44a6900c411183da01e150d74db229b690bcffce3f945dcbe15975c867237e6dc932e7185c7f971399c5b5211fdda8c54f0d82000a38a1b8c243bcfcce9804d2ca8f52f3170b1a5ff180bb78b3e45d81de923974f1bd8dd2f9a0d4ac565fc09c39ce937bd3bde3ef28415ca54ac0831712cff333f9d87c8e88c59bfd923631cb2ca8da9bd93e65b823ad82c120e8c6b57cad8d688ec5fe3043d6458f27bf5007ff4ea6bf0e9a7a49f05ebbe6729135d07a2c22dab3a8394b825948329717f61d4c445b7676725e93cde1b2f9523fb9c8e6d1e75623b6ac301d70b916a32b3e0c8f8e43a9a4ba256bad4efdd1e6ff1ec777a67f4d02b50774b091360e3c8515396e24116f1e4f126511bf65ccf3285d39fbb220bc208aff20583f658ce7c8dcbfedd3e3964c0643286758f097341a5eaec01d89b3f4947a7ed176128f167334a5552f4b97a0dde63c93ab6825c463b724c340fc58783144ef50a3f99144dc74c847db9e1e3e5cde30251190c3c9cf1d8721d5aa59ae0cdd8a1c6ef527470c255dbe333127f246bc5198b9d64e85b2c81014c515b79c8c69c4ccef1f837765ee07d41a28298ffba02d03a48548809f83f0e1ea83496571df0da9adf4f347554f8e0215448d2dc89579bf72734fd31e6987a192c9180d37095fc0974bdff194f1a42fce60bc30c780a7f784403c72afd4bdcdf5033dab2813af2c3bde971d4381cba74f6f671ae7b619f3395c2ef56d00a27581f1b37e59e2bbf5b0a41ab7e687a8d0c0cbde8dd78023a878bce32e91c69d5336519573d8ff86c7bfae73e10eb257459ab147a2025fce22688ad5caf64fa1cc992597449fa367f1ea0f5a0213019222e259bf06c53b64f48b543b8cee7a867ed25c6b39736867d422653f957aadfbf613ec37c41430c249003fab5bd4120e9eec1f7cf5de5caa4f7e49b0c3eea84cd436f5d79962b1db51d49049d1048b30d2aa08f0a91b793385ce6ffc7675e05db837d0ea1739be44499aebde0b44d3b11385574a35c83b6b23bfb56ac45f9b2ff2cc07b4336823b9f541d933f03b7137b050d2a696fb86b83623c7ceb4b4f0f6d5de97345f93c2d1c77be56a8db51d310f888cdb267020e9c6dccc50569c42d455e2da210ff356ee5a6e4ed99b9841497c540eb44e9c9d0e41ce368f11365ccc5775b0ca6be30f7177fa4f6d62da98be969365536c5cfc8946dcea2676f773aa311aba40f8fa0a4480b2a912c9d10f4e948ae53c42fe43a9f12f438364d9853a54a1c06b1a7048c736aa1b70d98c32768b394278a54412460d2233ad574d7b1f2830e64cd70c792abe2230f169d3de88b3754e946f6ba18bfb4691042ad03c51eeb7028172b886b835a446342e9839925bccebea3cabe7edfd9830dc939876ba1df57bbc59cd4db8c915fd0eb5d0eb639e782914f5cd93cba36b68e0b1e7acc4c004b3dff045e882334914d13d72c1341c88e5c39aad75e35d066d2f12913b68120b0a69febdbcb903dbdba70e74be98377f8e48a08827eddaa906aadd9b00612c889b4272465afc767e74f68913eb31ca7e54b8cd466a028ddaa7a983615a62fd7a3cad74e4483480205cd8bee528301ec2aab9b70afa4553bc0099381a6b3314c1fe8f41f11011ca8aee1c369c5f97d5b6b3d4fca447d1888801f8325d505c21ea59508792393eb5d7b7b637cdc1d9ee8a2377db42929954d4a8fe7035dc8922aaa3795cdacebc179a9c4fbd1b00c7ac5ed8768359b1f8ed04cae421e9a69df7e50049d935d36f3f2333e84fdb330e8eb343a9df613c738fadd8cd43d1b867bd17ea2d13e74902c29ae8d5fc417e160e75a620a21989268bc894ed3708ee61ac3597766aebda2691f34fca1e0da8ad5e618b820156583d591f63edd9398986a8a58abb38c31d723e8417d18c4c8c7af428e85978796b8e6e9655fed6dee28ada1e1bd9e6680d937b0419d510d5ebaa7a23008c04c4f61c866f284d525c41f114a7fa02a03edbb4e9bb5975f5d5a2eb484f54bbeff53f44eb372a2a057d25eb29c9ed89d4b4a1926b4a370a9793803b13339ae46155f8a199ec57a71e1995d2ad736dfd8893ee728f644dcc9746420dec8cf31fd91b2007a54c73f956189d3ade1e6a4c144afef27ec216367c1d7d5fadca522d3359481c66bfbe93418e2d3c77fab9e3e61eb2e0eace1d8dee5ae6f0bbfdda70864bbad07a67f33021eae39010b234d7d6bf28afea85117ff955ebe94856b147061d7fa201bb5f73c42141f282f3001333558528e090d6c68e1311fb555d4c6f766ae7bfe5d4a1b6d786580378008d34260ba95458b69756aea51722bdb0dd77c72aa79de4eadfe2ea679706e5693469f26cd30bc7691e15e0593a7d871d008e619a51755ad7ce1a66483636e6311b871089dd47f565c627e2aaf419a4678dbba9b5aca4853eb10f5716a5f5d862fc24b9b8addfaaed492b8e68be8374e66e2262678f63db7dbda8b5f10a7b2eb5c870236052f86108cbb562619077c18cacbb81eb0be64b1de3fda0490e2a9b6e579c0215c68573a2a872e3f1c3ddb4f5e9f9b96bd89c3b01d91b679c5c823790c2ac963dc542c901162f2f990a9eb3d12b2476212f46ebe4923102de8945a3018fac2c199611fd14249235ade48923cc71b0c3844d96dd5eb7a3761224fbc72ef507b07374e7bebe9644b538d24012cdf6d0b28009ad951b80218d102efbbc109d5968fbdd07d8a4595c85cc6929d4fba29311a76f3b48c6876102ef1a71b4bc4cccf2b52744e39c2b58669d4289baa6e080361e3b85ad1dd4dd9ce1a29392419f790bc894c05c8328fcadf72a2eac270718d508887b6ec51c1c944ea982b2563065fdced4916b0ff69923b0de831690b95c3fe8a92b8418b920dbc57e68ee6c99ff973d22935e141a95088738caf0e3f2a8f52ba5989c79a63bd53320426e5a27a35d02e5f701ce3b2c54469b56d9db4adddc154b65f0bda045c97854349b63068061db312d21b3463dc6879a6f8a134dd51c60e85a1c303e4a64e87c438762e9d5c67500268714ab1f870b208c5af89ff580599ef9f1a5b97d7beeb11c32214d3cac29a9ec1b92d5a225def302cfaee458e3d2e4a47e6e8bb2948e45edeecf72f9cdc51b41670c0941682a9d6841cfe78078dbf49f6b31ecd239d2bdd7a6a465eca08274a55fd96819d838d0db663814432cb642e728c3e8ddf3bbfae03f85dc3c6abb50d5a893935891e6a4d5f9f83570de97ed6fb7a8e3a66072ab651e08eafd88b71905da95375da72efd355f2f9173c5b08720389744f550b6e8344eb428916376728aa5e8d7c84cf6b743447904a9595e27a9fcd1fa95ab37a54966c1a8a9aa69a4ca76ea87807f5a4471880f000d312dcfc76e72f1f6573f988ac0bd5b74e5d2db7b7296ea6ef46ef3841120f1d2e338e7c5e18010f15ad4cdb3b35d8e62c503b11866148ce2eb0cf6768cca371e8f17c23ced386096f53be5b6373fb190a8b81c245a6cad800762980a466f8e3e4dcb2b7ad9d24963f0ac02b2f69bb3ff4c1c3f75f5516f64ee16360537c4bb04ec5ab00100ec25187317e56ef74d3ae773ad68ac2ffb876c3688c029ce8f8e07996279c9a69056d612ecc671c2ed7d6907c9d76689377f192e06ad0dde21b005dc6a4d3777ee4482c1abd9e9717257dc40b7db09fe814ca43798beed61a00879ce64d976ab1210c8989c7516cad3635a954544a604b1f1ab0ad21b19dbce2f14b1534a33d2c029c29184bc15a88c869625824814ade2a87d545826320ac32790eeb84bf86fa1a73d29ca7782f0f91acb01c22d9c4b4e04eb3c808c4ddb4a5c85f15e7000e874ea7955086df8be56f9629193ffffaab87408f29aa24f7066bbd61fe63a3d801ca4b71decc2a075739e03801ad06b16f3ff1478a6d325500397bc8d1d6ebaac3aef66f6220f94a19e321639b0d305025ed31334957cf4b655679cca10dd87ed65bcd981792540252b3c280cd25fa1ee0141356a7ca75ed53a6923b971b4b4c68e290491e4eba3e1041dcbdb04ba966b96689e988c29e82bfec5e1ef682715a007488dabd1dec430ab7656a9d6e5507f3eb1485897567e767b3f1332e1e865cf3710cc66f0fed4d4d3c31a4d3c7b52063675d4a0837cec957f253092fb45c066e9fef62035eef28dfff7451774f3fcde14fee661f78b6e4b9eb63fb967ae9b48db30e3b01e53d21659b060ab2360e04e9f3db193831f65c99ee5a05d65ea46dea0df323bbbbc922fb287d26a9cf360110c179daa1f5b5f1feeea7060e4bb1a7a68c27fd6293fdb21305d2222acd5a379d2a0fd375d6a0c69635e74cf2b130785906ec9f21d5265b48e599d467fd57d4e6bacc49e5a3991119e3cdcbed525e89603315c35f42f43f0a48bd6d773c03e6b1c2ee5e00325c365e3cc6a0f7a0de040c238ed452bf437f11c6f6ae5bfc9c08bd93537a6ed53382c8610fa71a3cb7781f74ef6e326addc4b6dfb5e7daff4178a7c5071a46dc9ea80e843196644c4d0ef0dc1c65b12febd5d1068c2018951d8b2e8b9de5b6f2f043933df27afc51e14daac0ac991856b1a2146e9bd0a8ea68f24ab844725de9fbd8fdb61d8d131203d29c38f8935dcd0bb94a7c0c90a991b0e36e2119fd18d95ba99d9d496d8e0eb6b25a7cd5ec5e904881c6566876f85e2525a5a258e12fd1e49420b058175fbac7ccff1575ce4b8e3498f30a86981ab0cf22ac3d1c5dbc9aaa06d2be08bdf9a5cec2bd85fd7469bbad5f0b6335d4710545da27a96ce6047fba13aa19705695b37698f3fa1e2a55ceba97e2240713853d3d87d948ca4451f11e957dd26bf4a9f688f91ae8e48742d70f64fb8a17da80d8975afa3f3e7b33f68ef02dce6d5c2cbc1043515e0b3b7cf229052542ab9ef5c3bb10d93acfd5d80f76537b982cd9b22ed854eab98c81381702dcfe91f61e871b2876dc67e88447776d720fd52daff6c729da5b50b3cdf9310a3d2e8bd9e8e0e95a163fc5e869c431e7f9434a7c1f95a3cae74ac853091285e6a4593ad71919fe364faee00dcbe265aa08d215e360401be6d88142778c06ba65d9373ce7ef50206f4052f2a20d05387aa522fcf9d4b3667685d60ecdaa644e0bfaadff3782f3f04c733e79ca78a3d52c84b2c9427d3f229a4eab5427073f84095b47f0cb9952fec67d79ba31d81c5991d5be5695ba4df77f8967acb6a119ac952dad1ec92341a605e92bfdc7b0796de2944b770ab282d480f01ef7455cd7814252cbfd917b7bc704da05d597819287c77a3379898cc8d1306b6e31c1ba201daae5b469942c25e5c0680527abafd02c8cbfb2acb4d990c65200b4998220b805fbf4be812de9d96b9824e2990da6237a90124f201bfc47f86a35f07634f441dcaae465c4ab1b1ad8551f97cb2c8910e8ee3a6add594597859852feba3715b497713531da67b28268aa720db795b54b34c12c5794a0b7c168267e7ecba030178ec115c9fda0ab13eaa92f3733cd74805e2ed76ec8b876f511930f0293fca0440328c5e0ed0520af419f5982de17441058a9ef387b6b0a53d0c10b603b956f26242ca788d401684f07b8adb98f64d4fc7390fe2537c2298d2b1d406947a1ff4598a2559cb21df341f4be159fcbdd3ec87f833f4f60bf57cd991547e66357446f1a59c9e5fc9cf7001a648b4608392be9978679a53728aa55ff950ccab0879cbd4915a643b4a0f390f67368a2b8aecc77083a3c14c038bcf637e522759b6e0e437d871b597f3f2746c4d2176b31c192b3e7f54ae5c4a85260b6a9aff3a1c4a4b6a5fdd7d088cc3a8897c2c7da3dfc2d2374495ef6bc31f44a21960e1a30fc9126a9269c478e8a5ddff8e8ebdaec7a135fdd924d05c4f6b163d314c03c506063 \ No newline at end of file diff --git a/hildr-utilities/src/test/resources/txtos.txt b/hildr-utilities/src/test/resources/txtos.txt new file mode 100644 index 00000000..6b4c0a51 --- /dev/null +++ b/hildr-utilities/src/test/resources/txtos.txt @@ -0,0 +1 @@ +0xbd03e4a0f0087b44ce1e054ec41ea9e783a168fe1009e4309c3b224c12d40c523c1b20c198b9d66708998139a9bbc2acc58269b2dbd91d60232e7b68f6db355acdd169dc652c9c37f1ab11961e1635720d976d9f017bcc82d03d6c8c67470736c7ad3612f9723df6f30f36622b1153cc6df3c0f6e5f1215fb35dee6a283019168fd1278fcdba7b9862f24c117a72d35e4741e2283ed2479f811e70ee7c72518d8a4a2715d121632ea76021a392311b885924be9e945dcd0a1f312e31e9446bfa302230f54916e406fca2da5acbc279c743b2fc5fb6699547aefdfb229fd8763e6b10d5584ad41847aa8e37671b2d3c156b5f133189a0111e182e293c89264bc6f25d3b741aa40a84021a704383c568728320d7f0d4d1064420bc54b5f22739f7198447689e971c3478110ee6f350187257e07914bc8a3fecba1b38e2bee51dad3b6ae5b3f14d9d1afb079d6862cff4bfd4d3e22ab44a9c76ed46fb4ecf6da5cbde13e8dc61c3c75a54f1d550bcf769f00319535fd3933ad5aefc6345d4a2013d5d18a76338549915046f997e3386fb9979a84c3c3b5096fbe40ed14a548121263e485f4d214b86221467ff39a6f522ec19f9063479aec0908f90cc07b8512db84cd936877732cfccc1e7f7c995b976b9cd6e51bd4c829bfd0a99fecd420a176d7d2a1d2fe7297bb4edc54d877d73ca35a4e6438797f987c1441b9829b6ec7a94dc7bd12949498ebb79070954ae5dfd73d9d8f06c95ca3b5ce403cf6473c98ac3f6e13592bea1f3aa6c9531f2d27022706bf242aeec2bc14dd8f905aa98c0facb3e3dc19128f1f96d36372466362d670efc3e3e181a78e208d1b5fbb85cc267d6873929cd03d111aeb0edbb6cf6ab8e5208351a9fed80cd118819a9a6eaef92e4635f6d00e345166383180f7f78c5c90f517508c41c12276ee794ee7cdec8cf38fc783cdc9824f74e5daabab5c113973cc1bb45d6d40f7cf92b0a9b426bcfc71115404761b02fd25363b5c34bc3ef55f18322d19449b6fbc115552bceac115662048d0a49406a46b9a85e209a906e96d401f5e92872da21748381a7279cf5599dfff2c36cddb4c72b7b0419e5cc8a554012a972f2700da9d658e671a341ab20b4d675c78559380e10f862a257639548ce3a867da02a16e23f6165c814145141d187971d7570def682456c3425c21d0ea5f188a3890ac3fc8de9cf5e466ce1e5bdb9cec8a158eb0f8200d846e844d2ab3d153d0340cce5d2ac72661522cd18dd0529f917d698b8c90623f2ba772c885263775d9f66decca9da794ccbbf6b52f4888ecbacf3c2d87066788df455ca7b3950b852f30e3bf657674ad8af5be29d55395e6360b3c460d7e15b98e2db4148ff5e967e6a39ee84a27245c00f88ee39d33d11e7baadb74b3b26b29c9c14369a2f67c0f5c39fcf978280f6bf32b38eacc7954d98b0c20000c1be7c8eaf1fbc11495136da1e551b8277c5efcddb45acbcd4aaa0c71c3afdfba70de42f392e9949e997cf02ea934d77e7b778c53895c45d9c2538867d5e84810e5692394d68f22267eb8f4cdf5222a9b9212170aac1b9b981dc1dc2955344dea1ffec73b4afaa11904e732639f819135c5bf9ddc9fd72dbf531e489c4bd3232e9bb27415e1c98b2043d36d2fd350e0e28efd6fc4a396532ea5defdbeaaca2fb5a7902a7596a4d9275e651e79fa9802efa2b23e234cfeafddc827132bda438170f232bbb7061229d36322e638dce7cf0c9c3c7eb0aab7bb5b4a362cc3b525cb8697599392ba6536e6ae1394ce15754400c152124eafe1b99a66e8a960a92b97f03361440e0f869b0508c6f38d4068a7f4f9ada680e1ae94c355373aca080beb31d0055928862170d6fda13136b84348b4a289e446bba83eb5edaa32a2cf4ce591b6aac40ff78b43bf7eaaf53d418edcd471e9647854e3b83394d5d32b9c182eb4032602b8bdb75b0822596d84401b08aee16160d3657f7ce3c11959bc3910b7598d99ba16ac7f827a6612ebdf3cb807bc2a13aa54f15c7b5c7803f7ef2a2f4c834f02b9624f9fd554efa2cf3e4fd38086e6042ecfcbebf505b272396f6ee16976c15e2f680e75f2b8c57f7db461b45390f4e7d0a6d71465ead98102f5af416144536984ac148c99d08f81715eaa2445bb974411d8f891d5a549e160e6a942acd72762901b26cd3ff1037e160f0d403673ca8368c785b97febdc8b5ba42ad2f375a7ec15f13c034c11a0efdaa14cf5ace2f9c988f245545a9157a47ad3c9facc90997c8fbbce919658f9b613c0f0077271b3d793be3b52e8a4dca23b684bb3bc0da8357e6898bd631f4587b6b4f95ed60caedda91c8d9065e959e651d0977c1a1720008d07b10f18f46735a32b0f7b1731e7910bbaaf670da824af5ac7944af18819ff2248cd446bd50ff2dab0b0723a1a9297ec7fb1c8f2e4ac4a26a9106e886daf92b13ef180dc1e8e5fb0400a837e5032b4533d2935c25e5f14543cd5bbea0c094e0be32106d9eab5be44e0d1ea929382627fa3f2bf8c625b8c1d25ca22535bfa996dc91ad92d0800946edd17af0e6a75a7c8f3fa75de92778f0731f91222964d4747009c5f11185d65bca0812ec73216eef06c5423d6fa9f03d98acef0aeeb0ed93218fb534a784a3da151763328dfc107bea9185213134ee8289809e57f9ac7cea8efe45f465de92b6fe3d5a2ec27fce837aea0dab1c58b01ef4cb1b5c60745a58e8d8361ae1f798832e91bdc9521c9e96e8e3018560e5ddaf2b7461c269e005c6e7c7e25578a38081a50f75fe83d92e3b79214c2c35b029b72cd959fa58c64c7d4c196369a7cdae8b09875a7b7db71239344b161bfbf504cc5da47e449ae35f5546037f29146158b6446f7cff9bbd0ac9ed665d36ef2f11375de8cd989c733042ef148793291b6dae3e8bb800a3db64c4e1f21525109c0c62ec85c050dccaded456ca542d8c3d5706086cd10d56b329ff18bc2bad26f36d91dd81e68a39f36e73f7a0a02cf98f0067e48339e90a0a41c2acf11fbfdfa006033494f1d534a09d786947d182562bda2e11d76734fbca5b337cd429d1c8edaa6c1db59fc8de1c0972147edb19825ff7bdc4a065ff200298f4e16914356657a128680545e9c45651149eddc4facf2d540fd670c93f48a3441d17cfa42add96c46a3c55f941ed64b23b17cbeb4097c395618b3385433987eb414775ded308e24ce9f4b4e1a990186223ff93f655948bc1e7c6ec6414d323e9ab0f97a1946ea65a29fcdc4c09282571ba29b161931ce15312df2defa91a6409d0bc7580da4deda0fd7439366f197dde3768be31b9d7cba7c7979e0749141380b67b3066f3456aecab23e7d0ce315686af9cf197f982213cadfb819f8006b5f4b6b401cef90163c306f5810163ff7ec076aa484a6fb1640b4954af249a4c81eed740798a706d1b3f26146b0c4075f773adc6a44d4f5c369d1aa1146627e9b06770c987c52a1ecbc07eafc75e03afe708ebd71ff53012039189717903f08abb83b5b3b1e40d01161512b82ab6e085194f2eb12bde61b744e9c2f3cb8054305b14d9864a9426bc225ab4612273cc1178f22e32916e1cd532ea9bff9cb9d8f4f5b0ed56456e72d5e04a96b870cbe345c68f17ad9cd0d2d56540a215bdce58016756def03db658bfed5870918a451a72112a99c8aac5501305e985073f37eb753813249451d2f34301badd098ceb5722e8687b9109c9ab32bf9572279674158f4a7f457ef777c9ff6ac5af036ced0634f9213d37487f418b5472fb7281b4e2bbbe92b48470dfd032f35f7013103240d9134f6f06125c67263f8472e3b94561ef08eea9dedb5f281865924da5f8dadad320444a107da6e9b1f1b005b888dcd94f09b16efcc2ff3ac3fa40b4efe5aa125dd3cd64328d137980617a9da57b83ea669f9581f7737c320f3a86d681121548980b1b96ea9955a2652d7e0ba3e46e6dcd6b3a310b4f6697dd4cf7e6c19f4bef94b191f5756e93b90e14c0688734479f8a5ebaa9864673c684fe8449081123021c839c5a450f4686fd737125aaf107c6e675d4f40dcbff925d306cb5bcd9031d4c2da6d430ad4c46b213c271804b78fa857837ad467b095d40834852e150295c456e6b812834cc73f4f141329cc615f8a9e3f524ce6a7b550e2a8c127ef2e0fa36dbae49d56b043adb01618a96890df9c0a08476a3efb475c47b375a35148c2498458164422799f28d9266436b8c333e741cb707cee8e4132abefdefeb51427641b0b1e4759f09d704cfd6a6daa2fc7eefe4d5eb549726f42252d022199488cfdbd84cb58280575db55d3542d6691060e0dffd9b29e701e8e5d12d659a7a6b66d58ed45571682686f2e41ad7dfe287966e31a87bdc2c48d9771b417e30c32bd1d40fa967771a0d22300d710318c7a3703a2e0e7b2434e3812be8654dcc0c68dae7347d325bac4dcf8b705101c71db383740028fac6a4bf2840f26ce6313c5af8cdaf0728abed1d8b2c1d881bd794d289ae55cddca1a48de7e6b1d71127194b18ae60fc5ba9e105db6a1e4cff4e3d5942b3da09123affe066678bd4240c5975677d32d2eefecf96a3b93e8e89ea43bcb21d738e383cfffc16b84aa767b31822279c983e86d2990bc2d3bd2692979cd784a59cda6451848b9d21e4c8708f10f1b6fd4128e9a57c0eaec6d56597c6cdc1c9b948c2cb9a5da705025a0d4ac02cb81a241ea2874cebbd3c8c176934587491ecad493feb8a99c5915eaa5c430ccb7dcdd4314a27e521b38b63502f3194bae7644afee0ff632120b138de7006ebbf2949274b2b608e176919b97ce329afd9e3ee8fa49269d03e62c5b5bf956a727397b9731ff28954d0fff114aa5f44ab18d74bb193f8b927361df13729916c66e198989e2fa896115e34098a305a9352ee430c6535d251ea3935dc117495f31ea04689c02452f73f21cfda84502162c3311c16b5f9824489960f1acc3019ccafb58cdf29c514f437de8bca5d6e5100b1b27dc5eac16b51cb3870e0ffb8c33ce76ede954efa7475727e5b38acce9428fccdf293b3d50f26eafae04b72ca0a305687393feb532e9968a439730e71db3f4c447c7949e69c70e75a93ce5b9310f06e9a038123d6610c391ba27616c04a981431311b95f5a48b860e36f95d48282190bf8d6e6431e892c8814bd0c76263f0bc92d8cdf76fd587bb14363051c8e2e67162ef889a687944643f8ece54cec6391e1be75b394274c7e2f3f82b5a97bc7df53af141c7a130cbfc721b765d8bd41257f8f4d6eed9e0b7dcef8fd9d256b7bb367bd50411ec42b203fc94c6db63f88a81aa33be4ebce84c3c1c0ccf0b55e9e6945219f41049aa4778a7cdf41d5d3aac6f9ca2e43201c5644325bd895e1cbf11e20c39c7f6930aadf11d21d90732cec7c1ce90e50946beefe8f19720199708920eca9497283a6e2085b321d3eed0b2d0fab9dc2d1fe7bd2a2ac407680215079094cf34484e876b563ba6653488544a56b70489aceaba74cccf0b77aa02030df3fd2a861b92c1f2ae9bf5c87621d81ddd811645885957b5a75383749e325bfe3b9d0cadd3fc4444a75c1aca93e5324054fc188614a1b0b8b00fae2876597aa54481e47e1f3561aff528080e8e2f13322db9a65a0548ee434ea1ae8fd69e8c745f175d609b1b7b9c2dc07126d85e6d2f9c329422d9285603f05126bf8a9ebcbbdbc3698458b6ce6d93ceb38c997786a9ed9bbf468fe2381c3bc707af4d44d6d499494807ce604e6929f0218f66e772d22e6c46b0e9609ac856f3b3864daffef180682aca484c90d00a5dacc699b33cf4dba3587f61b5069375ffdf2fc3402c0f1c36ffd2dc895b5d9b7accdf918e6c3c6391bdf7125ea06d0d48a0acbbdd3fda361bf88f1dcf2759e78e4ef05a5c62d46b644bae8096bf71f1549b67b276962e59c1331c8c228fd6b54ca135a53ef4be3289ad222ce3d151fe8e9dbf4aeca7970868d8c3372e48bc66ec246de2fcd76bdf2a55edb0730ba927a3a3c765e088c34196255bf54eb931c1a5a3f7cfa6fcac60d9ae28aff4511fb59a4b0dbd640f076cde6276652d055e0f4f3bac91cb8c274fcd3fba3e1770682f510c4f7189fbc8315bd5dc6dbf56b72625d9db41891d49d4ddf0c7d608064cba0b69b2dc0a65a52c3f75da36339d94edfab29582bffbc454965a114ff5100a1be900d218b4b086d7b519947557832286a72ac25392f8beb59f302ede2e8438c54293002f2894ee15091b55db784cacf8abaec2a01b642893e9f736cdfcd1bc96e31abdef039db4fb447562f39b94b1205ed666e50918a38eb1fba20486514abbf89a62d49c677f0ab5da295ab0911be06dfb45919083d13a4c99decf95a8cbdc8b0d4ca428cc565466f68ff908fc459f1f131e87552e35b0cc1e93d2232f6abe86df49cdb148744d0d7496138d17e8c9819084e532d2d86c548f431c4baf3b50d3076da7c1b72e232cee211f40b24015faa6c8166c4c722be4e50a8ac9eddd303eaa4edbcff6382ac3b5fe774dd97c87f4531af6070f8aaefc287e2400d46fa354298f30dfe51ddb80629a3184034a5472f5e21b2557a913db608122f0525ee93c9ec7993340da3a04189e87cf664a3743b551d3276cdb2dc1d50379b30f840f52e647fc8a0794f2e328c35278733e4d38adf11d424cb3d2b311767c7159f967a230fbb01d50236bc3c50252a970c643a479abc11764d52385814b5ba75021c6ba7b73bd6dfe0cd9d2f007fa9398d37b0dd44d9d8f7c81f3ea9e053dd435532c3da43b7d6637f074df7627b19c67a2d941b4800e0e9706e4b579d42529dc0cd1a74ff787d16887d8744f19f2e06e4a1a38f22eba629d98f8502a9cb6e5472b26ea80aed09a9f9b5bb7ff13cd39c159e0d286aa6fcf3836b97edfe04631d966a22cff76e2e627e31a2676233c927bbd043dc9456b3ce771f75c022a5eabc9bc3a36e24a66d86821a6a52d739a8b615dc26ea09f2bb9b19ab13b97461eac1594a2d7c361aadfa9cc434deabe8bc6fc7a45aa19179cf922d726da24d6b74e39a6ab0f68da0335f6636f8db39e127e356cd0b7ee3ad8ea398e068a8958d8afaace42434ca5f4bcaf2cac108ad6ca7266dbe672f920d2fe2f76c4b40e3fa5b3c3cbf3762841969f9859a037f4384a755c003f82fec59574fab19307a32feaee32a555750c23ff302c01e06cdee094036f2de941ee08eeb30c17f2ec5cf5cef1b031324d6b78cae31b28f771fb0cf191e9cb944af5e1d7ba99bb0c8ca5404096e6e6660eb536601175e39a0855d8f2d9b049deb925c2d8dbec5a935c89347b48acb9c19feb5512e4aba077be18867ab8deb72b237fbc91db2db86f31a6b48ff5b416da51b6dbd9decfd1e2a21de8787667ae6b915e7344aacd96b4d6390e39d4529f6c6e010f36d345c461fd71ad1b97a5049382b939bae48fe76bfa8041ff369f8ce93d008c30eca74859f1059c20052d88b94e49449875e9333204b79c6cf7c4197b3894d037a8e7ac46184c5f896b692af7fa64c5d4f0dc6a560bb006b4ce740250807cfac80fb0c61d6e29083d9f7e58ec70a427e44011c24ae624424e0362d6690266da2b2f626212cb019411c4e727e286a301c88664ff5cad0f85df7e300969795c2fddef7af0f5aa3f3584df5698aad344cfe63cd9f7673be12860a68c6289fae6972c84ec81369e7da93376c01f857f56d4fe916d5124d336d7485548e01bb397693019dafdd1e9f388f54620c886bfc61c6cff4aa7954edd3b151826c2a2a2546233e91d3fdfe53affa6e5aab1f094dcf35cd11383180a87adef074604df274dfa51a093b532fb39dd61cd342270d7fd4d4cd09fc9a8d1dc6453d00640fdc3fc23fdfd81d7e6918950e4cccba4638579c6cc099988f347310c5238723140d96c7d28de9866cb6606cec165ac25c3be7fb3bea75b8a957123b3d92c02e4df5bf3e2b89d7e9a42cd5fea457719aa93082e54922b3e3a102f53152ab491bd40df422a02c75f357269f28f4013e9742ea8f732924ed179be1bd4dd48a2d9f67580990b3c1f14770d602c547c4c1399da482a5358029c472ca0eb8fba27d29be62f2ef906aa99fa89258c7ede40bd523ccae09cee91ed297ad42faee603b2e7f6c585ab5e2ddac62dd0640d013503e3b51c31ac5c828945ff98861a8d00534dfc5951335b8e8435ca1713926acfedd7095936c1a314a4c584b90f917345cbf4537c31556bff7e5ccfca493d0a801fcf2164c26c8dae1d8f024f36f5c6044ae9153d2b0939cd2702cf301d279ab711f7c5dcbaf6ff5814d7e14f276c61b2bd6eee906983bf039f31bd6a1f826ed19cd0c93eccb796579c64ad311ddeaab0d65d590f5acfb146a7c70d5a7ff18c694d8233ddc7c11153c940c6f416580319c4474f2dc8895c559193778f35a629915c7020e944cd8ff8f8d03d8adefeafb4ed1aed3481d92148ffe7446b286cea36ec4915cb497d02dbf39e3918d10682536800a30c174e5fc3bf0ed839ee598d24ebadbd8e0ec0b1de0bf5de4f509b7e00052f63cdb8f095a057c7c53ce1e87709431ad60bc33b48e39d677257101d2994dcff6829a827f1251fe4240ccf188729e16abb274a52f7144cc7e17589ca5893fddc945e60dd2058eb3d2497c6f00f9e038b651ccceffa1b4d3ae03c77c46274f62d1b2167bb6d858a412092dd2f21220cde75e7ed67a7223f592ba2637ceff63bafb99b8e34072cafe27da60d4283f61e3ced813a45cb230647f09e4129e3072fa272b058594f88912de83849717e26284692949a9aa92de52f19d2418cb124351505a284e48a1dcadb5529e98a8d96818fd7c3e8bb4e673a2ac8e10ed20d390c7ce93496007504be7324d7399ead5d98b88dda2731d3cf94d585e349e3d18db738c5ed65b5950bb751d494c0c84a948e1dee30547dc8d1facb67ba773903c30930121c9022badbb5d2b0259717c4bc198dbe1e975e09399469b27e0da168468cadca97376fa02ca035fb88255a3f1f1cca61a1ba5ae253be351d12cbe8ccdeb278e81b18a555c35ce4755352c0d689020727cb9948127cb0e3ec4f6ff74b6ed7ff9b8acd3bd7e570f29052536e811642104da5fa36a4dfc405af455afab05af454022b98e248cf8a59d5702b095f8cca001cc6c1763f935dc9b381d8665126e5a1f346b362cc2ed7b03156eac21b84689f4bdcd915d76ccf065efcf7b600bb0326844784f58ce022d68cc2035b06ed555dadeb422c4a91c43cd7951238aa37144486a765a721cf217367e7e0323191ed0accd7512c14483faca55489f3694c4b7d157ffd63b8d0ec58331ae944f8896e67e00917d7267f67750e26bc78ce97e6208a37eefa08420dd55420d7cc2118b5ad139834a668a17f72ae4b514adac9aec60465f692052120268ea57d90a354ec2f715341b870d05cb6bc7415bb0038f0265cc1b7c0b014651349c7ac967efff86e9c73eee7afebc78602dc5df9f5efcf9969804462db2347383faecf4cb4a82653852725754a4fcc14caa57600cec1ca6e793a90cd26914a493669904e5aea2657051c81915b5347d5ce2bc6864d4e0a6d0a74c6ccddf1d76f88cb8bb91633eadfe1fe5d490869de9ce8cca17adb586cecffb6e87c5a904936e15076c1b7b0a1b9e6b7d39ab7f956badfddf274f82a52b4e64d70e26ee40f6b93e1386d1e5f49ae104b25ff5bb44f2be478d6f073144a1fd8bab8da77147ebfb1190cc609a3977de57f73185ccb2046905551597733997e03a9e7af5ddfa8e38dafb061488336b58cc98d78b78f494ba2a02a85002105bbf8f160a4f88fc9e18b9a3960f07cc9d91564e2e488167bef8dc41d76433c09b9bc9ee5de7b0319abb139c4a1d48133b9cdb33c0c5252d224b00e0700d34a928a917af17f198f230ececc9af079aa6ce77346dd00e0863e2f29db42c9dfab933ad3dab628c51e02878f9b00e233fdd42d4fa9c4be203a9167e5e2f6c98d5bd6c10f73cc65babffcb894c011ef201cc70b26aad97690a47349b36fd8259c1ebc100660fa287b9419c88c3eef912a8ca166bd5259d63e77f59c2b0f31d3b1f1c7f17f3a615931b87d8ebc20270c20a6192bdbb6fc5c16ddbcea2c3cde8aedcdb3e864bb64b13aa9ac63024adf021d8138e0af2e9fa0c824fe386b3c38edc1a82b9d983f2e4601b884d3646fe3f1e4aafb869f46cbe05dda68f70f3556c3f0ac70a81e6bfd3249e0462fc5a5f47cc7c1ffe63ddf65863c167e8b90f6606b1217d6d28e960da496943e0176c9ac2b88d9d82cea4ff7bd23167ebcf2e47d92d298a767d2960221312a3c10b5ff67accd40858800297b54e2107bc84d66807c6537ab437c9f180342139e9ac7831f4076bacc471281f4fcc8ccb1379b2a662afe45a9f6f05ead2510a548ba36ec121080cde23c6529d4aeb902b277dda7971cc073e725540fc63a07cd1ac1d64ff3a3205d4429255861e80ef35cef7ed3c5ffacfe7574c7c55fa4ea571061252c0e040c96c8fa2d304f979af41410d05890795a437023d3f094e34311542b05f54523be3001a6db1415f576e09f6a2cabec660878adc3c4cdcd61494a83745d10b3efd40c1a4599ca455625ee720cf61c08171e4dd4ee2de88ab04b1814147a4f4a43c42b36bb07f1f2aefe61c0eb13909a7a4574736a5591e0dcc005a0481d9da65deeab061d50c9448e379abf1083898c4754a6f4837fa9227937f87ca8fb09c4f3fe83aefd286fec41d1650a4e87e27b3d343ea94ba3490ad6d4a9e2626f9dda7a9f72ab21bc9d68784172a35031cd2cb93f77d5c5f6463659eb9b3e5e86d3656b26e992951cd7687bf4c4dea770f64b605058594a22ffe4a46d74570449b5516cc49f87cf30d0c2b1ee20f8e84dd73f2e0445f8bf236d5e650268dbbcb243f881fed321703082bb93130414f52a11eaebf2b7273bb2fcbab81a6fb6c7dad7f97aee0df94e2d8656450e09b6f39b22f575ce5deddfd114f294a44e6c10f41aedc5d831a5dc5fd04e5b0c2584b9923e0f3fc9e5a3d934950ec4ee9fcac09cd2f3d04ede506fdcaf74c0c8421f5db6f04a91457c36fc41d664947ce0f21f1ac1d4518056456c806a4e76b1d8eb459d3c55d7e28f973677d343fb8f6f9ba62da748239ab9400bd45f89d0fb1bf614ba6f5f07d7602362527d5e6b5339e90825b143f3be428296068769320088611e485072a17566cd3d7bce19ed014b1337e508418e29e360cc8f667687162b6683c7fa0cd39cdb13227d13111643bfc953d85c174f2b903d8cb9da26d8a3a6f6fb8bcdbd199cad03087cc9ebc2b35e58d49ee3c271a263a68966ffce06719a6d95d76ce8a46884349806a7aae78b5318f11672b885c33d28c59d7559b88ff4a690cc121a7b046a9e6448cd3e9128b796a8ffe9a7b67a28ba80bdec8f0bb783decee87b01cd0ae2acb0d75441587d11da683657fd4b00aa39749760eabbdbbb938d4d4fb413d0c34275f3e09411fbd23ca47323849a942de6fa563c068590fdbab52ae427f5e2fe29623f2ed7dd1ce5d1054c491f0a36ee297f7b9dc3e828a351d3a4813600b41add78f4ba09edef36b0cbc99d173b57ab4b94c78cd320c846cc13c033cb09aae636764a20450073c95ae9d9a8996f41f7a4450cc7dd3c67fa08b5415b930ae401b958daef4dfc32d65760c4826fde3755e9de49ac5a05ac0a445e294677dcbb5f75336499ebbf904f84a11a6954c5f827dcf26392e60c4627f7398a55960e4a19cf9d97e25bf822d35ac83dcabd943e71874d821703758dba3581269cf0311e3963165d4525f81b427919abe38a81fd405bbef623226924e2e6e25b08ea5258639307c79c17971ab2a440dd6e3757de1ca7728f4b244f3ef44039658c3a4c58ba99c2e1518675b3cec5ff95579d626614861f494335730384f66bce7faa90559d48db44e109156048e2cd13247aee719db0b7d3f31da5df04a17e19ca612f2669d0d3b69e82de76cd7a35d28c9a1d7f58db7344a65bf605d91d4f6702a56166b1a6a2ab4c6dd8b35c950e8b306924c010de71b7e3c7297a5151b8df7542702ae6d4be7d4e6962febbce4171d435542c19efe2de1e7db600fd2525a9d16048627b302b22eac9929d66ba7e1a3289f52307a28811b9a804d31f21a44d814745f53f55ce748ed9b335bd8602a368e2aeff77a7c7226c5e2e8fb6e3976cd39e9d711a15cb9f0bd285359291b6d3df22af8dd89c27f92295c3500cd7820454136bad8c5751dda10e20f5d19cd40a483024ab651c62b14ad67ba505196ac764b2fbb4b06da64bd8e289c3545f7b044e6d806a63547c8f0c47c3b58fb08df3318f9ce25f95cc8e98ea4046923932b6497b2b9aa182158dbc8085798e062dc761ed6e77e078147743a66c58bdc43a7052904ff0754142118556dfb0e162e507bce4f4d2334a1c9e961ef2038325fabaf2a2cf7d0ac6079acde170e8b6334afeb1ac6b2156f2343aa501d9cd6e02399174f190ca568a93f80e922547ee1cd9f161221ea95d4b2f9c9d594aee2f13166835c4590cae902fd1e5cc10eb464ee652756c1970c635d4e9cd606ef2be7fb1d9eeed7492b3cdd12ef326bb1a026a8e0f1440a05fb4769c7823d1710f53ac0df46ee4ff4a14aa2b4cd6b59916fa40f572618bdb57a917419634bff2bac14faf790f2f344cdbfb33bec0e7aba23d8ceb601508385367ef5f7e52ca0b36fa1b80fb8767b9557726d0d623210b30d6d2b356866d88f053349bb343a6f70d45d70f9a31a89ade4fa4a5e4067c14cec9150a3b92d7b96d0fc6be2b4fed9ef690dbd248bfec08035c4799963afd716a45f0541f7f5fa401893d235c734a7fca44b807a9f7da1589d609658060298be4332b4d2f3235fad15843498533c21ead7c4d65306cde34053d05ede8a121127f9e22aa3083f898ced869d4f73be43f8486dab126c58766d4441ad794baafc8d7e603f9e9db749248f68a238516c51d42d404b665616cd460c2eea93aca58181807587018296eb8b1e4177703c9ff263120ad90b996afa327b80d4c1a249c5e2c1ed1d441b5443a645fb3491b04bdc04b3c5a6ce79d48902d0c6e465ebce2c8744f64b298b51368d895defe6d64af6bb1e99df1ac6f579cfebc921f8b833c25e6f028d6b2a4b38174363b12907bd8193b08690f1dfda958fb449e1583f1d5f54943f1dc3c0e81faccbe4dfd3a9149de0c1d9cb7b011020d305a62d75079edf2cf49b8c518a46e0e4129179269ba35768b693af5269896ab76325f0ec41338a3c2328e584d5d8e018bb41c45db16a2d6b4c47dfe1d355f45b9d8d1e1a03409250f1983f7d7c836cb86fe4fa04b6eed58c7e77aad6e772c8c8f88107a85df2f3fd8ed4672cd20ab0a9499903bda532a3a9d1d324589cef7d41afc2f14148bc79b2ce4fb77b541beafbd2e1e7bcf175a019a41880f35cabda52cc6f8b2f794efe6d739df44a7473c2deb8820dc436243bb09b27d4b1888a02d515afabc4bab30398f1478bc8df8c68c826408656cdcdcfeb02ff8f88080af7fc3c2b68d1bc37201cd7433aacc667462573340e83cb5437322f156091fb4bacc72434735bdd8f90a4eb34edee5de812995653702374a78bfb585a1fb37e21a2ee48ec9dcfccf56b7a74e8bb874f316f40dc6ab1dd5cde8ee7397cf89e7bb9aacb7cea4eec56bec0ff26bcbe576c81654d96ede8ba7811b3c92056dc1a012281398fbfbae14abcac9fc3c82509b31e2905cd8992c282385ac3386adf1f7cb53a7691f6ab6e6ce22843050e0a43c6b012868739800591fb8bf331139ecaf8b6cf08596730002dff1299bf9f19900ea371f75c9bd621b913ded85f6855233076bcb1edb0008da90830df0c077b29717a185a0155cd094e7ff7e1bc7f93471b2ed171ab4a6d05be9cd9fbec12fcecc8876b442f236af007648b91758018d52c8252b3e84d81b1d6d110703febcd88305aea5bab655c5dbfc9296a8a9bf109244b0bcd855df8b10fb6f4f55a591943e6e4b81086bbd3d2114bbdf7269ac668b7b2456e6d7b11af07c36f87689651920b4b1a1d94d215e5a5b0cfb502285c0e0a10fcbab8ba77c83242e32282259bca2462b334cf3296b0475b94eb5f0548541bb5a9449723cecd4e646e4b3fd76be9e2aec0a4f3381cd6bc99ff9b8711672a92291b0b4b3bd732d0cf189cae1557c27693f7fb6a614a663944645201b8e3d69450cbc9072d4d9e351e7700901469fa641550a1f7d2d802d7b38d6073bdc7518b73143380428cfff2b68199bc716add3a4f005919d279850ebd48a26fd2ed40f0c7ea1686c7920e2f13a115133062d4f50f047b79b2623db25c7cc6333575494ec65a194a977afe0df17caa75cb82ebeac6d5be36f318935f3f66062b3319d3dc636e4d11387a4d9baa87aeb282351267108268ce90d9023e0dfd9125bc5cc696c8988b8126d721bb5bf61840753bfa424bd2d1f210b8186cdd83c6cb6872302f2cc196a841021c2a006085aa7cf2fb235ff6c2553e0dd46c527ec1ac20d72320196c601f814ec2fc38546c3158894db4270bf06f6b4b57d7f742fa5b129108b062853baa80e5c8712db34be609f394a9c44504efdad5182c02ffbeaf845fbb85b8d5f71cc01fa1626c14dab6f8abd7f356519cffbae2f597cfd3d25db96f2f65f82bc1c32d1559cb9db75d4a307dc8360e5bbdcf35fd7cef892b0a4e3824942f5d9cf7de23b18f612b54996300bbf363590385e341c8e79ab2a00bf879c439c6e30d9dd2d726ac916f9c4035375c4ce22f0df2ca3e1f15ead57a2f3a06d0a77f23bbc167970d51acafe5f015f9709f1ead1cffd96a807c1a639342d19ded61cf4070a0695761dd224d0a375f0b049d7c606b3cd29e717184228363692d4e745b991cb800045a44a16d2d5738521a9b88f636547567a581e4c799089592c5173fc0c3a949c985a4e7b21e70a0e3ee666951d436c9775cb78fdd929d847285d9df7ccbcef10246a720269763b66b1f58b775084a52a04e3a465eacd299061d5e80fefaaaeb2221a0c52a8d0cf259ad05804c21dd28a64ce405fb960bbc095d13f870d5ee7661707029907b013d3009216767e5944f6c5d1ad7d6f8e6cac284d21306313259ba57567888e8cfa6f3d4d94512d9cb9700f8950ab7386b59b084702a5861c9551077bb2e84055ed5799cdb470ac99d0f176ce3e4833365de959b0ebd96fbc642e0be7b50b0e0bf2fe8be1bd3b6dd20977cbee433fbdbdf4958728b2bcf98add5bb36f86a490365e4a74b8b136ffa79520c9db892db3e781ed8a4433821a054350fd9e78914151e53a7269a308d4034a343fbc53d6868d2daa83bb829b72c911f60a045d4df72a29aad5c1321aa88255e14ce91122300ab7471bddf21f0d00d976a492574ecb9edd018552690f53c6c96ae12e94b285ae33d6cabdd6d88ccf274e854cac147e25506b97fec49315f7a1f74a13ce7001405af0748eba26f118637484f02fba39947a43903d04b0828e8a46a414df0d46027f1f3dca633c6542b3567184f0eec086b7452f88f09bde0eb5d7881fcbe2968756af50b1f83d6f1741d764ab8d2aae30b5062ef3fb5fa6f0603f7fa21a4e5bc6059c8f2927f90db876772876df92101ac03b8e1686eb74c857ea2346f6047a5ae52ab19577d2f90bcf42d48f057d0eecc2cd529a8434d4dad3f2ea85e669a9e569695e93c50e4816846c538c12f5c2b541e75359ac9f8c1dffd6cb597a3b0924fe530faa470c53358c3546095ff8bdfba0fce656b1c91dd9ff4655f323a7134c6e995321ddc8d12b943d27d51d057e30a150c8f95a77638bf6fa2b48b2fdb8e03989be8338b3a3394a1ddc4e8e851e96d241eca100ea8e290b1ec10e1c0b506be67e59cefe60868dcfd13af46b4718d364b57f3625b5c1bdff518914f15c896ba21597be45aaa613e487e2cf44352d92add48e4a4a30f563b303c08ead3854ea1ce44c11e30d5cb3730cdfd6befef4ee25972e718002afcda9a2964fdcf0724fbe6e2f73ee44025acd2e7803e5f581daa3aef9eee4de9819e642df03ab1282b8a019a7ede55cfeaab5dce4a7640024562074847f4b3acfc0920873eb8a5bd63cd12df7c6efe7fd183c83c597b819cdd8f00ca6e5dd9d8b6bf94f4625a6b59b0a94afbf0ca4d3a89399afeb76db5d81f9b4f84ace3322253cceeb0cc4de000f9e229f934edd23a7230a34fb4947614b43a33cfcd4acd2daeddb54100f8295e2fdfd74c386d769599bb3c3f8cd7e7dfab2dec4d1fa06cdad3f66237929226adbbb95732b96e4041688f865bb8df07c1a7eb033336f0dd9c44d7a551e706636577f34911fdc010ff65cf2be63255490cdc3a8a0c503b657af68948827fa3aaaf69545adc133d9d31512041e694f70532d42b233a86d2abb4853450750a7a6c01ab1518d855183bf560e1cf70fc5d4dd967474576f1e584c6c046f6bd42830ee37f77e4f1c00fd8b30afbf0ffd5a1331cc0b814678af97c7d7d90c7211ae39eeb917129d07d39ef29d577965eb26ce9de3947468ea05b63fc0c99d482cff9f4d99c9023910b0a2b24beb99467cd7cf4674fc9471e118751a3e911b1650995164555b7333ff5d3e097e8e156f5a93ba545f018f7b805a8b03e2ad6c1174e7ac6b358e2f4758f3ca2e68ae57041a96872034d05dc2bb1635c06108f5e048fd1f2868b4ee804aa21ce0e50d9c708a403cc2a4205565f2d9da1f6efede523585a313915931e31db6a6361a2372cff4f2e61ca28e14d59a1418a34fc8f439a613a856c8687fee8436d9094634f82896c39a34f279bfbcb84fa9e2317fa2acad6632c6728056e8691fee63af945947c58efa93d59a43890a3288b90418b7ee54a6203b57c0302938c3bf1506138cf5a5ff1e75b67787fccd67bb5f2f66eb20a5a91ba44fc638e4ede954a4a0acdea53ade6e8c00ea67f3e07586851e35bfe33e14cbac142c131ad996a44f210bdb742956635f48d4e265b41169c6993aad4f525afcace1d1c00dc444cf157ab177a5bc7db3befe23c63370df940bf2864bc3c2c4a1eeaea1f238cb30abcbff0fefe972903583fef7985b6e169624230c103e255222bdd42315b75a54cace995310abfb0253dd6a2bdfd18d43a6f2302934b4fcdc70b8082be40134b5f6de9e1443acca7743348799b59c56512f35062334a269144a4e4f6128fca468d48bcb7a6f9b8e5ce5bebce4cd971cea898c8d73f9ec50b9acfd504a87be613128430c581c62cf5948b99663241e8211ad37879ef6f5441e9ee58d01db82ac739635d2238840c205c4f9b47d2f809fba715b7b1b24cce695e69b6dde44b67f636a2f1971fd771ea39255b0664e908f78323fef7804c7af889bc01caab7090613662e658feaeee9151a7748ea17b93517bc2dcb4c0d81f9298b07d3c0e967eb90dda2f6d0d4cddd93b3645b1597a0a7251bec29ea01aee0275d40fdd59c34cc2e46bc5d0bc49d87df5491fd85b9dea196f9d18896bba5b6f00aef1f6b7f9571fdf3d532b0dcca5b8f18fe830b51904d1011d3841e8cf4af960236e20d9ebc73e73390fcc29d2d62e8b45e04b41e65d02a8b4dd5ad2ed93bde1bb98afabaf8271d59e81ad4700111a1531e6c297808e89f3136537a05cc140286dd43d8d24b7e03e307cac035b3450727c73e77640001802341dd753b671a94b1dab8868d91a7129e834358e694c51241df8630a218f750cf831f9807de8fd7d55414fcef0b60c85a01ee9fbffb62e99c1bd74bb720c3ee6b427ca5ac39a7bf40a9c28f4077c7e874e37a74e793824f4339ba0647fbc4cc846a31e1a946834f34db639404dd6ad02c5b4eda757a236b690eba7a30e5c64abbeea4295313dd6e86c354075e6f873f6496ac4ddee9ca8f7291a5ff17392e45df6f233cb47c5df9559d545ccef194f25c15c12d22ea2c8bdd7475e5212bec2cf2597772393d304ba132c6c34e59a10e3a3fd9e63c580760d7df849950964f16d53d16806660f9a4352f96726f891cb50fdf2508b3a5d57aa5b98144a66218c564bfef3d0fa1c4cd7d6a83beec67fa43a979b3c86cd6049eff4d5376619f6ac25a93f5316f80ef8ea99a38a6be386b19bfac33aa65e8681018984ffb57ed5dc49e74bd1374e658ee08bf36e25d798996a0da5ccf4623bc73dce6b4fbecad8649e8245f910a7669ae3e055169019a543f46ff3df0032a858f89ddb11b147c3885fcc009a8217c308c3ab47d98b8cc79bccc3770877016617a72bbdc68fcfefb2bc76f7a50c8d3c22d1ee4a01a6ce3c52d225469600a72f67c97d1f12d98d8189a753a09315243a3057dfbc509ae737baa1f4968180affd87822a9276dca1c2f5ff363278abd5a3da42b6ba1b0ae068eba27c1064f4ed3c759c1706a785c899df6405bcb347eb7069d7b1ff03202e1691aed34a162417e220b935f09c69ca637577d6bb093461e1ffe0310ca4ac57929fbf9a22f7bee2d1acd190f23a567cb01d723e0fef5f899e4e18bd56850c7936e84b18b93663b74257a1df0aeeeb652465f5232bdedbd9a5fb4b5bce5ecf5221bedd6802aee37bd5809206bcfdc9a64ac04a0ac762ca3431c2e57f5dc921ee36a46eeb67c24436384f33660904b88e0f054d372a62f3c7acb71b45e3b8ed83b01b77b07c6c8fce13b4f5734d7590f9d4434458d13115f075f8082820ad5452a5257259d0c8ee34860bff68552ab10dcf2c9dcf09ce00ae9b73c23725f84abf2ec6416f15e223ff7cfa7e39eef5770a5d4cd6b1d87b9efe320f75568d2b49aa33833e1836d52d20e93df9768a8f9ff146a0cdb96af8f0b9bff44d9f127b20a430702e822eba0f098bef16292fc8a8a22e78e0732a2a00755d93437b26135af3ca249de29e3a3298aeb33873b8a83e1c0a45556937c88e38d69eff552b850489321f3c5d13f894c40c1d745bb745cf49288239af07f8dbdf85c6d54e766a135b50d38a452a729e14b057b0aa4d4e2751802760c6080ae31860a4e3c7de078167efc151eb82fcf20ab1b2abe60143814059ae05a6392bfe9b80e9a4fdf808c61dbe8e5cb02685911f5d17b64f55eee5193273640d9faed55367ccf644f523f7a718cb3353de685146b6100af828a8d02e3d4ad0c41f0abd99d9856031d9c36ccb12a3c86638aebba4a77e169c35522aa9994d143a430239f628720fa2ec07c81747badf20eb2b5afb27bc40ac08fc725019807b5ffd5fef600be0018fc74bcef868dd6008b8510a747c817a30212447d64348069d110ecf7d0418944e56b53ab7b88b0b0b66de10ac6b3626bbaea98815f4e95c7112d0433d59dd1345f77f1d3680777864dc5f4cc003577faa35c5afa9699e03b602f13c36653d5b5a0c247153c03ce9b075c3d84256c90bd1ce43039ff7835001fceda09462ffc69204151328b875a67f3c3f9ae82d80178d81eae9dcd245747bb1edd5504db35b9821339757892c7e5d7044cd0a2ba20603c4d9bff2069c9f4095bf79bd71a9cdb59d41cdd4d45c12516bde07ff129a80316f7ccc87b3ecaf3d0cfddd35476b2402ca309dfd5ecb3e717b9bd092ff1de7c34ab86943f22a57cd570d2175f42e05eecbaa31861a9a43fda01c05f9f5c73bcd74ddd884fe2420975f33308d646accd241558550c0ac4ed45a3d5b3a6d59518d8b6862b9e9439129344183cbec27e47242acfa4b8991262e74bde13acb4346e7ff529fdbd6184d0dba630504acbd1c3fe902e1099de4b554b09a6c61d6f21381a56bbfe1515953afe2ef23ba2aed9b6452335f0332263723f21d334f528b1a0b370a00cc6d7c7dd371ed975cc9d1c512dcc868f3e2712a68a208d3edbe0582e6faa666a958512985783e8bad92857d0862e8cd19b1f1d9fbf537d312b1cb7aba3c301be983f74bd1fb569485cf9100f5680a71d84268c4a58bba34f6d5bd4702377de9dcfd899c055216b851b94fe5e7f525fb00363b6b42d1adbc391808babc69609be0c458e2bad7f69570728af688ffcbd5d1a9fd0a0628261417e5405ff2ec9daf95c6db580bf24ab003dd16b951bfb85ecba006d1a95e8810b308c2c80ec5e1d72e50b3a1d0d3f9055a1e1cb8161120027ec30b86d4816417909e30390eab31bbd0bfb525e46d1a9b98edabea57837b168b8baeae05cce8f46b127da4054ccaa7d07de54788c88069a50a4b4180e6b869f680d604335aa40f278fd7ca34e4d4290cc9b6ffd34066bc850aef2851200bdd5ad77b5710d0fba326aea891921c84e3e1f3cf4a56835b8e6ff654338d8f85f8629f63a40b82042ccb328577a55f7a0938a840d665831dc233d1873176fb566c17df06c428cb6016f48de1153c03964f2fb609a9baf93a12287ebf62128e785b528ecad1999f1ba3766248094916c23c7aa7c907b85da0d850e4a94c086e7a2d69af03a0dc1bd939685a4b4f7acf0c2c181a35b6650d703a26b769c597e18be3e52f5e0cf270278d618eb3677f81ce55750cf7ffaf721950940b19f2ac1ed9aa4ae82cc6b6e71d90add66695c858b22887ea0dc9b996fa0bb487a048c8731e3d5dd28547a12545f04c6366d708c3e53d1dbf33469f7b8952756e41ec68c2b15501b174aad8c437e50fdf8d64751845936ee9019f6581d04d95ca5025e4f0bcfeb8c478d249b3c303d403c4f1b2ebb28f16d7bd2d5357c542bacd1901f49032c63f3c4447a475ad93b16564363685d5ce4bcdfdf2bf3e360b770a346ac3b433618328d371acaafffbce1545a9fa51fc6977dc5d3810a2dfa398a4f3ada45bb3f83ad13878ac9fb2fa2cee49d2a838557e0cbc3a9afb0734103e42f6b9a342d84e1ff9772d7b695e46507a149320e3bbd39ac369bb8b28f65782009882dc6145dc2b18dab6003d9aa8efff441bf10f9ba58859fe8c530b4b5e8b4e1c0fa63835e14f36c0a43e4e815a583cbad1c1bcc1d3111d03ae32da097422b9066c92b5a73c97a62b5cb8fd42a70f2ef18d764e370a9dcdcf27940114731256f503c32eece9a42a9de10afffa6a700ead1da91461e4bf5c09196853ecfc49c8a0e03abd1a31c2b217966004289506ffde7937f9bc47c27001573315a519883dc9d542bf1f6d8937dfd8071290109c5be83a159ebbc523c962d1c13d2a1be25bb799c869efeadee14ae95ad46a689abade92cae2868fe966201c823f0e9c807c154ea8da9033414332ceee693685c8b2eedbae97fb3bfbd03cd5827818ea5691bfebf9b6c7989e194339625787a557644c0e6f55ddae650de936b4ec96a749d8723cdd36a9d3863219f04562df0e75021faf51cea48baaefd6e5f682212da01cebdfba5ae7d647f6d31ca8e65b109a6fea96205cc6cbe66c85e18588ea8432ddaa31087c65b230e58547ffd41d436b92d8f3aa8b45d58e4ad7762544dc694b48fc98184ff1761b166ec2597fd7823e516c8742f2b4732d9533aed41147b066f059953773d3e68ff5fcf51d821e24c4859da3c4f373f2b83877b9e45355bfb3d1adcfa005617af2c21461ceab8a3137e92434d38b38a60b10b7aa9ceb29242fd96e3e5aa52a3fd3826a87e911cc2906ad6dfafa85f76256e760ed73d9c37f7929f1b0ee281042e6ffd2b751492e346612618d1b621ad12b63da49b30fabbb7494d8b5e1214f4efae732400fc36ec0897697dd71db2ded27bd8069decd52b62737691a79070bc958376e735088f1981f1416f45d7037cba724414153928ce0a529b448fbdde09d967c9de5a5d29cc1788774a37e4842cc286baaf5aad6d149ea306be598604761e01547c5045903928dc39e2aaf65177be3ee461a44dcddd92e53588db0b6f96e9efd1dfe03554c3722eb062cbcfbdd4064f176fc695022b779671199362344f2a12d777dbe11d1b279122377da8e369162ea1baf38c91b25835423de9f919cfd9ee1360308e1be130217a6d711cc21f2346b910a5e1bd5ab5d39c189b4e653ce0609191e6320ba3d3391daffb70f03879fa60cfd1cce54d77b30b4dafde34c5edde260eaf2313ec01bcc88167de9a3d98b689ed814dd2d9cf9625c1f918d1e377f18b4ce1f92049bcc3e3f58c2dcada2489b0a1c73067c7ab48542f8e2b48d70ecc488e63a80ef609c8defe2e8ef0de109ae13226fdfdebd3e067b443cdefb7dc464220b998f630dffa6da21321aea473d584844bf414ce997d49d8ac479402973cbb8f21770a3bc2a28d074f703f6775c4324578d15a3b5ff9a40106a606c5232159e78bad10ac68ed60d01e86f8e019fde9c198bd5369f03f89179cf319422877466981a9990d27841cdeec827e35d2781cfb24d7cffb794e3a8d89f249a6a8c38d271826a2e73a1a7148cba46d6672a49c6c766aa8fd7744534273b824a2a37d797ae4201e9fc9fcf77beab84bd421e0bb6909c10c3b1e7c3117b8d4e4ac0d35a8a5f80b6f78ecf92f9d7fa4ec3aba666fda4a4084b5002eaf2f8a36ff74555877d1221b292ea74067073b7931c0dbaf33e93626945efcfaad4b451221e63b5edc56b8659e56f9bf1b6df8c05e821ea8dae3e1f6a25dbe5c3de7a21c43f6f0ddc8a21afe184414c9349f13b87da723810fc9669c7353b9ef471ab5eefef9bc36c2af72307ec3ad82c74c608daaac35f9064011f93c367192d5a9e98c9fb9958ab525aafc0729691e3ded3b22b6237b0518eee720dca665d0cf570dbb59b951881851041fc173ea96c312b6630ecd3af037af39374ba49b16a5019275ea62780135ce5b3b75b74533bb4985504b6ed602ff9f6e4b85f40b3e3eee6e108becdd1b586fa943d73ed4441b704274379653dd8929998d85ace70f49df91fd219ae13719ef94c9e0b8f4af7319321b44cf4a9de9972e4ce43832fc8e26fdc6754ba3f51da4035a749a0b82769d4d2c33593a51429dd0a18a5e52ac19af6d8cdef6ffcc8ee0bffce32a2ace3b2c9292736bd5e02d0e17a895a40c8c35f25033d38565a64b0b7aaa0fd392e0660af6fca2aa6b5acd431b804e58ce21264f86e6c684764ba601acb8fa7d2fef5b753eebfaa31720d6f166f42ce16cedd4f089d8943b2e3268bc5a82bd206342ebe86f483e80c19f7767b005ed427e088aa2aa06bbebdcf994cf2dc5a638ef2fda027e1d87ece644cf155932052190463e9bde4e32102babeb2b15efc1af3342917405fc6e81cfd9127b40a963c749ad6d22b1d2d702 \ No newline at end of file