Source Code
Latest 25 from a total of 215 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| 0xebdf1bb9 | 17387662 | 201 days ago | IN | 0 ETH | 0.00000383 | ||||
| 0xebdf1bb9 | 17387659 | 201 days ago | IN | 0 ETH | 0.00000451 | ||||
| Transfer Ownersh... | 518596 | 402 days ago | IN | 0 ETH | 0.00000435 | ||||
| Set Default Exec... | 359069 | 404 days ago | IN | 0 ETH | 0.00000518 | ||||
| Set Default Uln ... | 359068 | 404 days ago | IN | 0 ETH | 0.00000734 | ||||
| Set Default Exec... | 359068 | 404 days ago | IN | 0 ETH | 0.00000518 | ||||
| Set Default Uln ... | 359068 | 404 days ago | IN | 0 ETH | 0.00000734 | ||||
| Set Default Exec... | 359067 | 404 days ago | IN | 0 ETH | 0.00000517 | ||||
| Set Default Uln ... | 359067 | 404 days ago | IN | 0 ETH | 0.00000735 | ||||
| Set Default Exec... | 359066 | 404 days ago | IN | 0 ETH | 0.00000518 | ||||
| Set Default Uln ... | 359066 | 404 days ago | IN | 0 ETH | 0.00000734 | ||||
| Set Default Exec... | 359066 | 404 days ago | IN | 0 ETH | 0.00000518 | ||||
| Set Default Uln ... | 359065 | 404 days ago | IN | 0 ETH | 0.00000829 | ||||
| Set Default Exec... | 199746 | 410 days ago | IN | 0 ETH | 0.00000511 | ||||
| Set Default Uln ... | 199745 | 410 days ago | IN | 0 ETH | 0.00000812 | ||||
| Set Default Exec... | 198195 | 411 days ago | IN | 0 ETH | 0.00000713 | ||||
| Set Default Uln ... | 198194 | 411 days ago | IN | 0 ETH | 0.0000133 | ||||
| Set Default Exec... | 197566 | 411 days ago | IN | 0 ETH | 0.00000567 | ||||
| Set Default Uln ... | 197565 | 411 days ago | IN | 0 ETH | 0.00000957 | ||||
| Set Default Exec... | 180645 | 417 days ago | IN | 0 ETH | 0.00001306 | ||||
| Set Default Uln ... | 180644 | 417 days ago | IN | 0 ETH | 0.00002897 | ||||
| Set Default Exec... | 68100 | 432 days ago | IN | 0 ETH | 0.0000049 | ||||
| Set Default Uln ... | 68099 | 432 days ago | IN | 0 ETH | 0.00000806 | ||||
| Set Default Exec... | 50253 | 447 days ago | IN | 0 ETH | 0.00000551 | ||||
| Set Default Uln ... | 50252 | 447 days ago | IN | 0 ETH | 0.0000081 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 44686209 | 1 min ago | 0.00002355 ETH | ||||
| 44685348 | 6 mins ago | 0.00003433 ETH | ||||
| 44684446 | 10 mins ago | 0.00003433 ETH | ||||
| 44683568 | 15 mins ago | 0.00003433 ETH | ||||
| 44681792 | 25 mins ago | 0.00002618 ETH | ||||
| 44681778 | 25 mins ago | 0.00003574 ETH | ||||
| 44681705 | 25 mins ago | 0.00004738 ETH | ||||
| 44681705 | 25 mins ago | 0.00003433 ETH | ||||
| 44681514 | 26 mins ago | 0.00003574 ETH | ||||
| 44679908 | 35 mins ago | 0.00003437 ETH | ||||
| 44678934 | 41 mins ago | 0.00003437 ETH | ||||
| 44678934 | 41 mins ago | 0.00029435 ETH | ||||
| 44678649 | 42 mins ago | 0.00003578 ETH | ||||
| 44677278 | 49 mins ago | 0.00003574 ETH | ||||
| 44677081 | 50 mins ago | 0.00030138 ETH | ||||
| 44677025 | 51 mins ago | 0.00002355 ETH | ||||
| 44676807 | 52 mins ago | 0.00002355 ETH | ||||
| 44676765 | 52 mins ago | 0.00002355 ETH | ||||
| 44676680 | 53 mins ago | 0.00002355 ETH | ||||
| 44676623 | 53 mins ago | 0.00002355 ETH | ||||
| 44676186 | 55 mins ago | 0.00003437 ETH | ||||
| 44676185 | 55 mins ago | 0.00032191 ETH | ||||
| 44675919 | 57 mins ago | 0.00030007 ETH | ||||
| 44675653 | 58 mins ago | 0.00002355 ETH | ||||
| 44675060 | 1 hr ago | 0.00003578 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SendUln302
Compiler Version
v0.8.22+commit.4fc1097e
ZkSolc Version
v1.3.22
Optimization Enabled:
Yes with Mode 3
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
import { SetConfigParam } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol";
import { ExecutorConfig } from "../../SendLibBase.sol";
import { SendLibBaseE2, WorkerOptions } from "../../SendLibBaseE2.sol";
import { UlnConfig } from "../UlnBase.sol";
import { SendUlnBase } from "../SendUlnBase.sol";
/// @dev This is a gluing contract. It simply parses the requests and forward to the super.impl() accordingly.
/// @dev In this case, it combines the logic of SendUlnBase and SendLibBaseE2
contract SendUln302 is SendUlnBase, SendLibBaseE2 {
uint32 internal constant CONFIG_TYPE_EXECUTOR = 1;
uint32 internal constant CONFIG_TYPE_ULN = 2;
error LZ_ULN_InvalidConfigType(uint32 configType);
constructor(
address _endpoint,
uint256 _treasuryGasLimit,
uint256 _treasuryGasForFeeCap
) SendLibBaseE2(_endpoint, _treasuryGasLimit, _treasuryGasForFeeCap) {}
// ============================ OnlyEndpoint ===================================
// on the send side the user can config both the executor and the ULN
function setConfig(address _oapp, SetConfigParam[] calldata _params) external override onlyEndpoint {
for (uint256 i = 0; i < _params.length; i++) {
SetConfigParam calldata param = _params[i];
_assertSupportedEid(param.eid);
if (param.configType == CONFIG_TYPE_EXECUTOR) {
_setExecutorConfig(param.eid, _oapp, abi.decode(param.config, (ExecutorConfig)));
} else if (param.configType == CONFIG_TYPE_ULN) {
_setUlnConfig(param.eid, _oapp, abi.decode(param.config, (UlnConfig)));
} else {
revert LZ_ULN_InvalidConfigType(param.configType);
}
}
}
// ============================ View ===================================
function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view override returns (bytes memory) {
if (_configType == CONFIG_TYPE_EXECUTOR) {
return abi.encode(getExecutorConfig(_oapp, _eid));
} else if (_configType == CONFIG_TYPE_ULN) {
return abi.encode(getUlnConfig(_oapp, _eid));
} else {
revert LZ_ULN_InvalidConfigType(_configType);
}
}
function version() external pure override returns (uint64 major, uint8 minor, uint8 endpointVersion) {
return (3, 0, 2);
}
function isSupportedEid(uint32 _eid) external view override returns (bool) {
return _isSupportedEid(_eid);
}
// ============================ Internal ===================================
function _quoteVerifier(
address _sender,
uint32 _dstEid,
WorkerOptions[] memory _options
) internal view override returns (uint256) {
return _quoteDVNs(_sender, _dstEid, _options);
}
function _payVerifier(
Packet calldata _packet,
WorkerOptions[] memory _options
) internal override returns (uint256 otherWorkerFees, bytes memory encodedPacket) {
(otherWorkerFees, encodedPacket) = _payDVNs(fees, _packet, _options);
}
function _splitOptions(
bytes calldata _options
) internal pure override returns (bytes memory, WorkerOptions[] memory) {
return _splitUlnOptions(_options);
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
import { ILayerZeroExecutor } from "./interfaces/ILayerZeroExecutor.sol";
import { ILayerZeroTreasury } from "./interfaces/ILayerZeroTreasury.sol";
import { SafeCall } from "./libs/SafeCall.sol";
import { MessageLibBase } from "./MessageLibBase.sol";
struct WorkerOptions {
uint8 workerId;
bytes options;
}
struct SetDefaultExecutorConfigParam {
uint32 eid;
ExecutorConfig config;
}
struct ExecutorConfig {
uint32 maxMessageSize;
address executor;
}
/// @dev base contract for both SendLibBaseE1 and SendLibBaseE2
abstract contract SendLibBase is MessageLibBase, Ownable {
using SafeCall for address;
address private constant DEFAULT_CONFIG = address(0);
uint16 internal constant TREASURY_MAX_COPY = 32;
uint256 internal immutable treasuryGasLimit;
uint256 internal treasuryNativeFeeCap;
// config
address public treasury;
mapping(address oapp => mapping(uint32 eid => ExecutorConfig)) public executorConfigs;
// accumulated fees for workers and treasury
mapping(address worker => uint256) public fees;
event ExecutorFeePaid(address executor, uint256 fee);
event TreasurySet(address treasury);
event DefaultExecutorConfigsSet(SetDefaultExecutorConfigParam[] params);
event ExecutorConfigSet(address oapp, uint32 eid, ExecutorConfig config);
event TreasuryNativeFeeCapSet(uint256 newTreasuryNativeFeeCap);
error LZ_MessageLib_InvalidMessageSize(uint256 actual, uint256 max);
error LZ_MessageLib_InvalidAmount(uint256 requested, uint256 available);
error LZ_MessageLib_TransferFailed();
error LZ_MessageLib_InvalidExecutor();
error LZ_MessageLib_ZeroMessageSize();
constructor(
address _endpoint,
uint32 _localEid,
uint256 _treasuryGasLimit,
uint256 _treasuryNativeFeeCap
) MessageLibBase(_endpoint, _localEid) {
treasuryGasLimit = _treasuryGasLimit;
treasuryNativeFeeCap = _treasuryNativeFeeCap;
}
function setDefaultExecutorConfigs(SetDefaultExecutorConfigParam[] calldata _params) external onlyOwner {
for (uint256 i = 0; i < _params.length; ++i) {
SetDefaultExecutorConfigParam calldata param = _params[i];
if (param.config.executor == address(0x0)) revert LZ_MessageLib_InvalidExecutor();
if (param.config.maxMessageSize == 0) revert LZ_MessageLib_ZeroMessageSize();
executorConfigs[DEFAULT_CONFIG][param.eid] = param.config;
}
emit DefaultExecutorConfigsSet(_params);
}
/// @dev the new value can not be greater than the old value, i.e. down only
function setTreasuryNativeFeeCap(uint256 _newTreasuryNativeFeeCap) external onlyOwner {
// assert the new value is no greater than the old value
if (_newTreasuryNativeFeeCap > treasuryNativeFeeCap)
revert LZ_MessageLib_InvalidAmount(_newTreasuryNativeFeeCap, treasuryNativeFeeCap);
treasuryNativeFeeCap = _newTreasuryNativeFeeCap;
emit TreasuryNativeFeeCapSet(_newTreasuryNativeFeeCap);
}
// ============================ View ===================================
// @dev get the executor config and if not set, return the default config
function getExecutorConfig(address _oapp, uint32 _remoteEid) public view returns (ExecutorConfig memory rtnConfig) {
ExecutorConfig storage defaultConfig = executorConfigs[DEFAULT_CONFIG][_remoteEid];
ExecutorConfig storage customConfig = executorConfigs[_oapp][_remoteEid];
uint32 maxMessageSize = customConfig.maxMessageSize;
rtnConfig.maxMessageSize = maxMessageSize != 0 ? maxMessageSize : defaultConfig.maxMessageSize;
address executor = customConfig.executor;
rtnConfig.executor = executor != address(0x0) ? executor : defaultConfig.executor;
}
// ======================= Internal =======================
function _assertMessageSize(uint256 _actual, uint256 _max) internal pure {
if (_actual > _max) revert LZ_MessageLib_InvalidMessageSize(_actual, _max);
}
function _payExecutor(
address _executor,
uint32 _dstEid,
address _sender,
uint256 _msgSize,
bytes memory _executorOptions
) internal returns (uint256 executorFee) {
executorFee = ILayerZeroExecutor(_executor).assignJob(_dstEid, _sender, _msgSize, _executorOptions);
if (executorFee > 0) {
fees[_executor] += executorFee;
}
emit ExecutorFeePaid(_executor, executorFee);
}
function _payTreasury(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) internal returns (uint256 treasuryNativeFee, uint256 lzTokenFee) {
if (treasury != address(0x0)) {
bytes memory callData = abi.encodeCall(
ILayerZeroTreasury.payFee,
(_sender, _dstEid, _totalNativeFee, _payInLzToken)
);
(bool success, bytes memory result) = treasury.safeCall(treasuryGasLimit, 0, TREASURY_MAX_COPY, callData);
(treasuryNativeFee, lzTokenFee) = _parseTreasuryResult(_totalNativeFee, _payInLzToken, success, result);
// fee should be in lzTokenFee if payInLzToken, otherwise in native
if (treasuryNativeFee > 0) {
fees[treasury] += treasuryNativeFee;
}
}
}
/// @dev the abstract process for quote() is:
/// 0/ split out the executor options and options of other workers
/// 1/ quote workers
/// 2/ quote executor
/// 3/ quote treasury
/// @return nativeFee, lzTokenFee
function _quote(
address _sender,
uint32 _dstEid,
uint256 _msgSize,
bool _payInLzToken,
bytes calldata _options
) internal view returns (uint256, uint256) {
(bytes memory executorOptions, WorkerOptions[] memory validationOptions) = _splitOptions(_options);
// quote the verifier used in the library. for ULN, it is a list of DVNs
uint256 nativeFee = _quoteVerifier(_sender, _dstEid, validationOptions);
// quote executor
ExecutorConfig memory config = getExecutorConfig(_sender, _dstEid);
// assert msg size
_assertMessageSize(_msgSize, config.maxMessageSize);
nativeFee += ILayerZeroExecutor(config.executor).getFee(_dstEid, _sender, _msgSize, executorOptions);
// quote treasury
(uint256 treasuryNativeFee, uint256 lzTokenFee) = _quoteTreasury(_sender, _dstEid, nativeFee, _payInLzToken);
nativeFee += treasuryNativeFee;
return (nativeFee, lzTokenFee);
}
/// @dev this interface should be DoS-free if the user is paying with native. properties
/// 1/ treasury can return an overly high lzToken fee
/// 2/ if treasury returns an overly high native fee, it will be capped by maxNativeFee,
/// which can be reasoned with the configurations
/// 3/ the owner can not configure the treasury in a way that force this function to revert
function _quoteTreasury(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) internal view returns (uint256 nativeFee, uint256 lzTokenFee) {
// treasury must be set, and it has to be a contract
if (treasury != address(0x0)) {
bytes memory callData = abi.encodeCall(
ILayerZeroTreasury.getFee,
(_sender, _dstEid, _totalNativeFee, _payInLzToken)
);
(bool success, bytes memory result) = treasury.safeStaticCall(
treasuryGasLimit,
TREASURY_MAX_COPY,
callData
);
return _parseTreasuryResult(_totalNativeFee, _payInLzToken, success, result);
}
}
function _parseTreasuryResult(
uint256 _totalNativeFee,
bool _payInLzToken,
bool _success,
bytes memory _result
) internal view returns (uint256 nativeFee, uint256 lzTokenFee) {
// failure, charges nothing
if (!_success || _result.length < TREASURY_MAX_COPY) return (0, 0);
// parse the result
uint256 treasureFeeQuote = abi.decode(_result, (uint256));
if (_payInLzToken) {
lzTokenFee = treasureFeeQuote;
} else {
// pay in native
// we must prevent high-treasuryFee Dos attack
// nativeFee = min(treasureFeeQuote, maxNativeFee)
// opportunistically raise the maxNativeFee to be the same as _totalNativeFee
// can't use the _totalNativeFee alone because the oapp can use custom workers to force the fee to 0.
// maxNativeFee = max (_totalNativeFee, treasuryNativeFeeCap)
uint256 maxNativeFee = _totalNativeFee > treasuryNativeFeeCap ? _totalNativeFee : treasuryNativeFeeCap;
// min (treasureFeeQuote, nativeFeeCap)
nativeFee = treasureFeeQuote > maxNativeFee ? maxNativeFee : treasureFeeQuote;
}
}
/// @dev authenticated by msg.sender only
function _debitFee(uint256 _amount) internal {
uint256 fee = fees[msg.sender];
if (_amount > fee) revert LZ_MessageLib_InvalidAmount(_amount, fee);
unchecked {
fees[msg.sender] = fee - _amount;
}
}
function _setTreasury(address _treasury) internal {
treasury = _treasury;
emit TreasurySet(_treasury);
}
function _setExecutorConfig(uint32 _remoteEid, address _oapp, ExecutorConfig memory _config) internal {
executorConfigs[_oapp][_remoteEid] = _config;
emit ExecutorConfigSet(_oapp, _remoteEid, _config);
}
// ======================= Virtual =======================
/// @dev these two functions will be overridden with specific logics of the library function
function _quoteVerifier(
address _oapp,
uint32 _eid,
WorkerOptions[] memory _options
) internal view virtual returns (uint256 nativeFee);
/// @dev this function will split the options into executorOptions and validationOptions
function _splitOptions(
bytes calldata _options
) internal view virtual returns (bytes memory executorOptions, WorkerOptions[] memory validationOptions);
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import { ILayerZeroEndpointV2, MessagingFee } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
import { IMessageLib, MessageLibType } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.sol";
import { ISendLib, Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
import { SendLibBase, WorkerOptions, ExecutorConfig } from "./SendLibBase.sol";
/// @dev send-side message library base contract on endpoint v2.
/// design: the high level logic is the same as SendLibBaseE1
/// 1/ with added interfaces
/// 2/ adapt the functions to the new types, like uint32 for eid, address for sender.
abstract contract SendLibBaseE2 is SendLibBase, ERC165, ISendLib {
event NativeFeeWithdrawn(address worker, address receiver, uint256 amount);
event LzTokenFeeWithdrawn(address lzToken, address receiver, uint256 amount);
error LZ_MessageLib_NotTreasury();
error LZ_MessageLib_CannotWithdrawAltToken();
constructor(
address _endpoint,
uint256 _treasuryGasLimit,
uint256 _treasuryNativeFeeCap
) SendLibBase(_endpoint, ILayerZeroEndpointV2(_endpoint).eid(), _treasuryGasLimit, _treasuryNativeFeeCap) {}
function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
_interfaceId == type(IMessageLib).interfaceId ||
_interfaceId == type(ISendLib).interfaceId ||
super.supportsInterface(_interfaceId);
}
// ========================= OnlyEndpoint =========================
// @dev this function is marked as virtual and public for testing purpose
function send(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) public virtual onlyEndpoint returns (MessagingFee memory, bytes memory) {
(bytes memory encodedPacket, uint256 totalNativeFee) = _payWorkers(_packet, _options);
(uint256 treasuryNativeFee, uint256 lzTokenFee) = _payTreasury(
_packet.sender,
_packet.dstEid,
totalNativeFee,
_payInLzToken
);
totalNativeFee += treasuryNativeFee;
return (MessagingFee(totalNativeFee, lzTokenFee), encodedPacket);
}
// ========================= OnlyOwner =========================
function setTreasury(address _treasury) external onlyOwner {
_setTreasury(_treasury);
}
// ========================= External =========================
/// @dev E2 only
function withdrawFee(address _to, uint256 _amount) external {
_debitFee(_amount);
address nativeToken = ILayerZeroEndpointV2(endpoint).nativeToken();
// transfers native if nativeToken == address(0x0)
Transfer.nativeOrToken(nativeToken, _to, _amount);
emit NativeFeeWithdrawn(msg.sender, _to, _amount);
}
/// @dev _lzToken is a user-supplied value because lzToken might change in the endpoint before all lzToken can be taken out
/// @dev E2 only
/// @dev treasury only function
function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external {
if (msg.sender != treasury) revert LZ_MessageLib_NotTreasury();
// lz token cannot be the same as the native token
if (ILayerZeroEndpointV2(endpoint).nativeToken() == _lzToken) revert LZ_MessageLib_CannotWithdrawAltToken();
Transfer.token(_lzToken, _to, _amount);
emit LzTokenFeeWithdrawn(_lzToken, _to, _amount);
}
// ========================= View =========================
function quote(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external view returns (MessagingFee memory) {
(uint256 nativeFee, uint256 lzTokenFee) = _quote(
_packet.sender,
_packet.dstEid,
_packet.message.length,
_payInLzToken,
_options
);
return MessagingFee(nativeFee, lzTokenFee);
}
function messageLibType() external pure virtual override returns (MessageLibType) {
return MessageLibType.Send;
}
// ========================= Internal =========================
/// 1/ handle executor
/// 2/ handle other workers
function _payWorkers(
Packet calldata _packet,
bytes calldata _options
) internal returns (bytes memory encodedPacket, uint256 totalNativeFee) {
// split workers options
(bytes memory executorOptions, WorkerOptions[] memory validationOptions) = _splitOptions(_options);
// handle executor
ExecutorConfig memory config = getExecutorConfig(_packet.sender, _packet.dstEid);
uint256 msgSize = _packet.message.length;
_assertMessageSize(msgSize, config.maxMessageSize);
totalNativeFee += _payExecutor(config.executor, _packet.dstEid, _packet.sender, msgSize, executorOptions);
// handle other workers
(uint256 verifierFee, bytes memory packetBytes) = _payVerifier(_packet, validationOptions); //for ULN, it will be dvns
totalNativeFee += verifierFee;
encodedPacket = packetBytes;
}
// ======================= Virtual =======================
// For implementation to override
function _payVerifier(
Packet calldata _packet,
WorkerOptions[] memory _options
) internal virtual returns (uint256 otherWorkerFees, bytes memory encodedPacket);
// receive native token from endpoint
receive() external payable virtual {}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
// the formal properties are documented in the setter functions
struct UlnConfig {
uint64 confirmations;
// we store the length of required DVNs and optional DVNs instead of using DVN.length directly to save gas
uint8 requiredDVNCount; // 0 indicate DEFAULT, NIL_DVN_COUNT indicate NONE (to override the value of default)
uint8 optionalDVNCount; // 0 indicate DEFAULT, NIL_DVN_COUNT indicate NONE (to override the value of default)
uint8 optionalDVNThreshold; // (0, optionalDVNCount]
address[] requiredDVNs; // no duplicates. sorted an an ascending order. allowed overlap with optionalDVNs
address[] optionalDVNs; // no duplicates. sorted an an ascending order. allowed overlap with requiredDVNs
}
struct SetDefaultUlnConfigParam {
uint32 eid;
UlnConfig config;
}
/// @dev includes the utility functions for checking ULN states and logics
abstract contract UlnBase is Ownable {
address private constant DEFAULT_CONFIG = address(0);
// reserved values for
uint8 internal constant DEFAULT = 0;
uint8 internal constant NIL_DVN_COUNT = type(uint8).max;
uint64 internal constant NIL_CONFIRMATIONS = type(uint64).max;
// 127 to prevent total number of DVNs (127 * 2) exceeding uint8.max (255)
// by limiting the total size, it would help constraint the design of DVNOptions
uint8 private constant MAX_COUNT = (type(uint8).max - 1) / 2;
mapping(address oapp => mapping(uint32 eid => UlnConfig)) internal ulnConfigs;
error LZ_ULN_Unsorted();
error LZ_ULN_InvalidRequiredDVNCount();
error LZ_ULN_InvalidOptionalDVNCount();
error LZ_ULN_AtLeastOneDVN();
error LZ_ULN_InvalidOptionalDVNThreshold();
error LZ_ULN_InvalidConfirmations();
error LZ_ULN_UnsupportedEid(uint32 eid);
event DefaultUlnConfigsSet(SetDefaultUlnConfigParam[] params);
event UlnConfigSet(address oapp, uint32 eid, UlnConfig config);
// ============================ OnlyOwner ===================================
/// @dev about the DEFAULT ULN config
/// 1) its values are all LITERAL (e.g. 0 is 0). whereas in the oapp ULN config, 0 (default value) points to the default ULN config
/// this design enables the oapp to point to DEFAULT config without explicitly setting the config
/// 2) its configuration is more restrictive than the oapp ULN config that
/// a) it must not use NIL value, where NIL is used only by oapps to indicate the LITERAL 0
/// b) it must have at least one DVN
function setDefaultUlnConfigs(SetDefaultUlnConfigParam[] calldata _params) external onlyOwner {
for (uint256 i = 0; i < _params.length; ++i) {
SetDefaultUlnConfigParam calldata param = _params[i];
// 2.a must not use NIL
if (param.config.requiredDVNCount == NIL_DVN_COUNT) revert LZ_ULN_InvalidRequiredDVNCount();
if (param.config.optionalDVNCount == NIL_DVN_COUNT) revert LZ_ULN_InvalidOptionalDVNCount();
if (param.config.confirmations == NIL_CONFIRMATIONS) revert LZ_ULN_InvalidConfirmations();
// 2.b must have at least one dvn
_assertAtLeastOneDVN(param.config);
_setConfig(DEFAULT_CONFIG, param.eid, param.config);
}
emit DefaultUlnConfigsSet(_params);
}
// ============================ View ===================================
// @dev assuming most oapps use default, we get default as memory and custom as storage to save gas
function getUlnConfig(address _oapp, uint32 _remoteEid) public view returns (UlnConfig memory rtnConfig) {
UlnConfig storage defaultConfig = ulnConfigs[DEFAULT_CONFIG][_remoteEid];
UlnConfig storage customConfig = ulnConfigs[_oapp][_remoteEid];
// if confirmations is 0, use default
uint64 confirmations = customConfig.confirmations;
if (confirmations == DEFAULT) {
rtnConfig.confirmations = defaultConfig.confirmations;
} else if (confirmations != NIL_CONFIRMATIONS) {
// if confirmations is uint64.max, no block confirmations required
rtnConfig.confirmations = confirmations;
} // else do nothing, rtnConfig.confirmation is 0
if (customConfig.requiredDVNCount == DEFAULT) {
if (defaultConfig.requiredDVNCount > 0) {
// copy only if count > 0. save gas
rtnConfig.requiredDVNs = defaultConfig.requiredDVNs;
rtnConfig.requiredDVNCount = defaultConfig.requiredDVNCount;
} // else, do nothing
} else {
if (customConfig.requiredDVNCount != NIL_DVN_COUNT) {
rtnConfig.requiredDVNs = customConfig.requiredDVNs;
rtnConfig.requiredDVNCount = customConfig.requiredDVNCount;
} // else, do nothing
}
if (customConfig.optionalDVNCount == DEFAULT) {
if (defaultConfig.optionalDVNCount > 0) {
// copy only if count > 0. save gas
rtnConfig.optionalDVNs = defaultConfig.optionalDVNs;
rtnConfig.optionalDVNCount = defaultConfig.optionalDVNCount;
rtnConfig.optionalDVNThreshold = defaultConfig.optionalDVNThreshold;
}
} else {
if (customConfig.optionalDVNCount != NIL_DVN_COUNT) {
rtnConfig.optionalDVNs = customConfig.optionalDVNs;
rtnConfig.optionalDVNCount = customConfig.optionalDVNCount;
rtnConfig.optionalDVNThreshold = customConfig.optionalDVNThreshold;
}
}
// the final value must have at least one dvn
// it is possible that some default config result into 0 dvns
_assertAtLeastOneDVN(rtnConfig);
}
/// @dev Get the uln config without the default config for the given remoteEid.
function getAppUlnConfig(address _oapp, uint32 _remoteEid) external view returns (UlnConfig memory) {
return ulnConfigs[_oapp][_remoteEid];
}
// ============================ Internal ===================================
function _setUlnConfig(uint32 _remoteEid, address _oapp, UlnConfig memory _param) internal {
_setConfig(_oapp, _remoteEid, _param);
// get ULN config again as a catch all to ensure the config is valid
getUlnConfig(_oapp, _remoteEid);
emit UlnConfigSet(_oapp, _remoteEid, _param);
}
/// @dev a supported Eid must have a valid default uln config, which has at least one dvn
function _isSupportedEid(uint32 _remoteEid) internal view returns (bool) {
UlnConfig storage defaultConfig = ulnConfigs[DEFAULT_CONFIG][_remoteEid];
return defaultConfig.requiredDVNCount > 0 || defaultConfig.optionalDVNThreshold > 0;
}
function _assertSupportedEid(uint32 _remoteEid) internal view {
if (!_isSupportedEid(_remoteEid)) revert LZ_ULN_UnsupportedEid(_remoteEid);
}
// ============================ Private ===================================
function _assertAtLeastOneDVN(UlnConfig memory _config) private pure {
if (_config.requiredDVNCount == 0 && _config.optionalDVNThreshold == 0) revert LZ_ULN_AtLeastOneDVN();
}
/// @dev this private function is used in both setDefaultUlnConfigs and setUlnConfig
function _setConfig(address _oapp, uint32 _eid, UlnConfig memory _param) private {
// @dev required dvns
// if dvnCount == NONE, dvns list must be empty
// if dvnCount == DEFAULT, dvn list must be empty
// otherwise, dvnList.length == dvnCount and assert the list is valid
if (_param.requiredDVNCount == NIL_DVN_COUNT || _param.requiredDVNCount == DEFAULT) {
if (_param.requiredDVNs.length != 0) revert LZ_ULN_InvalidRequiredDVNCount();
} else {
if (_param.requiredDVNs.length != _param.requiredDVNCount || _param.requiredDVNCount > MAX_COUNT)
revert LZ_ULN_InvalidRequiredDVNCount();
_assertNoDuplicates(_param.requiredDVNs);
}
// @dev optional dvns
// if optionalDVNCount == NONE, optionalDVNs list must be empty and threshold must be 0
// if optionalDVNCount == DEFAULT, optionalDVNs list must be empty and threshold must be 0
// otherwise, optionalDVNs.length == optionalDVNCount, threshold > 0 && threshold <= optionalDVNCount and assert the list is valid
// example use case: an oapp uses the DEFAULT 'required' but
// a) use a custom 1/1 dvn (practically a required dvn), or
// b) use a custom 2/3 dvn
if (_param.optionalDVNCount == NIL_DVN_COUNT || _param.optionalDVNCount == DEFAULT) {
if (_param.optionalDVNs.length != 0) revert LZ_ULN_InvalidOptionalDVNCount();
if (_param.optionalDVNThreshold != 0) revert LZ_ULN_InvalidOptionalDVNThreshold();
} else {
if (_param.optionalDVNs.length != _param.optionalDVNCount || _param.optionalDVNCount > MAX_COUNT)
revert LZ_ULN_InvalidOptionalDVNCount();
if (_param.optionalDVNThreshold == 0 || _param.optionalDVNThreshold > _param.optionalDVNCount)
revert LZ_ULN_InvalidOptionalDVNThreshold();
_assertNoDuplicates(_param.optionalDVNs);
}
// don't assert valid count here, as it needs to be validated along side default config
ulnConfigs[_oapp][_eid] = _param;
}
function _assertNoDuplicates(address[] memory _dvns) private pure {
address lastDVN = address(0);
for (uint256 i = 0; i < _dvns.length; i++) {
address dvn = _dvns[i];
if (dvn <= lastDVN) revert LZ_ULN_Unsorted(); // to ensure no duplicates
lastDVN = dvn;
}
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
import { PacketV1Codec } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol";
import { ILayerZeroDVN } from "./interfaces/ILayerZeroDVN.sol";
import { DVNOptions } from "./libs/DVNOptions.sol";
import { UlnOptions } from "./libs/UlnOptions.sol";
import { WorkerOptions } from "../SendLibBase.sol";
import { UlnConfig, UlnBase } from "./UlnBase.sol";
/// @dev includes the utility functions for checking ULN states and logics
abstract contract SendUlnBase is UlnBase {
event DVNFeePaid(address[] requiredDVNs, address[] optionalDVNs, uint256[] fees);
function _splitUlnOptions(bytes calldata _options) internal pure returns (bytes memory, WorkerOptions[] memory) {
(bytes memory executorOpts, bytes memory dvnOpts) = UlnOptions.decode(_options);
if (dvnOpts.length == 0) {
return (executorOpts, new WorkerOptions[](0));
}
WorkerOptions[] memory workerOpts = new WorkerOptions[](1);
workerOpts[0] = WorkerOptions(DVNOptions.WORKER_ID, dvnOpts);
return (executorOpts, workerOpts);
}
/// ---------- pay and assign jobs ----------
function _payDVNs(
mapping(address => uint256) storage _fees,
Packet memory _packet,
WorkerOptions[] memory _options
) internal returns (uint256 totalFee, bytes memory encodedPacket) {
bytes memory packetHeader = PacketV1Codec.encodePacketHeader(_packet);
bytes memory payload = PacketV1Codec.encodePayload(_packet);
bytes32 payloadHash = keccak256(payload);
uint32 dstEid = _packet.dstEid;
address sender = _packet.sender;
UlnConfig memory config = getUlnConfig(sender, dstEid);
// if options is not empty, it must be dvn options
bytes memory dvnOptions = _options.length == 0 ? bytes("") : _options[0].options;
uint256[] memory dvnFees;
(totalFee, dvnFees) = _assignJobs(
_fees,
config,
ILayerZeroDVN.AssignJobParam(dstEid, packetHeader, payloadHash, config.confirmations, sender),
dvnOptions
);
encodedPacket = abi.encodePacked(packetHeader, payload);
emit DVNFeePaid(config.requiredDVNs, config.optionalDVNs, dvnFees);
}
function _assignJobs(
mapping(address => uint256) storage _fees,
UlnConfig memory _ulnConfig,
ILayerZeroDVN.AssignJobParam memory _param,
bytes memory dvnOptions
) internal returns (uint256 totalFee, uint256[] memory dvnFees) {
(bytes[] memory optionsArray, uint8[] memory dvnIds) = DVNOptions.groupDVNOptionsByIdx(dvnOptions);
uint8 dvnsLength = _ulnConfig.requiredDVNCount + _ulnConfig.optionalDVNCount;
dvnFees = new uint256[](dvnsLength);
for (uint8 i = 0; i < dvnsLength; ++i) {
address dvn = i < _ulnConfig.requiredDVNCount
? _ulnConfig.requiredDVNs[i]
: _ulnConfig.optionalDVNs[i - _ulnConfig.requiredDVNCount];
bytes memory options = "";
for (uint256 j = 0; j < dvnIds.length; ++j) {
if (dvnIds[j] == i) {
options = optionsArray[j];
break;
}
}
dvnFees[i] = ILayerZeroDVN(dvn).assignJob(_param, options);
if (dvnFees[i] > 0) {
_fees[dvn] += dvnFees[i];
totalFee += dvnFees[i];
}
}
}
/// ---------- quote ----------
function _quoteDVNs(
address _sender,
uint32 _dstEid,
WorkerOptions[] memory _options
) internal view returns (uint256 totalFee) {
UlnConfig memory config = getUlnConfig(_sender, _dstEid);
// if options is not empty, it must be dvn options
bytes memory dvnOptions = _options.length == 0 ? bytes("") : _options[0].options;
(bytes[] memory optionsArray, uint8[] memory dvnIndices) = DVNOptions.groupDVNOptionsByIdx(dvnOptions);
totalFee = _getFees(config, _dstEid, _sender, optionsArray, dvnIndices);
}
function _getFees(
UlnConfig memory _config,
uint32 _dstEid,
address _sender,
bytes[] memory _optionsArray,
uint8[] memory _dvnIds
) internal view returns (uint256 totalFee) {
// here we merge 2 list of dvns into 1 to allocate the indexed dvn options to the right dvn
uint8 dvnsLength = _config.requiredDVNCount + _config.optionalDVNCount;
for (uint8 i = 0; i < dvnsLength; ++i) {
address dvn = i < _config.requiredDVNCount
? _config.requiredDVNs[i]
: _config.optionalDVNs[i - _config.requiredDVNCount];
bytes memory options = "";
// it is a double loop here. however, if the list is short, the cost is very acceptable.
for (uint256 j = 0; j < _dvnIds.length; ++j) {
if (_dvnIds[j] == i) {
options = _optionsArray[j];
break;
}
}
totalFee += ILayerZeroDVN(dvn).getFee(_dstEid, _config.confirmations, _sender, options);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
struct SetConfigParam {
uint32 eid;
uint32 configType;
bytes config;
}
interface IMessageLibManager {
struct Timeout {
address lib;
uint256 expiry;
}
event LibraryRegistered(address newLib);
event DefaultSendLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);
event SendLibrarySet(address sender, uint32 eid, address newLib);
event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);
event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);
function registerLibrary(address _lib) external;
function isRegisteredLibrary(address _lib) external view returns (bool);
function getRegisteredLibraries() external view returns (address[] memory);
function setDefaultSendLibrary(uint32 _eid, address _newLib) external;
function defaultSendLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external;
function defaultReceiveLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;
function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);
function isSupportedEid(uint32 _eid) external view returns (bool);
function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);
/// ------------------- OApp interfaces -------------------
function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;
function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);
function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);
function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;
function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);
function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external;
function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);
function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;
function getConfig(
address _oapp,
address _lib,
uint32 _eid,
uint32 _configType
) external view returns (bytes memory config);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import { MessagingFee } from "./ILayerZeroEndpointV2.sol";
import { IMessageLib } from "./IMessageLib.sol";
struct Packet {
uint64 nonce;
uint32 srcEid;
address sender;
uint32 dstEid;
bytes32 receiver;
bytes32 guid;
bytes message;
}
interface ISendLib is IMessageLib {
function send(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external returns (MessagingFee memory, bytes memory encodedPacket);
function quote(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external view returns (MessagingFee memory);
function setTreasury(address _treasury) external;
function withdrawFee(address _to, uint256 _amount) external;
function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external;
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
/// @dev simply a container of endpoint address and local eid
abstract contract MessageLibBase {
address internal immutable endpoint;
uint32 internal immutable localEid;
error LZ_MessageLib_OnlyEndpoint();
modifier onlyEndpoint() {
if (endpoint != msg.sender) revert LZ_MessageLib_OnlyEndpoint();
_;
}
constructor(address _endpoint, uint32 _localEid) {
endpoint = _endpoint;
localEid = _localEid;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface ILayerZeroTreasury {
function getFee(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) external view returns (uint256 fee);
function payFee(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) external payable returns (uint256 fee);
}// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.20;
/// @dev copied from https://github.com/nomad-xyz/ExcessivelySafeCall/blob/main/src/ExcessivelySafeCall.sol.
library SafeCall {
/// @notice calls a contract with a specified gas limit and value and captures the return data
/// @param _target The address to call
/// @param _gas The amount of gas to forward to the remote contract
/// @param _value The value in wei to send to the remote contract
/// to memory.
/// @param _maxCopy The maximum number of bytes of returndata to copy
/// to memory.
/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function safeCall(
address _target,
uint256 _gas,
uint256 _value,
uint16 _maxCopy,
bytes memory _calldata
) internal returns (bool, bytes memory) {
// check that target has code
uint size;
assembly {
size := extcodesize(_target)
}
if (size == 0) {
return (false, new bytes(0));
}
// set up for assembly call
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
_success := call(
_gas, // gas
_target, // recipient
_value, // ether value
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
// limit our copy to 100 bytes
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
// Store the length of the copied bytes
mstore(_returnData, _toCopy)
// copy the bytes from returndata[0:_toCopy]
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
/// @notice Use when you _really_ really _really_ don't trust the called
/// contract. This prevents the called contract from causing reversion of
/// the caller in as many ways as we can.
/// @dev The main difference between this and a solidity low-level call is
/// that we limit the number of bytes that the callee can cause to be
/// copied to caller memory. This prevents stupid things like malicious
/// contracts returning 10,000,000 bytes causing a local OOG when copying
/// to memory.
/// @param _target The address to call
/// @param _gas The amount of gas to forward to the remote contract
/// @param _maxCopy The maximum number of bytes of returndata to copy
/// to memory.
/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function safeStaticCall(
address _target,
uint256 _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal view returns (bool, bytes memory) {
// check that target has code
uint size;
assembly {
size := extcodesize(_target)
}
if (size == 0) {
return (false, new bytes(0));
}
// set up for assembly call
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
_success := staticcall(
_gas, // gas
_target, // recipient
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
// limit our copy to 256 bytes
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
// Store the length of the copied bytes
mstore(_returnData, _toCopy)
// copy the bytes from returndata[0:_toCopy]
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface ILayerZeroExecutor {
// @notice query price and assign jobs at the same time
// @param _dstEid - the destination endpoint identifier
// @param _sender - the source sending contract address. executors may apply price discrimination to senders
// @param _calldataSize - dynamic data size of message + caller params
// @param _options - optional parameters for extra service plugins, e.g. sending dust tokens at the destination chain
function assignJob(
uint32 _dstEid,
address _sender,
uint256 _calldataSize,
bytes calldata _options
) external returns (uint256 price);
// @notice query the executor price for relaying the payload and its proof to the destination chain
// @param _dstEid - the destination endpoint identifier
// @param _sender - the source sending contract address. executors may apply price discrimination to senders
// @param _calldataSize - dynamic data size of message + caller params
// @param _options - optional parameters for extra service plugins, e.g. sending dust tokens at the destination chain
function getFee(
uint32 _dstEid,
address _sender,
uint256 _calldataSize,
bytes calldata _options
) external view returns (uint256 price);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface ILayerZeroDVN {
struct AssignJobParam {
uint32 dstEid;
bytes packetHeader;
bytes32 payloadHash;
uint64 confirmations;
address sender;
}
// @notice query price and assign jobs at the same time
// @param _dstEid - the destination endpoint identifier
// @param _packetHeader - version + nonce + path
// @param _payloadHash - hash of guid + message
// @param _confirmations - block confirmation delay before relaying blocks
// @param _sender - the source sending contract address
// @param _options - options
function assignJob(AssignJobParam calldata _param, bytes calldata _options) external payable returns (uint256 fee);
// @notice query the dvn fee for relaying block information to the destination chain
// @param _dstEid the destination endpoint identifier
// @param _confirmations - block confirmation delay before relaying blocks
// @param _sender - the source sending contract address
// @param _options - options
function getFee(
uint32 _dstEid,
uint64 _confirmations,
address _sender,
bytes calldata _options
) external view returns (uint256 fee);
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import { ExecutorOptions } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/ExecutorOptions.sol";
import { DVNOptions } from "./DVNOptions.sol";
library UlnOptions {
using SafeCast for uint256;
uint16 internal constant TYPE_1 = 1; // legacy options type 1
uint16 internal constant TYPE_2 = 2; // legacy options type 2
uint16 internal constant TYPE_3 = 3;
error LZ_ULN_InvalidWorkerOptions(uint256 cursor);
error LZ_ULN_InvalidWorkerId(uint8 workerId);
error LZ_ULN_InvalidLegacyType1Option();
error LZ_ULN_InvalidLegacyType2Option();
error LZ_ULN_UnsupportedOptionType(uint16 optionType);
/// @dev decode the options into executorOptions and dvnOptions
/// @param _options the options can be either legacy options (type 1 or 2) or type 3 options
/// @return executorOptions the executor options, share the same format of type 3 options
/// @return dvnOptions the dvn options, share the same format of type 3 options
function decode(
bytes calldata _options
) internal pure returns (bytes memory executorOptions, bytes memory dvnOptions) {
// at least 2 bytes for the option type, but can have no options
if (_options.length < 2) revert LZ_ULN_InvalidWorkerOptions(0);
uint16 optionsType = uint16(bytes2(_options[0:2]));
uint256 cursor = 2;
// type3 options: [worker_option][worker_option]...
// worker_option: [worker_id][option_size][option]
// worker_id: uint8, option_size: uint16, option: bytes
if (optionsType == TYPE_3) {
unchecked {
uint256 start = cursor;
uint8 lastWorkerId; // worker_id starts from 1, so 0 is an invalid worker_id
// heuristic: we assume that the options are mostly EXECUTOR options only
// checking the workerID can reduce gas usage for most cases
while (cursor < _options.length) {
uint8 workerId = uint8(bytes1(_options[cursor:cursor + 1]));
if (workerId == 0) revert LZ_ULN_InvalidWorkerId(0);
// workerId must equal to the lastWorkerId for the first option
// so it is always skipped in the first option
// this operation slices out options whenever the the scan finds a different workerId
if (lastWorkerId == 0) {
lastWorkerId = workerId;
} else if (workerId != lastWorkerId) {
bytes calldata op = _options[start:cursor]; // slice out the last worker's options
(executorOptions, dvnOptions) = _insertWorkerOptions(
executorOptions,
dvnOptions,
lastWorkerId,
op
);
// reset the start cursor and lastWorkerId
start = cursor;
lastWorkerId = workerId;
}
++cursor; // for workerId
uint16 size = uint16(bytes2(_options[cursor:cursor + 2]));
if (size == 0) revert LZ_ULN_InvalidWorkerOptions(cursor);
cursor += size + 2;
}
// the options length must be the same as the cursor at the end
if (cursor != _options.length) revert LZ_ULN_InvalidWorkerOptions(cursor);
// if we have reached the end of the options and the options are not empty
// we need to process the last worker's options
if (_options.length > 2) {
bytes calldata op = _options[start:cursor];
(executorOptions, dvnOptions) = _insertWorkerOptions(executorOptions, dvnOptions, lastWorkerId, op);
}
}
} else {
executorOptions = decodeLegacyOptions(optionsType, _options);
}
}
function _insertWorkerOptions(
bytes memory _executorOptions,
bytes memory _dvnOptions,
uint8 _workerId,
bytes calldata _newOptions
) private pure returns (bytes memory, bytes memory) {
if (_workerId == ExecutorOptions.WORKER_ID) {
_executorOptions = _executorOptions.length == 0
? _newOptions
: abi.encodePacked(_executorOptions, _newOptions);
} else if (_workerId == DVNOptions.WORKER_ID) {
_dvnOptions = _dvnOptions.length == 0 ? _newOptions : abi.encodePacked(_dvnOptions, _newOptions);
} else {
revert LZ_ULN_InvalidWorkerId(_workerId);
}
return (_executorOptions, _dvnOptions);
}
/// @dev decode the legacy options (type 1 or 2) into executorOptions
/// @param _optionType the legacy option type
/// @param _options the legacy options, which still has the option type in the first 2 bytes
/// @return executorOptions the executor options, share the same format of type 3 options
/// Data format:
/// legacy type 1: [extraGas]
/// legacy type 2: [extraGas][dstNativeAmt][dstNativeAddress]
/// extraGas: uint256, dstNativeAmt: uint256, dstNativeAddress: bytes
function decodeLegacyOptions(
uint16 _optionType,
bytes calldata _options
) internal pure returns (bytes memory executorOptions) {
if (_optionType == TYPE_1) {
if (_options.length != 34) revert LZ_ULN_InvalidLegacyType1Option();
// execution gas
uint128 executionGas = uint256(bytes32(_options[2:2 + 32])).toUint128();
// dont use the encode function in the ExecutorOptions lib for saving gas by calling abi.encodePacked once
// the result is a lzReceive option: [executor_id][option_size][option_type][execution_gas]
// option_type: uint8, execution_gas: uint128
// option_size = len(option_type) + len(execution_gas) = 1 + 16 = 17
executorOptions = abi.encodePacked(
ExecutorOptions.WORKER_ID,
uint16(17), // 16 + 1, 16 for option_length, + 1 for option_type
ExecutorOptions.OPTION_TYPE_LZRECEIVE,
executionGas
);
} else if (_optionType == TYPE_2) {
// receiver size <= 32
if (_options.length <= 66 || _options.length > 98) revert LZ_ULN_InvalidLegacyType2Option();
// execution gas
uint128 executionGas = uint256(bytes32(_options[2:2 + 32])).toUint128();
// nativeDrop (amount + receiver)
uint128 amount = uint256(bytes32(_options[34:34 + 32])).toUint128(); // offset 2 + 32
bytes32 receiver;
unchecked {
uint256 receiverLen = _options.length - 66; // offset 2 + 32 + 32
receiver = bytes32(_options[66:]);
receiver = receiver >> (8 * (32 - receiverLen)); // padding 0 to the left
}
// dont use the encode function in the ExecutorOptions lib for saving gas by calling abi.encodePacked once
// the result has one lzReceive option and one nativeDrop option:
// [executor_id][lzReceive_option_size][option_type][execution_gas] +
// [executor_id][nativeDrop_option_size][option_type][nativeDrop_amount][receiver]
// option_type: uint8, execution_gas: uint128, nativeDrop_amount: uint128, receiver: bytes32
// lzReceive_option_size = len(option_type) + len(execution_gas) = 1 + 16 = 17
// nativeDrop_option_size = len(option_type) + len(nativeDrop_amount) + len(receiver) = 1 + 16 + 32 = 49
executorOptions = abi.encodePacked(
ExecutorOptions.WORKER_ID,
uint16(17), // 16 + 1, 16 for option_length, + 1 for option_type
ExecutorOptions.OPTION_TYPE_LZRECEIVE,
executionGas,
ExecutorOptions.WORKER_ID,
uint16(49), // 48 + 1, 32 + 16 for option_length, + 1 for option_type
ExecutorOptions.OPTION_TYPE_NATIVE_DROP,
amount,
receiver
);
} else {
revert LZ_ULN_UnsupportedOptionType(_optionType);
}
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { BytesLib } from "solidity-bytes-utils/contracts/BytesLib.sol";
import { BitMap256 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol";
import { CalldataBytesLib } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol";
library DVNOptions {
using CalldataBytesLib for bytes;
using BytesLib for bytes;
uint8 internal constant WORKER_ID = 2;
uint8 internal constant OPTION_TYPE_PRECRIME = 1;
error DVN_InvalidDVNIdx();
error DVN_InvalidDVNOptions(uint256 cursor);
/// @dev group dvn options by its idx
/// @param _options [dvn_id][dvn_option][dvn_id][dvn_option]...
/// dvn_option = [option_size][dvn_idx][option_type][option]
/// option_size = len(dvn_idx) + len(option_type) + len(option)
/// dvn_id: uint8, dvn_idx: uint8, option_size: uint16, option_type: uint8, option: bytes
/// @return dvnOptions the grouped options, still share the same format of _options
/// @return dvnIndices the dvn indices
function groupDVNOptionsByIdx(
bytes memory _options
) internal pure returns (bytes[] memory dvnOptions, uint8[] memory dvnIndices) {
if (_options.length == 0) return (dvnOptions, dvnIndices);
uint8 numDVNs = getNumDVNs(_options);
// if there is only 1 dvn, we can just return the whole options
if (numDVNs == 1) {
dvnOptions = new bytes[](1);
dvnOptions[0] = _options;
dvnIndices = new uint8[](1);
dvnIndices[0] = _options.toUint8(3); // dvn idx
return (dvnOptions, dvnIndices);
}
// otherwise, we need to group the options by dvn_idx
dvnIndices = new uint8[](numDVNs);
dvnOptions = new bytes[](numDVNs);
unchecked {
uint256 cursor = 0;
uint256 start = 0;
uint8 lastDVNIdx = 255; // 255 is an invalid dvn_idx
while (cursor < _options.length) {
++cursor; // skip worker_id
// optionLength asserted in getNumDVNs (skip check)
uint16 optionLength = _options.toUint16(cursor);
cursor += 2;
// dvnIdx asserted in getNumDVNs (skip check)
uint8 dvnIdx = _options.toUint8(cursor);
// dvnIdx must equal to the lastDVNIdx for the first option
// so it is always skipped in the first option
// this operation slices out options whenever the scan finds a different lastDVNIdx
if (lastDVNIdx == 255) {
lastDVNIdx = dvnIdx;
} else if (dvnIdx != lastDVNIdx) {
uint256 len = cursor - start - 3; // 3 is for worker_id and option_length
bytes memory opt = _options.slice(start, len);
_insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, opt);
// reset the start and lastDVNIdx
start += len;
lastDVNIdx = dvnIdx;
}
cursor += optionLength;
}
// skip check the cursor here because the cursor is asserted in getNumDVNs
// if we have reached the end of the options, we need to process the last dvn
uint256 size = cursor - start;
bytes memory op = _options.slice(start, size);
_insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, op);
// revert dvnIndices to start from 0
for (uint8 i = 0; i < numDVNs; ++i) {
--dvnIndices[i];
}
}
}
function _insertDVNOptions(
bytes[] memory _dvnOptions,
uint8[] memory _dvnIndices,
uint8 _dvnIdx,
bytes memory _newOptions
) internal pure {
// dvnIdx starts from 0 but default value of dvnIndices is 0,
// so we tell if the slot is empty by adding 1 to dvnIdx
if (_dvnIdx == 255) revert DVN_InvalidDVNIdx();
uint8 dvnIdxAdj = _dvnIdx + 1;
for (uint256 j = 0; j < _dvnIndices.length; ++j) {
uint8 index = _dvnIndices[j];
if (dvnIdxAdj == index) {
_dvnOptions[j] = abi.encodePacked(_dvnOptions[j], _newOptions);
break;
} else if (index == 0) {
// empty slot, that means it is the first time we see this dvn
_dvnIndices[j] = dvnIdxAdj;
_dvnOptions[j] = _newOptions;
break;
}
}
}
/// @dev get the number of unique dvns
/// @param _options the format is the same as groupDVNOptionsByIdx
function getNumDVNs(bytes memory _options) internal pure returns (uint8 numDVNs) {
uint256 cursor = 0;
BitMap256 bitmap;
// find number of unique dvn_idx
unchecked {
while (cursor < _options.length) {
++cursor; // skip worker_id
uint16 optionLength = _options.toUint16(cursor);
cursor += 2;
if (optionLength < 2) revert DVN_InvalidDVNOptions(cursor); // at least 1 byte for dvn_idx and 1 byte for option_type
uint8 dvnIdx = _options.toUint8(cursor);
// if dvnIdx is not set, increment numDVNs
// max num of dvns is 255, 255 is an invalid dvn_idx
// The order of the dvnIdx is not required to be sequential, as enforcing the order may weaken
// the composability of the options. e.g. if we refrain from enforcing the order, an OApp that has
// already enforced certain options can append additional options to the end of the enforced
// ones without restrictions.
if (dvnIdx == 255) revert DVN_InvalidDVNIdx();
if (!bitmap.get(dvnIdx)) {
++numDVNs;
bitmap = bitmap.set(dvnIdx);
}
cursor += optionLength;
}
}
if (cursor != _options.length) revert DVN_InvalidDVNOptions(cursor);
}
/// @dev decode the next dvn option from _options starting from the specified cursor
/// @param _options the format is the same as groupDVNOptionsByIdx
/// @param _cursor the cursor to start decoding
/// @return optionType the type of the option
/// @return option the option
/// @return cursor the cursor to start decoding the next option
function nextDVNOption(
bytes calldata _options,
uint256 _cursor
) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {
unchecked {
// skip worker id
cursor = _cursor + 1;
// read option size
uint16 size = _options.toU16(cursor);
cursor += 2;
// read option type
optionType = _options.toU8(cursor + 1); // skip dvn_idx
// startCursor and endCursor are used to slice the option from _options
uint256 startCursor = cursor + 2; // skip option type and dvn_idx
uint256 endCursor = cursor + size;
option = _options[startCursor:endCursor];
cursor += size;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
library Transfer {
using SafeERC20 for IERC20;
address internal constant ADDRESS_ZERO = address(0);
error Transfer_NativeFailed(address _to, uint256 _value);
error Transfer_ToAddressIsZero();
function native(address _to, uint256 _value) internal {
if (_to == ADDRESS_ZERO) revert Transfer_ToAddressIsZero();
(bool success, ) = _to.call{ value: _value }("");
if (!success) revert Transfer_NativeFailed(_to, _value);
}
function token(address _token, address _to, uint256 _value) internal {
if (_to == ADDRESS_ZERO) revert Transfer_ToAddressIsZero();
IERC20(_token).safeTransfer(_to, _value);
}
function nativeOrToken(address _token, address _to, uint256 _value) internal {
if (_token == ADDRESS_ZERO) {
native(_to, _value);
} else {
token(_token, _to, _value);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import { IMessageLibManager } from "./IMessageLibManager.sol";
import { IMessagingComposer } from "./IMessagingComposer.sol";
import { IMessagingChannel } from "./IMessagingChannel.sol";
import { IMessagingContext } from "./IMessagingContext.sol";
struct MessagingParams {
uint32 dstEid;
bytes32 receiver;
bytes message;
bytes options;
bool payInLzToken;
}
struct MessagingReceipt {
bytes32 guid;
uint64 nonce;
MessagingFee fee;
}
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct Origin {
uint32 srcEid;
bytes32 sender;
uint64 nonce;
}
interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);
event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);
event PacketDelivered(Origin origin, address receiver);
event LzReceiveAlert(
address indexed receiver,
address indexed executor,
Origin origin,
bytes32 guid,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
event LzTokenSet(address token);
event DelegateSet(address sender, address delegate);
function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);
function send(
MessagingParams calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt memory);
function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;
function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);
function initializable(Origin calldata _origin, address _receiver) external view returns (bool);
function lzReceive(
Origin calldata _origin,
address _receiver,
bytes32 _guid,
bytes calldata _message,
bytes calldata _extraData
) external payable;
// oapp can burn messages partially by calling this function with its own business logic if messages are verified in order
function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;
function setLzToken(address _lzToken) external;
function lzToken() external view returns (address);
function nativeToken() external view returns (address);
function setDelegate(address _delegate) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { SetConfigParam } from "./IMessageLibManager.sol";
enum MessageLibType {
Send,
Receive,
SendAndReceive
}
interface IMessageLib is IERC165 {
function setConfig(address _oapp, SetConfigParam[] calldata _config) external;
function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config);
function isSupportedEid(uint32 _eid) external view returns (bool);
// message libs of same major version are compatible
function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion);
function messageLibType() external view returns (MessageLibType);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { Packet } from "../../interfaces/ISendLib.sol";
import { AddressCast } from "../../libs/AddressCast.sol";
library PacketV1Codec {
using AddressCast for address;
using AddressCast for bytes32;
uint8 internal constant PACKET_VERSION = 1;
// header (version + nonce + path)
// version
uint256 private constant PACKET_VERSION_OFFSET = 0;
// nonce
uint256 private constant NONCE_OFFSET = 1;
// path
uint256 private constant SRC_EID_OFFSET = 9;
uint256 private constant SENDER_OFFSET = 13;
uint256 private constant DST_EID_OFFSET = 45;
uint256 private constant RECEIVER_OFFSET = 49;
// payload (guid + message)
uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path)
uint256 private constant MESSAGE_OFFSET = 113;
function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) {
encodedPacket = abi.encodePacked(
PACKET_VERSION,
_packet.nonce,
_packet.srcEid,
_packet.sender.toBytes32(),
_packet.dstEid,
_packet.receiver,
_packet.guid,
_packet.message
);
}
function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) {
return
abi.encodePacked(
PACKET_VERSION,
_packet.nonce,
_packet.srcEid,
_packet.sender.toBytes32(),
_packet.dstEid,
_packet.receiver
);
}
function encodePayload(Packet memory _packet) internal pure returns (bytes memory) {
return abi.encodePacked(_packet.guid, _packet.message);
}
function header(bytes calldata _packet) internal pure returns (bytes calldata) {
return _packet[0:GUID_OFFSET];
}
function version(bytes calldata _packet) internal pure returns (uint8) {
return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET]));
}
function nonce(bytes calldata _packet) internal pure returns (uint64) {
return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET]));
}
function srcEid(bytes calldata _packet) internal pure returns (uint32) {
return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET]));
}
function sender(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]);
}
function senderAddressB20(bytes calldata _packet) internal pure returns (address) {
return sender(_packet).toAddress();
}
function dstEid(bytes calldata _packet) internal pure returns (uint32) {
return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET]));
}
function receiver(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]);
}
function receiverB20(bytes calldata _packet) internal pure returns (address) {
return receiver(_packet).toAddress();
}
function guid(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]);
}
function message(bytes calldata _packet) internal pure returns (bytes calldata) {
return bytes(_packet[MESSAGE_OFFSET:]);
}
function payload(bytes calldata _packet) internal pure returns (bytes calldata) {
return bytes(_packet[GUID_OFFSET:]);
}
function payloadHash(bytes calldata _packet) internal pure returns (bytes32) {
return keccak256(payload(_packet));
}
}// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
library CalldataBytesLib {
function toU8(bytes calldata _bytes, uint256 _start) internal pure returns (uint8) {
return uint8(_bytes[_start]);
}
function toU16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16) {
unchecked {
uint256 end = _start + 2;
return uint16(bytes2(_bytes[_start:end]));
}
}
function toU32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32) {
unchecked {
uint256 end = _start + 4;
return uint32(bytes4(_bytes[_start:end]));
}
}
function toU64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64) {
unchecked {
uint256 end = _start + 8;
return uint64(bytes8(_bytes[_start:end]));
}
}
function toU128(bytes calldata _bytes, uint256 _start) internal pure returns (uint128) {
unchecked {
uint256 end = _start + 16;
return uint128(bytes16(_bytes[_start:end]));
}
}
function toU256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256) {
unchecked {
uint256 end = _start + 32;
return uint256(bytes32(_bytes[_start:end]));
}
}
function toAddr(bytes calldata _bytes, uint256 _start) internal pure returns (address) {
unchecked {
uint256 end = _start + 20;
return address(bytes20(_bytes[_start:end]));
}
}
function toB32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32) {
unchecked {
uint256 end = _start + 32;
return bytes32(_bytes[_start:end]);
}
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { CalldataBytesLib } from "../../libs/CalldataBytesLib.sol";
library ExecutorOptions {
using CalldataBytesLib for bytes;
uint8 internal constant WORKER_ID = 1;
uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;
uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2;
uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3;
uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4;
error Executor_InvalidLzReceiveOption();
error Executor_InvalidNativeDropOption();
error Executor_InvalidLzComposeOption();
/// @dev decode the next executor option from the options starting from the specified cursor
/// @param _options [executor_id][executor_option][executor_id][executor_option]...
/// executor_option = [option_size][option_type][option]
/// option_size = len(option_type) + len(option)
/// executor_id: uint8, option_size: uint16, option_type: uint8, option: bytes
/// @param _cursor the cursor to start decoding from
/// @return optionType the type of the option
/// @return option the option of the executor
/// @return cursor the cursor to start decoding the next executor option
function nextExecutorOption(
bytes calldata _options,
uint256 _cursor
) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {
unchecked {
// skip worker id
cursor = _cursor + 1;
// read option size
uint16 size = _options.toU16(cursor);
cursor += 2;
// read option type
optionType = _options.toU8(cursor);
// startCursor and endCursor are used to slice the option from _options
uint256 startCursor = cursor + 1; // skip option type
uint256 endCursor = cursor + size;
option = _options[startCursor:endCursor];
cursor += size;
}
}
function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) {
if (_option.length != 16 && _option.length != 32) revert Executor_InvalidLzReceiveOption();
gas = _option.toU128(0);
value = _option.length == 32 ? _option.toU128(16) : 0;
}
function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) {
if (_option.length != 48) revert Executor_InvalidNativeDropOption();
amount = _option.toU128(0);
receiver = _option.toB32(16);
}
function decodeLzComposeOption(
bytes calldata _option
) internal pure returns (uint16 index, uint128 gas, uint128 value) {
if (_option.length != 18 && _option.length != 34) revert Executor_InvalidLzComposeOption();
index = _option.toU16(0);
gas = _option.toU128(2);
value = _option.length == 34 ? _option.toU128(18) : 0;
}
function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) {
return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value);
}
function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) {
return abi.encodePacked(_amount, _receiver);
}
function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) {
return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value);
}
}// SPDX-License-Identifier: MIT
// modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol
pragma solidity ^0.8.20;
type BitMap256 is uint256;
using BitMaps for BitMap256 global;
library BitMaps {
/**
* @dev Returns whether the bit at `index` is set.
*/
function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) {
uint256 mask = 1 << index;
return BitMap256.unwrap(bitmap) & mask != 0;
}
/**
* @dev Sets the bit at `index`.
*/
function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) {
uint256 mask = 1 << index;
return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IMessagingComposer {
event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);
event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);
event LzComposeAlert(
address indexed from,
address indexed to,
address indexed executor,
bytes32 guid,
uint16 index,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
function composeQueue(
address _from,
address _to,
bytes32 _guid,
uint16 _index
) external view returns (bytes32 messageHash);
function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;
function lzCompose(
address _from,
address _to,
bytes32 _guid,
uint16 _index,
bytes calldata _message,
bytes calldata _extraData
) external payable;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IMessagingChannel {
event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);
event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
function eid() external view returns (uint32);
// this is an emergency function if a message cannot be verified for some reasons
// required to provide _nextNonce to avoid race condition
function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;
function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);
function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);
function inboundPayloadHash(
address _receiver,
uint32 _srcEid,
bytes32 _sender,
uint64 _nonce
) external view returns (bytes32);
function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IMessagingContext {
function isSendingMessage() external view returns (bool);
function getSendContext() external view returns (uint32 dstEid, address sender);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
library AddressCast {
error AddressCast_InvalidSizeForAddress();
error AddressCast_InvalidAddress();
function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) {
if (_addressBytes.length > 32) revert AddressCast_InvalidAddress();
result = bytes32(_addressBytes);
unchecked {
uint256 offset = 32 - _addressBytes.length;
result = result >> (offset * 8);
}
}
function toBytes32(address _address) internal pure returns (bytes32 result) {
result = bytes32(uint256(uint160(_address)));
}
function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) {
if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress();
result = new bytes(_size);
unchecked {
uint256 offset = 256 - _size * 8;
assembly {
mstore(add(result, 32), shl(offset, _addressBytes32))
}
}
}
function toAddress(bytes32 _addressBytes32) internal pure returns (address result) {
result = address(uint160(uint256(_addressBytes32)));
}
function toAddress(bytes calldata _addressBytes) internal pure returns (address result) {
if (_addressBytes.length != 20) revert AddressCast_InvalidAddress();
result = address(bytes20(_addressBytes));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}{
"optimizer": {
"enabled": true,
"mode": "3"
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"abi"
]
}
},
"libraries": {},
"isSystem": false,
"forceEvmla": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"uint256","name":"_treasuryGasLimit","type":"uint256"},{"internalType":"uint256","name":"_treasuryGasForFeeCap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DVN_InvalidDVNIdx","type":"error"},{"inputs":[{"internalType":"uint256","name":"cursor","type":"uint256"}],"name":"DVN_InvalidDVNOptions","type":"error"},{"inputs":[],"name":"LZ_MessageLib_CannotWithdrawAltToken","type":"error"},{"inputs":[{"internalType":"uint256","name":"requested","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"LZ_MessageLib_InvalidAmount","type":"error"},{"inputs":[],"name":"LZ_MessageLib_InvalidExecutor","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"LZ_MessageLib_InvalidMessageSize","type":"error"},{"inputs":[],"name":"LZ_MessageLib_NotTreasury","type":"error"},{"inputs":[],"name":"LZ_MessageLib_OnlyEndpoint","type":"error"},{"inputs":[],"name":"LZ_MessageLib_TransferFailed","type":"error"},{"inputs":[],"name":"LZ_MessageLib_ZeroMessageSize","type":"error"},{"inputs":[],"name":"LZ_ULN_AtLeastOneDVN","type":"error"},{"inputs":[{"internalType":"uint32","name":"configType","type":"uint32"}],"name":"LZ_ULN_InvalidConfigType","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidConfirmations","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidLegacyType1Option","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidLegacyType2Option","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidOptionalDVNCount","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidOptionalDVNThreshold","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidRequiredDVNCount","type":"error"},{"inputs":[{"internalType":"uint8","name":"workerId","type":"uint8"}],"name":"LZ_ULN_InvalidWorkerId","type":"error"},{"inputs":[{"internalType":"uint256","name":"cursor","type":"uint256"}],"name":"LZ_ULN_InvalidWorkerOptions","type":"error"},{"inputs":[],"name":"LZ_ULN_Unsorted","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"LZ_ULN_UnsupportedEid","type":"error"},{"inputs":[{"internalType":"uint16","name":"optionType","type":"uint16"}],"name":"LZ_ULN_UnsupportedOptionType","type":"error"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer_NativeFailed","type":"error"},{"inputs":[],"name":"Transfer_ToAddressIsZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"optionalDVNs","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"fees","type":"uint256[]"}],"name":"DVNFeePaid","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct ExecutorConfig","name":"config","type":"tuple"}],"indexed":false,"internalType":"struct SetDefaultExecutorConfigParam[]","name":"params","type":"tuple[]"}],"name":"DefaultExecutorConfigsSet","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"config","type":"tuple"}],"indexed":false,"internalType":"struct SetDefaultUlnConfigParam[]","name":"params","type":"tuple[]"}],"name":"DefaultUlnConfigsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oapp","type":"address"},{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"indexed":false,"internalType":"struct ExecutorConfig","name":"config","type":"tuple"}],"name":"ExecutorConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ExecutorFeePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lzToken","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LzTokenFeeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"worker","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeFeeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTreasuryNativeFeeCap","type":"uint256"}],"name":"TreasuryNativeFeeCapSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"TreasurySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oapp","type":"address"},{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"indexed":false,"internalType":"struct UlnConfig","name":"config","type":"tuple"}],"name":"UlnConfigSet","type":"event"},{"inputs":[{"internalType":"address","name":"oapp","type":"address"},{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"executorConfigs","outputs":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"worker","type":"address"}],"name":"fees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_remoteEid","type":"uint32"}],"name":"getAppUlnConfig","outputs":[{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_configType","type":"uint32"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_remoteEid","type":"uint32"}],"name":"getExecutorConfig","outputs":[{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct ExecutorConfig","name":"rtnConfig","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_remoteEid","type":"uint32"}],"name":"getUlnConfig","outputs":[{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"rtnConfig","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"}],"name":"isSupportedEid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messageLibType","outputs":[{"internalType":"enum MessageLibType","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"receiver","type":"bytes32"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct Packet","name":"_packet","type":"tuple"},{"internalType":"bytes","name":"_options","type":"bytes"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quote","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"receiver","type":"bytes32"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct Packet","name":"_packet","type":"tuple"},{"internalType":"bytes","name":"_options","type":"bytes"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"send","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint32","name":"configType","type":"uint32"},{"internalType":"bytes","name":"config","type":"bytes"}],"internalType":"struct SetConfigParam[]","name":"_params","type":"tuple[]"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct ExecutorConfig","name":"config","type":"tuple"}],"internalType":"struct SetDefaultExecutorConfigParam[]","name":"_params","type":"tuple[]"}],"name":"setDefaultExecutorConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"config","type":"tuple"}],"internalType":"struct SetDefaultUlnConfigParam[]","name":"_params","type":"tuple[]"}],"name":"setDefaultUlnConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTreasuryNativeFeeCap","type":"uint256"}],"name":"setTreasuryNativeFeeCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint64","name":"major","type":"uint64"},{"internalType":"uint8","name":"minor","type":"uint8"},{"internalType":"uint8","name":"endpointVersion","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lzToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawLzTokenFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
9c4d535b000000000000000000000000000000000000000000000000000000000000000001000a83aedec744a0b1f607768a6213805825736b99282e12d8268bfc1c6e4d000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000600000000000000000000000005c6cff4b7c49805f8295ff73c204ac83f3bc4ae70000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000016bcc41e90000
Deployed Bytecode
0x0004000000000002002100000000000200000000030100190000006004300270000009e80340019700030000003103550002000000010355000009e80040019d0000000102200190000000310000c13d0000008005000039000000400050043f000000040230008c0000003f0000413d000000000201043b000000e002200270000009f40420009c0000006a0000a13d000009f50420009c000000d90000213d000009fd0420009c000005690000213d00000a010420009c000007c70000613d00000a020420009c000006bc0000613d00000a030120009c000000680000c13d0000000001000416000000000101004b000000680000c13d000000000100041a000009ec021001970000000005000411000000000252004b000008be0000c13d000009f001100197000000000010041b000009e8010000410000000002000414000009e80320009c0000000002018019000000c001200210000009f1011001c70000800d020000390000000303000039000009f2040000410000000006000019000009060000013d000000e002000039000000400020043f0000000002000416000000000202004b000000680000c13d000009e902300041000009ea0220009c000000430000213d00000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b00010430000000000103004b000000680000c13d00000000010000190000279a0001042e000000ff02300039000009eb02200197000000400020043f0000001f0230018f0000000504300272000000520000613d00000000050000190000000506500210000000000761034f000000000707043b000000e00660003900000000007604350000000105500039000000000645004b0000004a0000413d000000000502004b000000610000613d0000000504400210000000000141034f0000000302200210000000e004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f0000000000140435000000600130008c000000680000413d000000e00100043d000009ec02100197001b00000001001d000009ec0110009c000005f70000a13d00000000010000190000279b0001043000000a040420009c000001000000a13d00000a050420009c000005e70000213d00000a090420009c0000085d0000613d00000a0a0420009c000008090000613d00000a0b0220009c000000680000c13d0000000002000416000000000202004b000000680000c13d000000040230008a000000600420008c000000680000413d0000000404100370000000000404043b001a00000004001d000009ef0440009c000000680000213d0000001a0220006a00000a1c04000041000000e00520008c0000000005000019000000000504401900000a1c02200197000000000602004b000000000400a01900000a1c0220009c000000000405c019000000000204004b000000680000c13d0000002402100370000000000202043b001900000002001d000009ef0220009c000000680000213d0000001902000029000000230220003900000a1c04000041000000000532004b0000000005000019000000000504801900000a1c02200197000000000602004b000000000400801900000a1c0220009c000000000405c019000000000204004b000000680000c13d0000001902000029001800040020003d0000001802100360000000000402043b000009ef0240009c000000680000213d00000019020000290000002405200039001700000054001d000000170230006b000000680000213d0000004401100370000000000201043b000000000102004b0000000001000019000000010100c039001600000002001d000000000112004b000000680000c13d001b00000005001d001500000004001d000000c001000039000000400010043f000000800000043f000000a00000043f00000a140100004100000000001004390000000001000412001400000001001d00000004001004430000002400000443000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a15011001c70000800502000039279927940000040f00000001022001900000229c0000613d000000000101043b000009ec011001970000000002000411000000000121004b00000c3e0000c13d0000001501000029000000010110008c00000dc40000213d000000400100043d00000a3a02000041000000000021043500000004021000390000000000020435000009e802000041000009e80310009c0000000001028019000000400110021000000a38011001c70000279b00010430000009f60420009c000005b00000213d000009fa0420009c000007cd0000613d000009fb0420009c000006d20000613d000009fc0220009c000000680000c13d0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000401100370000000000101043b000009ec0210009c000000680000213d000000000200041a000009ec022001970000000003000411000000000232004b000008be0000c13d0000000302000039000000000302041a000009f003300197000000000313019f000000000032041b000000800010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a28011001c70000800d02000039000000010300003900000a2904000041000009060000013d00000a0c0420009c000006060000a13d00000a0d0420009c000006b60000613d00000a0e0420009c000006820000613d00000a0f0220009c000000680000c13d0000000002000416000000000202004b000000680000c13d000000040230008a000000400220008c000000680000413d0000000402100370000000000202043b001900000002001d000009ec0220009c000000680000213d0000002402100370000000000202043b000d00000002001d000009ef0220009c000000680000213d0000000d02000029000000230220003900000a1c04000041000000000532004b0000000005000019000000000504801900000a1c02200197000000000602004b000000000400801900000a1c0220009c000000000405c019000000000204004b000000680000c13d0000000d020000290000000402200039000000000121034f000000000101043b000c00000001001d000009ef0110009c000000680000213d0000000d01000029001700240010003d0000000c0100002900000005011002100000001701100029000000000131004b000000680000213d00000a14010000410000000000100439000000000100041200000004001004430000002400000443000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a15011001c70000800502000039279927940000040f00000001022001900000229c0000613d000000000101043b000009ec011001970000000002000411000000000121004b00000c3e0000c13d0000000c0100006b000000410000613d001a00000000001d0000001a01000029000000050110021000000017021000290000000201000367000000000221034f000000000202043b0000000d030000290000000003300079000000830330008a000000000432004b00000a1c070000410000000004000019000000000407801900000a1c0330019700000a1c05200197000000000635004b00000000060000190000000006074019000000000335013f00000a1c0330009c000000000604c019000000000306004b000000680000c13d0000001703200029000000000131034f000000000401043b000009e80140009c000000680000213d000000000040043500000a3d01000041000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039001b00000003001d001800000004001d279927940000040f00000018030000290000001b090000290000000102200190000000680000613d000000000101043b000000000101041a00000a6a01100198000012d40000613d00000020029000390000000201000367000000000221034f000000000202043b000009e80320009c000000680000213d000000010320008c000002700000613d000000020320008c0000137d0000c13d000000000291034f000000000c02043b000009e802c0009c000000680000213d0000004002900039000000000221034f000000000300003100000000049300490000001f0440008a000000000202043b000000000542004b00000a1c080000410000000005000019000000000508801900000a1c0440019700000a1c06200197000000000746004b00000000070000190000000007084019000000000446013f00000a1c0440009c000000000705c019000000000407004b000000680000c13d0000000004920019000000000241034f000000000202043b000009ef0520009c000000680000213d00000000052300490000002003400039000000000453004b00000a1c080000410000000004000019000000000408201900000a1c0550019700000a1c06300197000000000756004b00000000070000190000000007084019000000000556013f00000a1c0550009c000000000704c019000000000407004b000000680000c13d000000200420008c000000680000413d000000000431034f000000000404043b000009ef0540009c000000680000213d000000000232001900000000033400190000000004320049000000c00540008c00000a1c070000410000000005000019000000000507401900000a1c04400197000000000604004b0000000006000019000000000607201900000a1c0440009c000000000605c019000000000406004b000000680000c13d000000400400043d001b00000004001d00000a180440009c000000390000213d0000001b04000029000000c004400039000000400040043f000000000431034f000000000404043b000009ef0540009c000000680000213d0000001b050000290000000004450436001800000004001d0000002004300039000000000541034f000000000505043b000000ff0650008c000000680000213d000000180600002900000000005604350000002004400039000000000541034f000000000505043b000000ff0650008c000000680000213d0000001b060000290000004006600039001600000006001d00000000005604350000002004400039000000000541034f000000000505043b000000ff0650008c000000680000213d0000001b060000290000006006600039001500000006001d00000000005604350000002004400039000000000541034f000000000505043b000009ef0650009c000000680000213d00000000063500190000001f05600039000000000725004b00000a1c0a000041000000000700001900000000070a801900000a1c0550019700000a1c08200197000000000985004b000000000900001900000000090a4019000000000585013f00000a1c0550009c000000000907c019000000000509004b000000680000c13d000000000561034f000000000705043b000009ef0570009c000000390000213d00000005087002100000003f058000390012002000000092000000120950017f000000400500043d0000000009950019000000000a59004b000000000a000019000000010a004039000009ef0b90009c000000390000213d000000010aa00190000000390000c13d000000400090043f000000000075043500000020066000390000000007680019000000000827004b000000680000213d000000000876004b000002250000813d0000000008050019000000000961034f000000000909043b000009ec0a90009c000000680000213d000000200880003900000000009804350000002006600039000000000976004b0000021c0000413d0000001b060000290000008006600039001400000006001d00000000005604350000002004400039000000000441034f000000000404043b000009ef0540009c000000680000213d00000000053400190000001f03500039000000000423004b00000a1c080000410000000004000019000000000408801900000a1c0330019700000a1c06200197000000000763004b00000000070000190000000007084019000000000363013f00000a1c0330009c000000000704c019000000000307004b000000680000c13d000000000351034f000000000303043b000009ef0430009c000000390000213d00000005063002100000003f04600039000000120740017f000000400400043d0000000007740019000000000847004b00000000080000190000000108004039000009ef0970009c000000390000213d0000000108800190000000390000c13d000000400070043f000000000334043600000020055000390000000006560019000000000226004b000000680000213d000000000265004b000002600000813d0000000002040019000000000751034f000000000707043b000009ec0870009c000000680000213d000000200220003900000000007204350000002005500039000000000765004b000002570000413d0000001b01000029000000a001100039001100000001001d000000000041043500000018010000290000000001010433000000ff051001900000026a0000613d000000ff0150008c000002f70000c13d000000140100002900000000010104330000000001010433000000000101004b0000030c0000613d000010e80000013d000000000291034f000000000202043b001800000002001d000009e80220009c000000680000213d0000004002900039000000000321034f000000000200003100000000049200490000001f0440008a000000000303043b000000000543004b00000a1c080000410000000005000019000000000508801900000a1c0440019700000a1c06300197000000000746004b00000000070000190000000007084019000000000446013f00000a1c0440009c000000000705c019000000000407004b000000680000c13d0000000003930019000000000431034f000000000404043b000009ef0540009c000000680000213d000000400540008c000000680000413d00000000044200490000002002300039000000000342004b00000a1c070000410000000003000019000000000307201900000a1c0440019700000a1c05200197000000000645004b00000000060000190000000006074019000000000445013f00000a1c0440009c000000000603c019000000000306004b000000680000c13d000000400400043d00000a3b0340009c000000390000213d001b00000004001d0000004003400039000000400030043f000000000321034f000000000303043b000009e80430009c000000680000213d0000001b040000290000000003340436001600000003001d0000002002200039000000000121034f000000000101043b000009ec0210009c000000680000213d00000016020000290000000000120435000000190100002900000000001004350000000401000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b00000018020000290000000000200435000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001b040000290000000002040433000009e802200197000000000101043b000000000301041a00000a7103300197000000000223019f00000016050000290000000003050433000000200330021000000a4b03300197000000000232019f000000000021041b000000400100043d000000200210003900000018030000290000000000320435000000190200002900000000002104350000000002040433000009e802200197000000400310003900000000002304350000000002050433000009ec0220019700000060031000390000000000230435000009e80210009c000009e80400004100000000010480190000000002000414000009e80320009c00000000020480190000004001100210000000c002200210000000000112019f00000a72011001c70000800d02000039000000010300003900000a7304000041000005600000013d0000007f0150008c000010e80000213d000000140100002900000000010104330000000021010434000000000551004b000010e80000c13d000000000501004b0000030c0000613d00000000050000190000000006000019000000050750021000000000077200190000000007070433000009ec07700197000000000667004b00000d9d0000a13d0000000105500039000000000615004b0000000006070019000003020000413d00000016010000290000000001010433000000ff01100190000003120000613d000000ff0210008c0000031a0000c13d0000000001040433000000000101004b000010eb0000c13d00000015010000290000000001010433000000ff01100190000003330000613d000011010000013d0000007f0210008c000010eb0000213d0000000002040433000000000212004b000010eb0000c13d00000015020000290000000002020433000000ff02200190000011010000613d000000000212004b000011010000213d000000000201004b000003330000613d00000000020000190000000004000019000000050520021000000000055300190000000005050433000009ec05500197000000000445004b00000d9d0000a13d0000000102200039000000000412004b0000000004050019000003290000413d000000190100002900000000001004350000000101000039000b00000001001d000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c7000080100200003900130000000c001d279927940000040f00000013030000290000000102200190000000680000613d000000000101043b000009e802300197001300000002001d0000000000200435000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001b020000290000000002020433000009ef02200197000000000301043b000000000103041a00000a6301100197000000000121019f00000018020000290000000002020433000000400220021000000a6402200197000000000121019f00000016020000290000000002020433000000480220021000000a6502200197000000000121019f00000015020000290000000002020433000000500220021000000a6602200197000000000121019f000000000013041b00000014010000290000000001010433000f00000001001d0000000002010433000009ef0120009c000000390000213d000e00000003001d0000000104300039000000000304041a000000000024041b001000000002001d000000000132004b0000038b0000813d000900000003001d000a00000004001d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000201043b00000010012000290000000902200029000000000321004b0000000a040000290000038b0000813d000000000001041b0000000101100039000000000321004b000003870000413d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000001006000029000000000206004b0000000f05000029000003a30000613d0000000002000019000000000312001900000020055000390000000004050433000009ec04400197000000000043041b0000000102200039000000000362004b0000039b0000413d00000011010000290000000001010433000f00000001001d0000000002010433000009ef0120009c0000000e01000029000000390000213d0000000204100039000000000304041a000000000024041b001000000002001d000000000132004b000003c60000813d000a00000003001d000e00000004001d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000201043b00000010012000290000000a02200029000000000321004b0000000e04000029000003c60000813d000000000001041b0000000101100039000000000321004b000003c20000413d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000001006000029000000000206004b0000000f05000029000003de0000613d0000000002000019000000000312001900000020055000390000000004050433000009ec04400197000000000043041b0000000102200039000000000362004b000003d60000413d000000400300043d00000a180130009c000000390000213d000000c001300039000000400010043f000000a0023000390000006001000039000700000002001d00000000001204350000008002300039000a00000001001d000800000002001d00000000001204350000006001300039000900000001001d00000000000104350000004001300039000600000001001d0000000000010435000e00000003001d0000000001030436000f00000001001d00000000000104350000001301000029000000000010043500000a3d01000041000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001000000001001d000000190100002900000000001004350000000b01000029000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b00000013020000290000000000200435000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000401043b000000000204041a000009ef01200198000004270000613d000009ef0110009c000000000102001900000010030000290000042c0000613d000004290000013d0000001003000029000000000103041a000009ef011001970000000e0500002900000000001504350000004001200270000000ff051001900000045f0000613d000000ff0150008c000004990000613d000500000005001d000e00000002001d000b00000004001d0000000101400039000000000301041a000000400200043d000400000002001d000200000003001d0000000002320436000300000002001d00000000001004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000205000029000000000205004b0000000304000029000004520000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b0000044b0000413d000000040500002900000000015400490000001f01100039000000120210017f0000000001520019000000000221004b00000000020000190000000102004039000009ef0310009c0000000b040000290000000503000029000004900000a13d000000390000013d000000000103041a0000004001100270000000ff01100190000004990000613d000500000001001d000b00000004001d000e00000002001d0000000101300039000000000301041a000000400200043d000400000002001d000200000003001d0000000002320436000300000002001d00000000001004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000205000029000000000205004b0000000304000029000004840000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b0000047d0000413d000000040500002900000000015400490000001f01100039000000120210017f0000000001520019000000000221004b00000000020000190000000102004039000009ef0310009c0000000b040000290000000503000029000000390000213d0000000102200190000000390000c13d000000400010043f000000080100002900000000005104350000000f0100002900000000003104350000000e0200002900000010030000290000004801200270000000ff05100190000004ca0000613d000000ff0150008c000005050000613d001000000005001d000e00000002001d0000000201400039000000000301041a000000400200043d000b00000002001d000500000003001d0000000002320436000800000002001d00000000001004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000504000029000000000204004b0000000805000029000004be0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000535043600000001011000390000000102200039000000000342004b000004b70000413d0000000b0400002900000000014500490000001f01100039000000120210017f0000000001420019000000000221004b00000000020000190000000102004039000009ef0310009c0000001003000029000004f90000a13d000000390000013d000000000203041a0000004801200270000000ff01100190000005050000613d001000000001001d000e00000002001d0000000201300039000000000301041a000000400200043d000b00000002001d000500000003001d0000000002320436000800000002001d00000000001004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000504000029000000000204004b0000000805000029000004ee0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000535043600000001011000390000000102200039000000000342004b000004e70000413d0000000b0400002900000000014500490000001f01100039000000120210017f0000000001420019000000000221004b00000000020000190000000102004039000009ef0310009c0000001003000029000000390000213d0000000102200190000000390000c13d000000400010043f00000007010000290000000000410435000000060100002900000000003104350000000e010000290000005001100270000000ff0110018f000000090200002900000000001204350000000f010000290000000001010433000000ff011001900000050d0000c13d00000009010000290000000001010433000000ff01100190000010450000613d000000400100043d00000040021000390000000a030000290000000000320435000000200210003900000013030000290000000000320435000000190200002900000000002104350000001b020000290000000002020433000009ef032001970000006002100039000000000032043500000018030000290000000003030433000000ff0330018f0000008004100039000000000034043500000016030000290000000003030433000000ff0330018f000000a004100039000000000034043500000015030000290000000003030433000000ff0330018f000000c004100039000000000034043500000014030000290000000004030433000000e003100039000000c00500003900000000005304350000012003100039000000000504043300000000005304350000014003100039000000000605004b0000053d0000613d000000000600001900000020044000390000000007040433000009ec0770019700000000037304360000000106600039000000000756004b000005360000413d0000000004230049000000110200002900000000020204330000010005100039000000000045043500000000040204330000000003430436000000000504004b0000054e0000613d000000000500001900000020022000390000000006020433000009ec0660019700000000036304360000000105500039000000000645004b000005470000413d0000000002130049000009e80310009c000009e80400004100000000010480190000004001100210000009e80320009c00000000020480190000006002200210000000000112019f0000000002000414000009e80320009c0000000002048019000000c002200210000000000121019f000009f1011001c70000800d02000039000000010300003900000a6c040000412799278f0000040f0000000101200190000000680000613d0000001a020000290000000102200039001a00000002001d0000000c0120006c0000014a0000413d000000410000013d000009fe0420009c000007e40000613d000009ff0420009c0000074b0000613d00000a000220009c000000680000c13d0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000402100370000000000202043b000009ef0420009c000000680000213d000000230420003900000a1c05000041000000000634004b0000000006000019000000000605801900000a1c04400197000000000704004b000000000500801900000a1c0440009c000000000506c019000000000405004b000000680000c13d0000000404200039000000000441034f000000000404043b001900000004001d000009ef0440009c000000680000213d0000002409200039000000190200002900000060422000c90000000002920019000000000232004b000000680000213d000000000200041a000009ec022001970000000003000411000000000232004b000008be0000c13d000000190200006b000009c30000c13d0000002001000039000000800010043f000000c0030000390000008002000039000000a00000043f0000000001230049000009e803000041000009e80420009c00000000020380190000004002200210000009e80410009c00000000010380190000006001100210000000000121019f0000000002000414000009e80420009c0000000002038019000000c002200210000000000121019f000009f1011001c70000800d02000039000000010300003900000a4e04000041000009060000013d000009f70420009c000007ec0000613d000009f80420009c000007a20000613d001b00000005001d000009f90220009c000000680000c13d0000000002000416000000000202004b000000680000c13d000000040230008a000000400220008c000000680000413d0000000402100370000000000202043b001a00000002001d000009ec0220009c000000680000213d0000002401100370000000000101043b001900000001001d0000000001000411001800000001001d00000000001004350000000501000039001700000001001d000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000401041a0000001903000029000000000134004b0000090a0000813d000000400100043d0000002402100039000000000042043500000a2302000041000000000021043500000004021000390000000000320435000009e802000041000009e80310009c0000000001028019000000400110021000000a1f011001c70000279b0001043000000a060120009c000008a80000613d00000a070120009c000008400000613d00000a080120009c000000680000c13d0000000001000416000000000101004b000000680000c13d0000000301000039000000800010043f000000a00000043f0000000201000039000000c00010043f00000a53010000410000279a0001042e000001200100043d001900000001001d000001000100043d001a00000001001d000000400a00043d000009ed0100004100000000001a04350000000001000414000000040320008c000006160000c13d0000000103000031000000200130008c00000000040300190000002004008039000006470000013d00000a100420009c000007b40000613d00000a110120009c000000680000c13d0000000001000416000000000101004b000000680000c13d0000000001030019279924aa0000040f279925710000040f000000400200043d001b00000002001d279924c20000040f000009e8010000410000001b03000029000008580000013d000009e803000041000009e80410009c0000000001038019000009e804a0009c00000000030a40190000004003300210000000c001100210000000000131019f000009ee011001c700180000000a001d279927940000040f000000180a00002900000000030100190000006003300270000009e803300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000006340000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b0000062c0000413d000000000705004b000006430000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000008c70000613d0000001f01400039000000600210018f00000000050a00190000000001a20019000000000221004b00000000020000190000000102004039000009ef0410009c000000390000213d0000000102200190000000390000c13d000000400010043f000000200130008c000000680000413d0000000001050433000009e80210009c000000680000213d0000001b02000029000000800020043f000000a00010043f000000000200041a000009f0012001970000000006000411000000000161019f000000000010041b000009e8010000410000000003000414000009e80430009c0000000003018019000000c001300210000009f1011001c7000009ec052001970000800d020000390000000303000039001b00000003001d000009f2040000412799278f0000040f0000000101200190000000680000613d0000001a03000029000000c00030043f00000002010000390000001902000029000000000021041b000000800100043d00000140000004430000016000100443000000a00100043d00000020020000390000018000200443000001a0001004430000004001000039000001c000100443000001e00030044300000100002004430000001b010000290000012000100443000009f3010000410000279a0001042e0000000002000416000000000202004b000000680000c13d000000040230008a000000600220008c000000680000413d0000000402100370000000000202043b001b00000002001d000009ec0220009c000000680000213d0000002402100370000000000202043b001a00000002001d000009ec0220009c000000680000213d0000004401100370000000000301043b0000000301000039000000000101041a000009ec011001970000000002000411000000000112004b000008f60000c13d001900000003001d00000a1301000041000000800010043f00000a14010000410000000000100439000000000100041200000004001004430000002400000443000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a15011001c70000800502000039279927940000040f00000001022001900000229c0000613d000000000201043b0000000001000414000009ec02200197000000040320008c0000098b0000c13d0000000103000031000000200130008c00000000040300190000002004008039000009b60000013d0000000001000416000000000101004b000000680000c13d000000800000043f00000a24010000410000279a0001042e0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000401100370000000000101043b000009e80210009c000000680000213d279927620000040f000000000101004b0000000001000019000000010100c039000000400200043d0000000000120435000009e801000041000009e80320009c0000000002018019000000400120021000000a52011001c70000279a0001042e0000000002000416000000000202004b000000680000c13d000000040230008a000000600420008c000000680000413d0000000404100370000000000704043b000009ef0470009c000000680000213d000000000272004900000a1c04000041000000e00520008c0000000005000019000000000504401900000a1c02200197000000000602004b000000000400a01900000a1c0220009c000000000405c019000000000204004b000000680000c13d0000002402100370000000000402043b000009ef0240009c000000680000213d000000230240003900000a1c05000041000000000632004b0000000006000019000000000605801900000a1c02200197000000000802004b000000000500801900000a1c0220009c000000000506c019000000000205004b000000680000c13d0000000408400039000000000281034f000000000502043b000009ef0250009c000000680000213d00000024064000390000000002650019000000000232004b000000680000213d0000004402100370000000000902043b000000000209004b0000000002000019000000010200c039001700000009001d000000000229004b000000680000c13d000000c002000039001b00000002001d000000400020043f001800440070003d0000001802100360000000800000043f000000a00000043f000000000202043b001a00000002001d000009ec0220009c000000680000213d0000001802000029001400200020003d0000001402100360000000000202043b001900000002001d000009e80920009c000000680000213d00000014020000290000006009200039000000000991034f000000000a730049000000230aa0008a000000000909043b00000a1c0b000041000000000ca9004b000000000c000019000000000c0b801900000a1c0aa0019700000a1c0d900197000000000ead004b000000000b008019000000000aad013f00000a1c0aa0009c000000000b0cc019000000000a0b004b000000680000c13d00000004077000390000000007970019000000000971034f000000000209043b000c00000002001d000009ef0920009c000000680000213d0000000c0930006a000000200770003900000a1c0a000041000000000b97004b000000000b000019000000000b0a201900000a1c0990019700000a1c07700197000000000c97004b000000000a008019000000000797013f00000a1c0770009c000000000a0bc01900000000070a004b000000680000c13d000000010750008c0000112c0000213d00000a3a01000041000000c00010043f000000c40000043f00000a36010000410000279b000104300000000002000416000000000202004b000000680000c13d000000040230008a000000600220008c000000680000413d0000000402100370000000000202043b001b00000002001d000009e80220009c000000680000213d0000002402100370000000000202043b001a00000002001d000009ec0220009c000000680000213d0000004401100370000000000101043b000009e80210009c000000680000213d000009e802100197000000010320008c0000093a0000613d000000020220008c000009860000c13d0000014001000039000000400010043f000000800000043f000000a00000043f000000c00000043f000000e00000043f0000006001000039000001000010043f000001200010043f0000001b01000029000000000010043500000a3d01000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001900000001001d0000001a0100002900000000001004350000000101000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000001b020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001800000001001d000000000101041a001b00000001001d000009ef0110019800000f0b0000613d000009ef0110009c0000001b0100002900000f0f0000613d00000f0d0000013d0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000401100370000000000101043b000009ec0210009c000000680000213d00000000001004350000000501000039000000200010043f00000040020000390000000001000019279927790000040f000000000101041a000007e90000013d0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000401100370000000000201043b00000a7c01200197000000000112004b000000680000c13d000000010100003900000a7d0320009c000007e90000613d00000a7e0320009c000007e90000613d00000a7f0220009c000000000100c019000007e90000013d0000000001000416000000000101004b000000680000c13d0000000301000039000000000101041a000007e80000013d0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000401100370000000000101043b000000000200041a000009ec022001970000000003000411000000000232004b000008be0000c13d0000000203000039000000000203041a000000000421004b000008ea0000a13d00000a2303000041000000800030043f000000840010043f000000a40020043f00000a48010000410000279b000104300000000001000416000000000101004b000000680000c13d000000000100041a000009ec01100197000000800010043f00000a24010000410000279a0001042e0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000401100370000000000601043b000009ec0160009c000000680000213d000000000100041a000009ec021001970000000005000411000000000252004b000008be0000c13d000000000206004b000008fa0000c13d00000a1d01000041000000800010043f0000002001000039000000840010043f0000002601000039000000a40010043f00000a2501000041000000c40010043f00000a2601000041000000e40010043f00000a27010000410000279b000104300000000001000416000000000101004b000000680000c13d0000000001030019279924aa0000040f001a00000001001d001b00000002001d279925c40000040f0000001a01000029000009ec0110019700000000001004350000000101000039000000200010043f00000040020000390000000001000019279927790000040f0000001b02000029279925490000040f001a00000001001d000000400100043d001b00000001001d2799255a0000040f0000001a05000029000000000105041a0000005002100270000000ff0220018f0000001b04000029000000600340003900000000002304350000004802100270000000ff0220018f000000400340003900000000002304350000004002100270000000ff0220018f00000020034000390000000000230435000009ef0110019700000000001404350000000101500039279925dc0000040f0000001b02000029000000800220003900000000001204350000001a010000290000000201100039279925dc0000040f0000001b02000029000000a0032000390000000000130435000000400100043d001a00000001001d279924fe0000040f0000001a04000029000008b40000013d0000000001000416000000000101004b000000680000c13d0000000001030019279924aa0000040f001b00000002001d000009ec0110019700000000001004350000000401000039000000200010043f00000040020000390000000001000019279927790000040f0000001b02000029279925490000040f000000000101041a0000002002100270000009ec02200197000000400300043d00000020043000390000000000240435000009e8011001970000000000130435000009e801000041000009e80230009c0000000003018019000000400130021000000a45011001c70000279a0001042e0000000002000416000000000202004b000000680000c13d000000040230008a000000200220008c000000680000413d0000000402100370000000000202043b001100000002001d000009ef0220009c000000680000213d0000001102000029000000230220003900000a1c04000041000000000532004b0000000005000019000000000504801900000a1c02200197000000000602004b000000000400801900000a1c0220009c000000000405c019000000000204004b000000680000c13d00000011020000290000000402200039000000000121034f000000000101043b001600000001001d000009ef0110009c000000680000213d0000001101000029000000240210003900000016010000290000000501100210001700000002001d001000000001001d0000000001210019000000000131004b000000680000213d000000000100041a000009ec011001970000000002000411000000000121004b000008be0000c13d00000080050000390000001604000029000000000104004b00000a270000c13d00000020010000390000000001150436000000000041043500000040025000390000001003200029000000000104004b00000c470000c13d0000000001530049000009e802000041000009e80350009c00000000050280190000004003500210000009e80410009c00000000010280190000006001100210000000000131019f0000000003000414000009e80430009c0000000003028019000000c002300210000000000121019f000009f1011001c70000800d02000039000000010300003900000a6804000041000009060000013d0000000001000416000000000101004b000000680000c13d0000000001030019279924aa0000040f279926120000040f0000002002000039000000400300043d001b00000003001d0000000002230436279924c90000040f0000001b040000290000000001410049000009e802000041000009e80310009c0000000001028019000009e80340009c000000000402801900000040024002100000006001100210000000000121019f0000279a0001042e00000a1d01000041000000800010043f0000002001000039000000840010043f000000a40010043f00000a6101000041000000c40010043f00000a62010000410000279b00010430000000400200043d0000001f0430018f0000000505300272000008d40000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000008cc0000413d000000000604004b000008e30000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000009e801000041000009e80420009c000000000201801900000040012002100000006002300210000000000121019f0000279b00010430000000000013041b000000800010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a28011001c70000800d02000039000000010300003900000a4704000041000009060000013d00000a7501000041000000800010043f00000a76010000410000279b00010430000009f001100197000000000161019f000000000010041b000009e8010000410000000002000414000009e80320009c0000000002018019000000c001200210000009f1011001c70000800d020000390000000303000039000009f2040000412799278f0000040f0000000101200190000000680000613d000000410000013d001600000004001d000000180100002900000000001004350000001701000029000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001603000029000000190230006a000000000101043b000000000021041b00000a1301000041000000400200043d001700000002001d000000000012043500000a140100004100000000001004390000000001000412000000040010044300000024000004430000000001000414000009e80210009c000009e801008041000000c00110021000000a15011001c70000800502000039279927940000040f00000001022001900000229c0000613d000000000201043b0000000001000414000009ec02200197000000040320008c00000d2c0000c13d0000000103000031000000200130008c00000000040300190000002004008039000000170a00002900000d5d0000013d000000c001000039000000400010043f000000800000043f000000a00000043f0000001b01000029000000000010043500000a4201000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001900000001001d0000001a0100002900000000001004350000000401000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000001b020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000101041a000009e802100198000009700000c13d0000001902000029000000000202041a000009e802200197000000800020043f0000002001100270000009ec01100198000009780000c13d0000001901000029000000000101041a0000002001100270000009ec01100197000000a00010043f000000400100043d00000020031000390000000000230435000000a00200043d000009ec02200197000000400310003900000000002304350000004002000039000000000021043500000a4f0210009c000000390000213d00000060041000390000108d0000013d00000a5002000041000000800020043f000000840010043f00000a51010000410000279b00010430000009e803000041000009e80410009c0000000001038019000000c00110021000000a76011001c7279927940000040f00000000030100190000006003300270000009e803300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000009a30000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b0000099b0000413d000000000705004b000009b20000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f0003000000010355000000010220019000000d0f0000613d0000001f01400039000000600210018f00000080012001bf000000400010043f000000200430008c000000680000413d000000800400043d000009ec0540009c000000680000213d0000001b0440006c00000d980000c13d00000a7b0200004100000d9b0000013d001800040000003d0000000006000019001700000009001d00000060326000c900000000059200190000004002500039000000000321034f000000000303043b000009ec0430009c000000680000213d000000000303004b00000da00000613d000000200220008a000000000221034f000000000202043b000009e80320009c000000680000213d000000000202004b00000da30000613d00000000000004350000001802000029000000200020043f000000000151034f000000000101043b000009e80210009c000000680000213d000000000010043500000a4201000041000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039001b00000006001d001a00000005001d279927940000040f0000001a040000290000001b060000290000001709000029000000000301034f0000000101200190000000680000613d00000020024000390000000201000367000000000421034f000000000404043b000009e80540009c000000680000213d0000002002200039000000000521034f000000000203043b000000000302041a00000a4903300197000000000343019f000000000032041b000000000405043b000009ec0540009c000000680000213d00000a4a03300197000000200440021000000a4b04400197000000000334019f000000000032041b0000000106600039000000190260006c000009c60000413d000000400200043d0000002003200039000000190400002900000000004304350000002003000039000000000032043500000040032000390000000004000019000000000591034f000000000505043b000009e80650009c000000680000213d00000000065304360000002005900039000000000751034f000000000707043b000009e80870009c000000680000213d00000000007604350000002005500039000000000551034f000000000505043b000009ec0650009c000000680000213d00000040063000390000000000560435000000600990003900000060033000390000000104400039000000190540006c00000a0f0000413d0000059d0000013d000000000200001900000a2d0000013d00000013020000290000000102200039000000160120006c000011290000813d001300000002001d000000050120021000000017021000290000000005000031000000110150006a000000630310008a0000000201000367000000000221034f000000000202043b000000000432004b00000a1c080000410000000004000019000000000408801900000a1c0330019700000a1c06200197000000000736004b00000000070000190000000007084019000000000336013f00000a1c0330009c000000000704c019000000000307004b000000680000c13d00000017032000290000002002300039000000000221034f001b00000003001d0000000003350049000000bf0330008a000000000202043b000000000432004b00000a1c080000410000000004000019000000000408801900000a1c0330019700000a1c06200197000000000736004b00000000070000190000000007084019000000000336013f00000a1c0330009c000000000704c019000000000307004b000000680000c13d0000001b0f2000290000002002f00039000000000321034f000000000303043b001a00000003001d000000ff0330008c000000680000213d0000001a03000029000000ff0330008c000010e80000613d0000002002200039000000000221034f000000000202043b001900000002001d000000ff0220008c000000680000213d0000001902000029000000ff0220008c000010eb0000613d0000000002f1034f000000000202043b001800000002001d000009ef0220009c000000680000213d0000001802000029000009ef0220009c000011260000613d0000000002f50049000000c00320008c00000a1c060000410000000003000019000000000306401900000a1c02200197000000000402004b0000000004000019000000000406201900000a1c0220009c000000000403c019000000000204004b000000680000c13d000000400900043d00000a180290009c000000390000213d000000c002900039000000400020043f000000400290003900000019030000290000000000320435000000180200002900000000032904360000001a02000029001500000003001d00000000002304350000006002f00039000000000321034f000000000703043b000000ff0370008c000000680000213d0000006003900039001200000003001d00000000007304350000002002200039000000000321034f000000000303043b000009ef0430009c000000680000213d0000000008f300190000001f03800039000000000453004b00000a1c060000410000000004000019000000000406801900000a1c0330019700000a1c0a500197000000000ba3004b000000000b000019000000000b0640190000000003a3013f00000a1c0330009c000000000b04c01900000000030b004b000000680000c13d000000000381034f000000000a03043b000009ef03a0009c000000390000213d000000050ba002100000003f04b00039000000200300008a0014000000340173000000400d00043d0000001404d00029000000000cd4004b000000000c000019000000010c004039000009ef0e40009c000000390000213d000000010cc00190000000390000c13d000000400040043f0000000000ad04350000002008800039000000000b8b001900000000045b004b000000680000213d0000000004b8004b00000acf0000813d000000000c08001900000000040d0019000000000ec1034f000000000e0e043b000009ec06e0009c000000680000213d00000020044000390000000000e40435000000200cc000390000000006bc004b00000ac60000413d00000080049000390000000000d404350000002002200039000000000221034f000000000202043b000009ef0420009c000000680000213d000000000df200190000001f02d00039000000000452004b00000a1c0e000041000000000400001900000000040e801900000a1c0220019700000a1c06500197000000000c62004b000000000c000019000000000c0e4019000000000262013f00000a1c0220009c000000000c04c01900000000020c004b000000680000c13d0000000002d1034f000000000202043b000009ef0420009c000000390000213d00000005042002100000003f06400039000000000336016f000000400c00043d000000000f3c00190000000006cf004b000000000e000019000000010e004039000009ef06f0009c000000390000213d0000000106e00190000000390000c13d0000004000f0043f00000000002c0435000000200fd00039000000000df4001900000000045d004b000000680000213d0000000004df004b00000b090000813d00000000050f001900000000040c0019000000000651034f000000000e06043b000009ec06e0009c000000680000213d00000020044000390000000000e4043500000020055000390000000006d5004b00000b000000413d000000a0049000390000000000c4043500000015040000290000000004040433000000ff0440019000000b130000c13d00000012040000290000000004040433000000ff04400190000010450000613d0000001b04100360000000000504043b000009e80450009c000000680000213d000000400400043d001b00000004001d00000a180440009c000000390000213d0000001b06000029000000c004600039000000400040043f000000600c60003900000000007c0435000000400e600039000000190400002900000000004e0435000000180400002900000000064604360000001a04000029001900000006001d0000000000460435000000400400043d0000001406400029000000000746004b00000000070000190000000107004039000009ef0960009c000000390000213d0000000107700190000000390000c13d000000400060043f0000000000a404350000000006b8004b00000b3f0000813d0000000006040019000000000781034f000000000707043b000009ec0970009c000000680000213d0000002006600039000000000076043500000020088000390000000007b8004b00000b360000413d0000001b06000029000000800a60003900000000004a0435000000400400043d0000000003340019000000000643004b00000000060000190000000106004039000009ef0730009c000000390000213d0000000106600190000000390000c13d000000400030043f00000000022404360000000003df004b00000b590000813d00000000030400190000000006f1034f000000000606043b000009ec0760009c000000680000213d00000020033000390000000000630435000000200ff000390000000006df004b00000b500000413d0000001b01000029000000a009100039000000000049043500000019010000290000000001010433000000ff0610019000000b620000613d000000ff0160008c00000b670000c13d00000000010a04330000000001010433000000000101004b00000b7b0000613d000010e80000013d0000007f0160008c000010e80000213d00000000010a04330000000031010434000000000661004b000010e80000c13d000000000601004b00000b7b0000613d00000000060000190000000007000019000000050860021000000000088300190000000008080433000009ec08800197000000000778004b00000d9d0000a13d0000000106600039000000000716004b000000000708001900000b710000413d00000000010e0433000000ff0110019000000b800000613d000000ff0310008c00000b870000c13d0000000001040433000000000101004b000010eb0000c13d00000000010c0433000000ff0110019000000b9f0000613d000011010000013d0000007f0310008c000010eb0000213d0000000003040433000000000313004b000010eb0000c13d00000000030c0433000000ff03300190000011010000613d000000000313004b000011010000213d000000000301004b00000b9f0000613d00000000030000190000000004000019000000050630021000000000066200190000000006060433000009ec06600197000000000446004b00000d9d0000a13d0000000103300039000000000413004b000000000406001900000b950000413d001400000009001d000009e801500197000000000010043500000a3d01000041000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039001a0000000c001d00180000000e001d00150000000a001d279927940000040f000000150500002900000018040000290000001a030000290000000102200190000000680000613d0000001b020000290000000002020433000009ef02200197000000000601043b000000000106041a00000a6301100197000000000121019f00000019020000290000000002020433000000400220021000000a6402200197000000000121019f0000000002040433000000480220021000000a6502200197000000000121019f0000000002030433000000500220021000000a6602200197000000000121019f000000000016041b0000000001050433001a00000001001d0000000002010433000009ef0120009c000000390000213d001900000006001d0000000104600039000000000304041a000000000024041b001b00000002001d000000000132004b00000bea0000813d001500000003001d001800000004001d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000201043b0000001b012000290000001502200029000000000321004b000000180400002900000bea0000813d000000000001041b0000000101100039000000000321004b00000be60000413d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000001b06000029000000000206004b0000001a0500002900000c020000613d0000000002000019000000000312001900000020055000390000000004050433000009ec04400197000000000043041b0000000102200039000000000362004b00000bfa0000413d00000014010000290000000001010433001a00000001001d0000000002010433000009ef0120009c0000001901000029000000390000213d0000000204100039000000000304041a000000000024041b001b00000002001d000000000132004b00000c250000813d001800000003001d001900000004001d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000201043b0000001b012000290000001802200029000000000321004b000000190400002900000c250000813d000000000001041b0000000101100039000000000321004b00000c210000413d00000000004004350000000001000414000009e80210009c000009e801008041000000c00110021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000001b06000029000000000206004b0000001a0500002900000a290000613d0000000002000019000000000312001900000020055000390000000004050433000009ec04400197000000000043041b0000000102200039000000000362004b00000c350000413d00000a290000013d000000400100043d00000a69020000410000000000210435000009e802000041000009e80310009c00000000010280190000004001100210000009ee011001c70000279b0001043000000002040003670000000006000031000000110160006a001b00000006001d001900bf00600092001a00630010009200000a1c080000410000000009000019000000170a000029001800000005001d00000c570000013d000000200aa000390000000109900039000000160190006c0000001805000029000008950000813d0000000001530049000000400110008a00000000021204360000000001a4034f000000000101043b0000001a05000029000000000651004b0000000006000019000000000608801900000a1c0750019700000a1c0b100197000000000c7b004b000000000c000019000000000c08401900000000077b013f00000a1c0770009c000000000c06c01900000000060c004b000000680000c13d0000001701100029000000000614034f000000000606043b000009e80760009c000000680000213d00000000066304360000001907100069000000200b100039000000000bb4034f000000000b0b043b000000000c7b004b000000000c000019000000000c08801900000a1c0770019700000a1c0db00197000000000e7d004b000000000e000019000000000e08401900000000077d013f00000a1c0770009c000000000e0cc01900000000070e004b000000680000c13d00000040070000390000000000760435000000000b1b00190000000001b4034f000000000101043b000009ef0610009c000000680000213d000000400630003900000000001604350000002001b00039000000000614034f000000000606043b000000ff0760008c000000680000213d000000600730003900000000006704350000002001100039000000000614034f000000000606043b000000ff0760008c000000680000213d000000800730003900000000006704350000002001100039000000000614034f000000000606043b000000ff0760008c000000680000213d000000a00730003900000000006704350000001b06b00069000000200d1000390000000001d4034f000000000101043b0000001f0c60008a00000a1c06c0019700000a1c07100197000000000e67004b000000000e000019000000000e084019000000000667013f0000000007c1004b0000000007000019000000000708801900000a1c0660009c000000000e07c01900000000060e004b000000680000c13d0000000001b10019000000000614034f000000000f06043b000009ef06f0009c000000680000213d00000020011000390000000506f002100000001b06600069000000000761004b0000000007000019000000000708201900000a1c0660019700000a1c0e10019700000000056e004b0000000005000019000000000508401900000000066e013f00000a1c0660009c000000000507c019000000000505004b000000680000c13d000000c005300039000000c006000039000000000065043500000100053000390000000000f50435000001200e30003900000000050f004b00000cd80000613d0000000006000019000000000514034f000000000705043b000009ec0570009c000000680000213d000000000e7e0436000000200110003900000001066000390000000005f6004b00000ccf0000413d0000002001d00039000000000114034f000000000101043b0000000005c1004b0000000005000019000000000508801900000a1c06c0019700000a1c07100197000000000c67004b000000000c000019000000000c084019000000000667013f00000a1c0660009c000000000c05c01900000000050c004b000000680000c13d0000000001b10019000000000514034f000000000b05043b000009ef05b0009c000000680000213d00000020011000390000000505b002100000001b05500069000000000651004b0000000006000019000000000608201900000a1c0550019700000a1c07100197000000000c57004b000000000c000019000000000c084019000000000557013f00000a1c0550009c000000000c06c01900000000050c004b000000680000c13d00000000053e0049000000400550008a000000e00330003900000000005304350000000003be043600000000050b004b00000c520000613d0000000006000019000000000514034f000000000705043b000009ec0570009c000000680000213d0000000003730436000000200110003900000001066000390000000005b6004b00000d050000413d00000c520000013d000000400200043d0000001f0430018f000000050530027200000d1c0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b00000d140000413d000000000604004b00000d2b0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000008e30000013d000009e803000041000009e80410009c00000000010380190000001705000029000009e80450009c00000000030540190000004003300210000000c001100210000000000131019f000009ee011001c7279927940000040f000000170a00002900000000030100190000006003300270000009e803300197000000200430008c000000000403001900000020040080390000001f0540018f000000050640027200000d4a0000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b00000d420000413d000000000705004b00000d590000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f0003000000010355000000010220019000000d7b0000613d0000001f01400039000000600210018f0000000001a20019000000000221004b00000000020000190000000102004039000009ef0410009c000000390000213d0000000102200190000000390000c13d000000400010043f000000200230008c000000680000413d00000017020000290000000002020433001700000002001d000009ec0220009c000000680000213d000000170200006b000010000000c13d0000001a0200006b000010020000613d00000000020004140000001a04000029000000040440008c000010f80000c13d0000000102000039000009ef0430009c000000390000213d000012700000013d000000400200043d0000001f0430018f000000050530027200000d880000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b00000d800000413d000000000604004b00000d970000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000008e30000013d0000001a0400006b00000da60000c13d00000a2202000041000000000021043500000c440000013d000000400100043d00000a6b0200004100000c400000013d000000400100043d00000a4d0200004100000c400000013d000000400100043d00000a4c0200004100000c400000013d000000c40420003900000019050000290000000000540435000000a00420003900000a16050000410000000000540435000000a4052000390000001a060000290000000000650435000000440500003900000000005104350000014005200039000000400050043f000001200520003900000a1906000041000000000065043500000100022001bf0000002005000039001700000002001d001600000005001d0000000000520435000000000201043300000000010004140000001b05000029000000040550008c00000fa90000c13d0000000102000039000009ef0130009c000000390000213d00000fbd0000013d000000180100002900000020021000390000000201000367000000000221034f000000000202043b000000f002200270000000030320008c000010930000c13d001900600000003d0000001502000029000000030220008c0000001902000029000014b30000413d000000020400003900000060020000390000000003000031000000000e020019000000000a0000190000000007040019000000150f0000290000001b0d0000290000000008d40019000000000581034f000000000505043b00000a2c0650009c000012e40000413d000000f805500270000000ff0ba001900000000006050019000000000905001900000ed20000613d0000000006b5004b00000000060b001900000000090a001900000ed20000613d000000000674004b000000680000413d00000000067400490000000007d70019000000ff09a0018f000000010a90008c00000e310000613d000000020990008c000014760000c13d0000000009020433000000000a09004b00000ea00000613d000000400800043d000000200a800039000000000b000019000000000cab0019000000200bb00039000000000d2b0019000000000d0d04330000000000dc0435000000000c9b004b00000df60000413d000000000771034f00000000029a00190000000000020435000000050960027200000e0b0000613d000000000a000019000000050ba00210000000000cb20019000000000bb7034f000000000b0b043b0000000000bc0435000000010aa00039000000000b9a004b00000e030000413d0000001f0a6001900000001b0d00002900000e1b0000613d0000000509900210000000000797034f0000000009920019000000030aa00210000000000b090433000000000bab01cf000000000bab022f000000000707043b000001000aa000890000000007a7022f0000000007a701cf0000000007b7019f0000000000790435000000000262001900000000000204350000000002820049000000200620008a00000000006804350000001f02200039000000200600008a000000000662016f0000000002860019000000000662004b00000000060000190000000106004039000009ef0720009c000000390000213d0000000106600190000000390000c13d000000400020043f000000000605001900000000070400190000000009050019000000000208001900000ed20000013d000000000a0e043300000000090a004b00000e720000613d000000400800043d000000200b8000390000000009000019000000000cb900190000002009900039000000000de90019000000000d0d04330000000000dc0435000000000ca9004b00000e370000413d000000000971034f0000000007ab00190000000000070435000000050a60027200000e4c0000613d000000000b000019000000050cb00210000000000dc70019000000000cc9034f000000000c0c043b0000000000cd0435000000010bb00039000000000cab004b00000e440000413d0000001f0b60019000000e5b0000613d000000050aa002100000000009a9034f000000000aa70019000000030bb00210000000000c0a0433000000000cbc01cf000000000cbc022f000000000909043b000001000bb000890000000009b9022f0000000009b901cf0000000009c9019f00000000009a0435000000000667001900000000000604350000000006860049000000200760008a00000000007804350000001f06600039000000200700008a000000000776016f0000000006870019000000000776004b00000000070000190000000107004039000009ef0960009c0000001b0d000029000000390000213d0000000107700190000000390000c13d000000400060043f000000000605001900000000070400190000000009050019000000000e08001900000ed20000013d000009ef0960009c000000390000213d0000003f09600039000000200a00008a0000000009a9016f000000400e00043d00000000099e0019000000000ae9004b000000000a000019000000010a004039000009ef0b90009c000000390000213d000000010aa00190000000390000c13d000000400090043f00000000096e0436000000000838004b000000680000213d000000000771034f000000050860027200000e900000613d000000000a000019000000050ba00210000000000cb90019000000000bb7034f000000000b0b043b0000000000bc0435000000010aa00039000000000b8a004b00000e880000413d0000001f0a60019000000e9f0000613d0000000508800210000000000787034f0000000008890019000000030aa00210000000000b080433000000000bab01cf000000000bab022f000000000707043b000001000aa000890000000007a7022f0000000007a701cf0000000007b7019f000000000078043500000ecd0000013d000009ef0260009c000000390000213d0000003f02600039000000200900008a000000000992016f000000400200043d0000000009920019000000000a29004b000000000a000019000000010a004039000009ef0b90009c000000390000213d000000010aa00190000000390000c13d000000400090043f0000000009620436000000000838004b000000680000213d000000000771034f000000050860027200000ebe0000613d000000000a000019000000050ba00210000000000cb90019000000000bb7034f000000000b0b043b0000000000bc0435000000010aa00039000000000b8a004b00000eb60000413d0000001f0a60019000000ecd0000613d0000000508800210000000000787034f0000000008890019000000030aa00210000000000b080433000000000bab01cf000000000bab022f000000000707043b000001000aa000890000000007a7022f0000000007a701cf0000000007b7019f000000000078043500000000066900190000000000060435000000000605001900000000070400190000000009050019000000040500008a000000000554004b000000680000213d00000003054000390000000005f5004b000000680000213d00000001044000390000000005d40019000000000551034f000000000505043b00000a390850009c000013dc0000413d000000f00550027000000002055000390000ffff0550018f00000000044500190000000005f4004b000000000a09001900000dd90000413d00190000000e001d0000000005f4004b000013dc0000c13d0000001505000029000000000475004b0000001b08000029000000680000413d00000000047500490000000005870019000000ff0790018f000000010870008c0000147c0000613d000000020770008c000015790000c13d0000000006020433000000000706004b000015da0000c13d000009ef0240009c0000001909000029000000390000213d0000003f02400039000000200600008a000000000262016f000000400600043d0000000002260019000000000762004b00000000070000190000000107004039000009ef0820009c000000390000213d0000000107700190000000390000c13d000000400020043f0000000000460435000000170230006b0000000002060019000014930000a13d000000680000013d0000001901000029000000000101041a000009ef01100197000000800010043f0000001b010000290000004001100270001a00ff0010019400000f410000613d0000001a01000029000000ff0110008c00000f770000613d00000018010000290000000101100039000000000301041a000000400200043d001700000002001d001500000003001d0000000002320436001600000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001505000029000000000205004b000000160400002900000f360000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b00000f2f0000413d000000170140006a0000001f01100039000000200200008a000000000221016f0000001701200029000000000221004b00000000020000190000000102004039000009ef0310009c00000f700000a13d000000390000013d0000001901000029000000000101041a0000004001100270001a00ff0010019400000f770000613d00000019010000290000000101100039000000000301041a000000400200043d001700000002001d001500000003001d0000000002320436001600000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001505000029000000000205004b000000160400002900000f660000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b00000f5f0000413d000000170140006a0000001f01100039000000200200008a000000000221016f0000001701200029000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f0000001701000029000001000010043f0000001a01000029000000a00010043f0000001b010000290000004801100270001a00ff00100194000010040000613d0000001a01000029000000ff0110008c0000103f0000613d00000018010000290000000201100039000000000301041a000000400200043d001900000002001d001700000003001d0000000002320436001800000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001705000029000000000205004b000000180400002900000f9e0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b00000f970000413d000000190140006a0000001f01100039000000200200008a000000000221016f0000001901200029000000000221004b00000000020000190000000102004039000009ef0310009c000010340000a13d000000390000013d000009e803000041000009e80520009c000000000203801900000060022002100000004004400210000000000242019f000009e80410009c0000000001038019000000c001100210000000000112019f0000001b020000292799278f0000040f001800600000003d001500800000003d000000010220018f00030000000103550000006001100270000109e80010019d000009e80310019800000fea0000613d0000003f01300039000000200400008a000000000141016f000000400400043d0000000001140019001800000004001d000000000441004b00000000040000190000000104004039000009ef0510009c000000390000213d0000000104400190000000390000c13d000000400010043f0000001f0130018f000000180400002900000000083404360000000304000367000000050330027200000fda0000613d000000000500001900000005065002100000000007680019000000000664034f000000000606043b00000000006704350000000105500039000000000635004b00000fd20000413d001500000008001d000000000501004b00000fea0000613d0000000503300210000000000434034f00000015033000290000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f000000000013043500000018010000290000000001010433000000000202004b0000109f0000c13d000000000201004b000010ee0000c13d000000400300043d001b00000003001d00000a1d01000041000000000013043500000004013000390000001602000029000000000021043500000024023000390000001701000029279925360000040f0000001b040000290000000001410049000009e802000041000009e80310009c0000000001028019000010f20000013d0000001a0200006b000010c40000c13d00000a220200004100000c400000013d0000001901000029000000000101041a001b00000001001d0000004801100270001a00ff001001940000103f0000613d00000019010000290000000201100039000000000301041a000000400200043d001900000002001d001700000003001d0000000002320436001800000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000001705000029000000000205004b00000018040000290000102a0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000010230000413d000000190140006a0000001f01100039000000200200008a000000000221016f0000001901200029000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f0000001901000029000001200010043f0000001a01000029000000c00010043f0000001b010000290000005001100270000000ff0110018f000000e00010043f000000a00100043d000000ff01100190000010480000c13d000000e00100043d000000ff01100190000010480000c13d000000400100043d00000a6d0200004100000c400000013d000000400100043d000000200210003900000020030000390000000000320435000000800200043d000009ef0320019700000040021000390000000000320435000000a00300043d000000ff0330018f00000060041000390000000000340435000000c00300043d000000ff0330018f00000080041000390000000000340435000000e00300043d000000ff0330018f000000a0041000390000000000340435000000c003100039000000c005000039000001000400043d00000000005304350000010003100039000000000504043300000000005304350000012003100039000000000605004b0000106e0000613d000000000600001900000020044000390000000007040433000009ec0770019700000000037304360000000106600039000000000756004b000010670000413d0000000004230049000000e005100039000001200200043d000000000045043500000000040204330000000003430436000000000504004b0000107e0000613d000000000500001900000020022000390000000006020433000009ec0660019700000000036304360000000105500039000000000645004b000010770000413d0000000002130049000000200320008a00000000003104350000001f02200039000000200300008a000000000232016f0000000003120019000000000223004b000000000200001900000001020040390000000004030019000009ef0330009c000000390000213d0000000102200190000000390000c13d001b00000004001d000000400040043f00000020020000390000000002240436279925360000040f000008b30000013d000000010320008c000011040000613d000000020320008c000011200000c13d0000001502000029000000630220008a000000210300008a000000000232004b000012bc0000213d000000400100043d00000a2f0200004100000c400000013d000000000201004b000012eb0000c13d00000a1a0100004100000000001004390000001b010000290000000400100443000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a1b011001c70000800202000039279927940000040f00000001022001900000229c0000613d000000000101043b000000000101004b000012e70000c13d000000400100043d000000440210003900000a7a03000041000000000032043500000024021000390000001d03000039000000000032043500000a1d020000410000000000210435000000040210003900000020030000390000000000320435000009e802000041000009e80310009c0000000001028019000000400110021000000a5a011001c70000279b00010430000000440210003900000019040000290000000000420435000000200210003900000a1604000041000000000042043500000024041000390000001a0500002900000000005404350000004404000039000000000041043500000a170410009c000000390000213d0000008004100039001600000004001d000000400040043f00000a180410009c000000390000213d000000c004100039000000400040043f00000020050000390000001604000029001400000005001d0000000000540435000000a00410003900000a19050000410000000000540435000000000401043300000000010004140000001705000029000000040550008c0000132b0000c13d0000000102000039000009ef0130009c000000390000213d000013400000013d000000400100043d00000a700200004100000c400000013d000000400100043d00000a6f0200004100000c400000013d000009e802000041000009e80310009c00000000010280190000001504000029000009e80340009c000000000402801900000040024002100000006001100210000000000121019f0000279b00010430000009e801000041000009e80320009c0000000002018019000000c001200210000000190200006b000012640000c13d0000001a020000292799278f0000040f0000126a0000013d000000400100043d00000a6e0200004100000c400000013d0000001502000029000000220220008c000012d10000c13d00000019020000290000002602200039000000000221034f000000000202043b00000a2b0320009c000012c70000213d000000400600043d000000200360003900000a2c040000410000000000430435000000210360003900000a2d050000410000000000530435000000230360003900000000004304350000008002200210000000240360003900000000002304350000001402000039000000000026043500000a3b0260009c000000390000213d001900000006001d00000040026000390000143c0000013d000000400100043d00000a3503000041000000000031043500000004031000390000000000230435000000d30000013d000000400100043d00000a670200004100000c400000013d000000400500043d00000016040000290000088e0000013d0000002007800039000000000771034f000000000707043b000000f007700270000000030870008c000012da0000c13d000000030450008c000013800000413d00000002070000390000006004000039001b00000004001d000000000d000019000000000a070019000000000b6700190000000008b1034f000000000808043b00000a2c0980009c000012e40000413d000000f808800270000000ff0ed001900000000009080019000000000c080019000012330000613d0000000009e8004b00000000090e0019000000000c0d0019000012330000613d0000000009a7004b000000680000413d0000000009a70049000000000a6a0019000000ff0cd0018f000000010dc0008c000011900000613d000000020cc0008c000016550000c13d000000000c040433000000000d0c004b000012010000613d000000400b00043d000000200db00039000000000e000019000000000fde0019000000200ee0003900000000024e0019000000000202043300000000002f04350000000002ce004b000011560000413d000000000aa1034f0000000004cd00190000000000040435000000050c9002720000116b0000613d000000000d0000190000000502d00210000000000e24001900000000022a034f000000000202043b00000000002e0435000000010dd000390000000002cd004b000011630000413d0000001f0d9001900000117a0000613d0000000502c00210000000000a2a034f0000000002240019000000030cd00210000000000d020433000000000dcd01cf000000000dcd022f000000000a0a043b000001000cc00089000000000aca022f000000000aca01cf000000000ada019f0000000000a20435000000000294001900000000000204350000000002b20049000000200420008a00000000004b04350000001f02200039000000200400008a000000000242016f0000000004b20019000000000224004b00000000090000190000000109004039000009ef0240009c000000390000213d0000000102900190000000390000c13d000000400040043f0000000009080019000000000a070019000000000c08001900000000040b0019000012330000013d0000001b02000029000000000d02043300000000020d004b000011d10000613d000000400b00043d000000200eb00039000000000c0000190000000002ec0019000000200cc000390000001b0fc00029000000000f0f04330000000000f204350000000002dc004b000011970000413d000000000ca1034f000000000ade001900000000000a0435000000050d900272000011ac0000613d000000000e0000190000000502e00210000000000f2a001900000000022c034f000000000202043b00000000002f0435000000010ee000390000000002de004b000011a40000413d0000001f0e900190000011bb0000613d0000000502d00210000000000c2c034f00000000022a0019000000030de00210000000000e020433000000000ede01cf000000000ede022f000000000c0c043b000001000dd00089000000000cdc022f000000000cdc01cf000000000cec019f0000000000c2043500000000029a001900000000000204350000000002b20049000000200920008a00000000009b04350000001f02200039000000200900008a000000000292016f0000000009b20019000000000229004b000000000a000019000000010a004039000009ef0290009c000000390000213d0000000102a00190000000390000c13d000000400090043f0000000009080019000000000a070019000000000c080019001b0000000b001d000012330000013d000009ef0290009c000000390000213d0000003f02900039000000200c00008a0000000002c2016f000000400d00043d000000000c2d0019001b0000000d001d0000000002dc004b000000000d000019000000010d004039000009ef02c0009c000000390000213d0000000102d00190000000390000c13d0000004000c0043f0000001b02000029000000000c92043600000000023b004b000000680000213d000000000aa1034f000000050b900272000011f10000613d000000000d0000190000000502d00210000000000e2c001900000000022a034f000000000202043b00000000002e0435000000010dd000390000000002bd004b000011e90000413d0000001f0d900190000012000000613d0000000502b00210000000000a2a034f00000000022c0019000000030bd00210000000000d020433000000000dbd01cf000000000dbd022f000000000a0a043b000001000bb00089000000000aba022f000000000aba01cf000000000ada019f0000000000a204350000122e0000013d000009ef0290009c000000390000213d0000003f02900039000000200400008a000000000242016f000000400400043d000000000c24001900000000024c004b000000000d000019000000010d004039000009ef02c0009c000000390000213d0000000102d00190000000390000c13d0000004000c0043f000000000c94043600000000023b004b000000680000213d000000000aa1034f000000050b9002720000121f0000613d000000000d0000190000000502d00210000000000e2c001900000000022a034f000000000202043b00000000002e0435000000010dd000390000000002bd004b000012170000413d0000001f0d9001900000122e0000613d0000000502b00210000000000a2a034f00000000022c0019000000030bd00210000000000d020433000000000dbd01cf000000000dbd022f000000000a0a043b000001000bb00089000000000aba022f000000000aba01cf000000000ada019f0000000000a2043500000000029c001900000000000204350000000009080019000000000a070019000000000c080019000000040800008a000000000887004b000000680000213d0000000308700039000000000858004b000000680000213d00000001077000390000000008670019000000000881034f000000000808043b00000a390b80009c0000157f0000413d000000f00280027000000002022000390000ffff0220018f0000000007720019000000000257004b000000000d0c0019000011390000413d000000000357004b0000157f0000c13d0000000002a5004b000000680000413d0000000003a5004900000000056a0019000000ff06c0018f000000010260008c0000165b0000613d000000020260008c000016910000c13d0000000007040433000000000207004b000017380000c13d000009ef0230009c000000390000213d0000003f02300039000000200400008a000000000242016f000000400600043d0000000007260019000000000267004b00000000040000190000000104004039000009ef0270009c000000390000213d000000010240019000000000040600190000166e0000613d000000390000013d000009f1011001c7000080090200003900000019030000290000001a0400002900000000050000192799278f0000040f00030000000103550000006001100270000109e80010019d000009e803100198000012990000613d000000400100043d0000003f04300039000000200500008a000000000554016f0000000004150019000000000554004b00000000050000190000000105004039000009ef0640009c000000390000213d0000000105500190000000390000c13d000000400040043f0000001f0430018f0000000001310436000000030500036700000005033002720000128a0000613d000000000600001900000005076002100000000008710019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b000012820000413d000000000604004b000012990000613d0000000503300210000000000535034f00000000013100190000000303400210000000000401043300000000043401cf000000000434022f000000000505043b0000010003300089000000000535022f00000000033501cf000000000343019f00000000003104350000000101200190000012b30000613d000000400100043d00000040021000390000001903000029000000000032043500000020021000390000001a0300002900000000003204350000001802000029000009ec022001970000000000210435000009e8020000410000000003000414000009e80430009c0000000003028019000009e80410009c00000000010280190000004001100210000000c002300210000000000112019f00000a20011001c70000800d02000039000000010300003900000a2104000041000009060000013d000000400100043d00000024021000390000001903000029000000000032043500000a1e02000041000000000021043500000004021000390000001a03000029000005e00000013d00000019020000290000002602200039000000000321034f000000000403043b00000a2a0340009c000012c70000813d0000002002200039000000000321034f000000000303043b00000a2b0530009c0000140e0000a13d000000400100043d000000640210003900000a33030000410000000000320435000000440210003900000a3203000041000000000032043500000024021000390000002703000039000013080000013d000000400100043d00000a310200004100000c400000013d000000400100043d00000a7402000041000000000021043500000004021000390000000000320435000000d30000013d000000010370008c000014410000613d000000020370008c000014520000c13d000000630350008a000000210600008a000000000363004b0000145c0000213d00000a2f01000041000014730000013d000000400100043d00000a3702000041000000d00000013d00000018010000290000000001010433000000000201004b000013140000613d00000a1c02000041000000200310008c0000000003000019000000000302401900000a1c01100197000000000401004b000000000200a01900000a1c0110009c000000000203c019000000000102004b000000680000c13d00000015010000290000000001010433000000000201004b0000000002000019000000010200c039000000000221004b000000680000c13d000000000101004b000013140000c13d000000400100043d000000640210003900000a77030000410000000000320435000000440210003900000a7803000041000000000032043500000024021000390000002a03000039000000000032043500000a1d020000410000000000210435000000040210003900000020030000390000000000320435000009e802000041000009e80310009c0000000001028019000000400110021000000a54011001c70000279b00010430000000400100043d00000040021000390000001903000029000000000032043500000020021000390000001a0300002900000000003204350000001b020000290000000000210435000009e8020000410000000003000414000009e80430009c0000000003028019000009e80410009c00000000010280190000004001100210000000c002300210000000000112019f00000a20011001c70000800d02000039000000010300003900000a7904000041000008a70000013d000009e803000041000009e80520009c00000000020380190000004002200210000009e80540009c00000000040380190000006004400210000000000224019f000009e80410009c0000000001038019000000c001100210000000000112019f00000017020000292799278f0000040f001500600000003d000000010220018f00030000000103550000006001100270000109e80010019d000009e8031001980000136d0000613d0000003f01300039000000200400008a000000000141016f000000400400043d0000000001140019001500000004001d000000000441004b00000000040000190000000104004039000009ef0510009c000000390000213d0000000104400190000000390000c13d000000400010043f0000001f0130018f00000015040000290000000008340436000000030400036700000005033002720000135d0000613d000000000500001900000005065002100000000007680019000000000664034f000000000606043b00000000006704350000000105500039000000000635004b000013550000413d001b00000008001d000000000501004b0000136d0000613d0000000503300210000000000434034f0000001b033000290000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f000000000013043500000015010000290000000001010433000000000202004b000013e20000c13d000000000201004b000014570000c13d000000400300043d001b00000003001d00000a1d0100004100000000001304350000000401300039000000140200002900000000002104350000002402300039000000160100002900000ff90000013d000000400100043d00000a5003000041000011220000013d0000006004000039001600c00000003d000000600100043d000000000101004b001b00000004001d000015b20000c13d00000016010000290000002002100039001500000002001d000000400020043f0000000000010435000000400100043d001200000001001d00000a180110009c000000390000213d0000001202000029000000c001200039000000400010043f000000a0012000390000006003000039000d00000001001d00000000003104350000008001200039000e00000001001d000f00000003001d00000000003104350000006001200039001300000001001d00000000000104350000004001200039000b00000001001d00000000000104350000000001020436001100000001001d00000000000104350000001901000029000009e801100197001900000001001d000000000010043500000a3d01000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001000000001001d0000001a01000029000009ec0110019700000000001004350000000101000039001a00000001001d000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b00000019020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000900000001001d000000000101041a001900000001001d000009ef01100198000016970000613d000009ef0110009c00000019010000290000169c0000613d000016990000013d000000400100043d00000a3a02000041000000000021043500000004021000390000000000420435000000d30000013d000000000201004b000013f90000c13d00000a1a01000041000000000010043900000017010000290000000400100443000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a1b011001c70000800202000039279927940000040f00000001022001900000229c0000613d000000000101043b000000000101004b000010b20000613d00000015010000290000000001010433000000000201004b0000129b0000613d00000a1c02000041000000200310008c0000000003000019000000000302401900000a1c01100197000000000401004b000000000200a01900000a1c0110009c000000000203c019000000000102004b000000680000c13d0000001b010000290000000001010433000000000201004b0000000002000019000000010200c039000000000221004b000000680000c13d000000000101004b000012ff0000613d0000129b0000013d0000002002200039000000000221034f000000000202043b000000400800043d000000200580003900000a2c060000410000000000650435000000210580003900000a2d0700004100000000007504350000002305800039000000000065043500000080044002100000002405800039000000000045043500000034048000390000000000640435000000350480003900000a2e0500004100000000005404350000003704800039000009f10500004100000000005404350000008003300210000000380480003900000000003404350000001506000029000000420360008a00000003043002100000010004400089000000010500008a00000000044501cf000000200330008c0000000004058019000000000242016f00000003036002100000031003300089000000000232022f000000480380003900000000002304350000004802000039000000000028043500000a170280009c000000390000213d001900000008001d0000008002800039001b00000002001d0000001b02000029000000400020043f0000006002000039000014b50000013d000000220350008c000014720000c13d0000002603400039000000000131034f000000000101043b00000a2b0310009c000014660000213d00000a2c03000041000000e00030043f00000a2d04000041000000e10040043f000000e30030043f0000008001100210000000e40010043f001601000000003d0000001401000039000015a40000013d00000a3501000041000000c00010043f000000c40070043f00000a36010000410000279b00010430000009e802000041000009e80310009c00000000010280190000001b04000029000010f20000013d0000002604400039000000000341034f000000000303043b00000a2a0630009c000014660000813d0000002006400039000000000461034f000000000404043b00000a2b0740009c000015850000a13d00000a1d01000041000000c00010043f0000002001000039000000c40010043f0000002701000039000000e40010043f00000a3201000041000001040010043f00000a3301000041000001240010043f00000a34010000410000279b0001043000000a3101000041000000c00010043f00000a30010000410000279b00010430000000400100043d00000a3702000041000000000021043500000004021000390000000000b20435000000d30000013d00000019060000290000000007060433000000000607004b000016170000c13d000009ef0640009c000000390000213d0000003f06400039000000200700008a000000000776016f000000400600043d0000000007760019000000000867004b00000000080000190000000108004039000009ef0970009c000000390000213d0000000108800190000000390000c13d000000400070043f0000000000460435000000170330006b0000000009060019000000680000213d001900000009001d000000000751034f0000001f0540018f00000020036000390000000506400272000014a20000613d00000000080000190000000509800210000000000a930019000000000997034f000000000909043b00000000009a04350000000108800039000000000968004b0000149a0000413d000000000805004b000014b10000613d0000000506600210000000000767034f00000000066300190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f000000000056043500000000034300190000000000030435000000400300043d001b00000003001d0000000003020433000000000303004b000015540000c13d0000001b0200002900000a3c0220009c000000390000213d0000001b030000290000002002300039000000400020043f00000000000304350000001a02000029001800440020003d0000001802100360000000000202043b001700000002001d000009ec0220009c000000680000213d0000001802000029001300200020003d0000001301100360000000000101043b001500000001001d000009e80110009c000000680000213d000000400100043d001200000001001d00000a3b0110009c000000390000213d00000012020000290000004001200039000000400010043f0000000001020436001100000001001d00000000000104350000001501000029000000000010043500000a4201000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001000000001001d000000170100002900000000001004350000000401000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b00000015020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000101041a000009e802100198000015090000c13d0000001002000029000000000202041a000009e802200197000000120300002900000000002304350000002001100270000f09ec0010019c000015120000c13d0000001001000029000000000101041a0000002001100270000f09ec0010019b0000000f010000290000001102000029000000000012043500000000020000310000001a0120006a000000230410008a0000001301000029001100600010003d00000002010003670000001103100360000000000303043b00000a1c05000041000000000643004b0000000006000019000000000605801900000a1c0440019700000a1c07300197000000000847004b0000000005008019000000000447013f00000a1c0440009c000000000506c019000000000405004b000000680000c13d0000001a04000029001a00040040003d0000001a03300029000000000131034f000000000101043b000009ef0410009c000000680000213d0000000002120049000000200330003900000a1c04000041000000000523004b0000000005000019000000000504201900000a1c0220019700000a1c03300197000000000623004b0000000004008019000000000223013f00000a1c0220009c000000000405c019000000000204004b000000680000c13d000000400300043d0000002402300039001000000003001d000000040330003900000012040000290000000004040433000009e804400197000000000541004b000018d70000a13d00000a46050000410000001006000029000000000056043500000000001304350000000000420435000009e801000041000009e80260009c0000000006018019000000400160021000000a1f011001c70000279b000104300000001b0300002900000a3b0330009c000000390000213d0000001b040000290000004003400039000000400030043f00000001030000390000000003340436000000400400043d00000a3b0540009c000000390000213d0000004005400039000000400050043f00000020054000390000006006000039000000000065043500000000000404350000000000430435000000400400043d00000a3b0540009c000000390000213d0000004005400039000000400050043f00000020054000390000000000250435000000020200003900000000002404350000001b020000290000000002020433000000000202004b000015d60000613d00000000004304350000001b020000290000000002020433000000000202004b000015d60000613d000014bf0000013d000000400100043d00000a3702000041000000000021043500000004021000390000000000620435000000d30000013d000000400100043d00000a3a02000041000000000021043500000004021000390000000000720435000000d30000013d000000420750008a00000003087002100000010008800089000000010900008a00000000088901cf000000200770008c00000000080980190000002006600039000000000161034f000000000101043b00000a2c06000041000000e00060043f00000a2d07000041000000e10070043f000000e30060043f0000008003300210000000e40030043f000000f40060043f00000a2e03000041000000f50030043f000009f103000041000000f70030043f0000008003400210000000f80030043f000000000181016f00000003035002100000031003300089000000000131022f000001080010043f001601400000003d0000004801000039000000c00010043f0000001601000029000000400010043f00000060040000390000000001040433000000000101004b000015af0000c13d000000160100002900000a3c0110009c000000390000213d000013860000013d000000160100002900000a3b0110009c000000390000213d00000016020000290000004001200039000000400010043f00000001010000390000000001120436001500000001001d000000400100043d00000a3b0210009c000000390000213d0000004002100039000000400020043f000000200210003900000060030000390000000000320435000000000001043500000015020000290000000000120435000000400100043d00000a3b0210009c000000390000213d0000004002100039000000400020043f000000200210003900000000004204350000000202000039000000000021043500000016020000290000000002020433000000000202004b000015d60000613d0000001502000029000000000012043500000016010000290000000001010433000000000101004b0000138b0000c13d00000a5e01000041000000000010043500000032010000390000003c0000013d000000400300043d0000002007300039000000000800001900000000097800190000002008800039000000000a280019000000000a0a04330000000000a90435000000000968004b000015dd0000413d000000000551034f00000000026700190000001f0640018f00000000000204350000000507400272000015f30000613d00000000080000190000000509800210000000000a920019000000000995034f000000000909043b00000000009a04350000000108800039000000000978004b000015eb0000413d000000000806004b000016020000613d0000000507700210000000000575034f00000000077200190000000306600210000000000807043300000000086801cf000000000868022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000585019f0000000000570435000000000242001900000000000204350000000002320049000000200420008a00000000004304350000001f02200039000000200400008a000000000242016f0000000004320019000000000224004b00000000020000190000000102004039001b00000004001d000009ef0440009c000000390000213d0000000102200190000000390000c13d0000001b02000029000000400020043f0000000002030019000014b50000013d000000400300043d00000020083000390000000006000019000000190b00002900000000098600190000002006600039000000000ab60019000000000a0a04330000000000a90435000000000976004b0000161b0000413d000000000651034f00000000057800190000001f0740018f00000000000504350000000508400272000016310000613d0000000009000019000000050a900210000000000ba50019000000000aa6034f000000000a0a043b0000000000ab04350000000109900039000000000a89004b000016290000413d000000000907004b000016400000613d0000000508800210000000000686034f00000000088500190000000307700210000000000908043300000000097901cf000000000979022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000696019f0000000000680435000000000445001900000000000404350000000004340049000000200540008a00000000005304350000001f04400039000000200500008a000000000454016f0000000005340019000000000445004b00000000040000190000000104004039001b00000005001d000009ef0550009c000000390000213d0000000104400190000000390000c13d0000001b04000029000000400040043f001900000003001d000014b50000013d000000400100043d00000a3702000041000000000021043500000004021000390000000000e20435000000d30000013d0000001b020000290000000007020433000000000207004b000017750000c13d000009ef0230009c000000390000213d0000003f02300039000000200600008a000000000262016f000000400600043d0000000007260019000000000267004b00000000080000190000000108004039000009ef0270009c000000390000213d0000000102800190001b00000006001d000000390000c13d000000400070043f000000000751034f0000001f0530018f000000000136043600000005063002720000167d0000613d00000000080000190000000509800210000000000a910019000000000997034f000000000909043b00000000009a04350000000108800039000000000968004b000016750000413d000000000205004b0000168c0000613d0000000506600210000000000767034f00000000066100190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f000000000056043500000000013100190000000000010435000000400100043d001600000001001d000015a80000013d000000400100043d00000a3702000041000000000021043500000004021000390000000000920435000000d30000013d0000001001000029000000000101041a000009ef011001970000001202000029000000000012043500000019010000290000004001100270000a00ff00100194000016ce0000613d0000000a01000029000000ff0110008c000017060000613d00000009010000290000000101100039000000000301041a000000400200043d000800000002001d000600000003001d0000000002320436000700000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000605000029000000000205004b0000000704000029000016c30000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000016bc0000413d000000080140006a0000001f01100039000000200200008a000000000221016f0000000801200029000000000221004b00000000020000190000000102004039000009ef0310009c000016fd0000a13d000000390000013d0000001001000029000000000101041a0000004001100270000a00ff00100194000017060000613d00000010010000290000000101100039000000000301041a000000400200043d000800000002001d000600000003001d0000000002320436000700000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000605000029000000000205004b0000000704000029000016f30000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000016ec0000413d000000080140006a0000001f01100039000000200200008a000000000221016f0000000801200029000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f0000000e010000290000000802000029000000000021043500000011010000290000000a02000029000000000021043500000019010000290000004801100270000a00ff00100194000017b30000613d0000000a01000029000000ff0110008c000017f10000613d00000009010000290000000201100039000000000301041a000000400200043d001000000002001d000800000003001d0000000002320436000900000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000805000029000000000205004b00000009040000290000172d0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000017260000413d000000100140006a0000001f01100039000000200200008a000000000221016f0000001001200029000000000221004b00000000020000190000000102004039000009ef0310009c000017e30000a13d000000390000013d000000400600043d0000002008600039000000000900001900000000028900190000002009900039000000000a490019000000000a0a04330000000000a20435000000000279004b0000173b0000413d000000000451034f00000000017800190000001f0530018f00000000000104350000000507300272000017510000613d000000000800001900000005028002100000000009210019000000000224034f000000000202043b00000000002904350000000108800039000000000278004b000017490000413d000000000205004b000017600000613d0000000502700210000000000424034f00000000022100190000000305500210000000000702043300000000075701cf000000000757022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000474019f0000000000420435000000000131001900000000000104350000000001610049000000200210008a00000000002604350000001f01100039000000200200008a000000000121016f0000000002610019000000000112004b00000000010000190000000101004039001600000002001d000009ef0220009c000000390000213d0000000101100190000000390000c13d0000001601000029000000400010043f0000000004060019000015a80000013d000000400600043d000000200860003900000000090000190000001b0b00002900000000028900190000002009900039000000000ab90019000000000a0a04330000000000a20435000000000279004b000017790000413d000000000551034f00000000017800190000001f0730018f000000000001043500000005083002720000178f0000613d00000000090000190000000502900210000000000a210019000000000225034f000000000202043b00000000002a04350000000109900039000000000289004b000017870000413d000000000207004b0000179e0000613d0000000502800210000000000525034f00000000022100190000000307700210000000000802043300000000087801cf000000000878022f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f0000000000520435000000000131001900000000000104350000000001610049000000200210008a00000000002604350000001f01100039000000200200008a000000000121016f0000000002610019000000000112004b00000000010000190000000101004039001600000002001d000009ef0220009c000000390000213d0000000101100190000000390000c13d0000001601000029000000400010043f001b00000006001d000015a80000013d0000001001000029000000000101041a001900000001001d0000004801100270000a00ff00100194000017f10000613d00000010010000290000000201100039000000000301041a000000400200043d001000000002001d000800000003001d0000000002320436000900000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d0000000805000029000000000205004b0000000904000029000017d90000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000017d20000413d000000100140006a0000001f01100039000000200200008a000000000221016f0000001001200029000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f0000000d01000029000000100200002900000000002104350000000b010000290000000a02000029000000000021043500000019010000290000005001100270000000ff0110018f0000001302000029000000000012043500000011010000290000000001010433000000ff01100190000017f90000c13d00000013010000290000000001010433000000ff01100190000010450000613d00000016010000290000000001010433000000000101004b000018050000c13d000000400100043d00000a3c0210009c000000390000213d0000002002100039000000400020043f00000000000104350013000f0000002d0000180d0000013d00000015010000290000000001010433000000200110003900000000030104330000000001030433000000000201004b0013000f0000002d000018830000c13d00000011010000290000000001010433000000ff0110018f0000000b020000290000000002020433000000ff0220018f0000000001120019001000000001001d000000ff0110008c0000181b0000a13d00000a5e01000041000000000010043500000011010000390000003c0000013d000000100100006b000018fe0000c13d000000400100043d001600000001001d001500000000001d00000002010003670000001802100360000000000202043b001a00000002001d000000160200002900000a3b0220009c000000390000213d0000001401100360000000000101043b00000016030000290000004002300039000000400020043f0000000002030436001300000002001d0000000000020435000009e801100197001900000001001d000000000010043500000a4201000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b001200000001001d0000001a01000029000009ec0110019700000000001004350000000401000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b00000019020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000101041a000009e802100198000018630000c13d0000001202000029000000000202041a000009e802200197000000160300002900000000002304350000002001100270000009ec021001980000186c0000c13d0000001201000029000000000101041a0000002001100270000009ec0210019700000013010000290000000000210435000000400300043d0000002401300039001a00000003001d000000040330003900000016040000290000000004040433000009e8044001970000000c0540006b00001bf60000a13d00000a46020000410000001a0500002900000000002504350000000c0200002900000000002304350000000000410435000009e801000041000009e80250009c0000000005018019000000400150021000000a1f011001c70000279b000104300000000404300039000000040500008a000000010600008a000000000700001900000000020000190000000008000019000000000957004b000018170000213d0000000309700039000000000a91004b000021130000413d000000000a390019000000000a0a04330000ffff0aa0018f000000010ba0008c00001b820000a13d000000000b69004b000018170000613d000000000b91004b000018d00000a13d00000000074700190000000007070433000000ff0770018f000000ff0b70008c000020250000613d000000010b800039000000ff0bb0018f000000010770020f000000000c270170000000000b08c019000000000700c019000000000227019f00000000079a0019000000000817004b00000000080b0019000018890000413d000000400200043d001300000002001d000000000117004b00001b850000c13d000000ff01b0018f001500000001001d000000010110008c00001b900000c13d000000130100002900000a3b0110009c000000390000213d00000013050000290000004001500039000000400010043f0000002001500039000000600200003900000000002104350000001a020000290000000000250435000000000202004b000015d60000613d000000000031043500000013010000290000000001010433000000000101004b000015d60000613d000000400100043d00000a3b0210009c000000390000213d0000004002100039000000400020043f0000001a020000290000000002210436000000000500003100000002055003670000000005500350000000000505043b00000000005204350000000003030433000000040330008c00001d620000813d000000400100043d000000440210003900000a5b03000041000000000032043500000024021000390000001303000039000010b80000013d002100200000003d00000a5504000041000000100500002900000000004504350000001504000029000000000043043500000017030000290000000000320435000000640250003900000080030000390000000000320435000000440250003900000000001204350000001906000029000000000106043300000084025000390000000000120435000000a402500039000000000301004b000018f30000613d000000000300001900000000042300190000002003300039000000000563001900000000050504330000000000540435000000000413004b000018ec0000413d0000000002210019000000000002043500000000020004140000000f03000029000000040330008c000019bc0000c13d0000000103000031000000200130008c00000000040300190000002004008039000019f60000013d0000000003000019001500000000001d00000011010000290000000001010433000000ff0110018f000000000213004b001900000003001d0000190d0000813d0000000e0100002900000000020104330000000001020433000000000131004b0000000001030019000019150000213d000015d60000013d0000000001130049000000ff0210008c000018170000213d0000000d0200002900000000020204330000000003020433000000000313004b000015d60000a13d0000000501100210000000000121001900000020011000390000000001010433000009ec02100197000000400100043d00000a3c0310009c000000390000213d0000002003100039000000400030043f000000000001043500000013070000290000000003070433000000000403004b0000001908000029000019370000613d00000000040000190000000505400210000000200550003900000000067500190000000006060433000000ff0660018f000000000686004b000019310000613d0000000104400039000000000534004b000019260000413d000019370000013d0000000f010000290000000001010433000000000141004b000015d60000a13d0000000f01500029000000000101043300000012030000290000000003030433000000400800043d00000a410400004100000000004804350000001805000029000000020550036700000014060000290000000204600367000000000404043b000000000505043b000000640680003900000080070000390000000000760435000009ef0330019700000024068000390000000000360435000009ec0350019700000044058000390000000000350435000009e80340019700000004048000390000000000340435000000000301043300000084048000390000000000340435001a00000008001d000000a404800039000000000503004b0000195d0000613d000000000500001900000000064500190000002005500039000000000715001900000000070704330000000000760435000000000635004b000019560000413d000000000143001900000000000104350000000001000414000000040420008c000019670000c13d0000000103000031000000200130008c000000000403001900000020040080390000199f0000013d0000001f03300039000000200400008a000000000343016f0000001a05000029000009e80450009c000009e806000041000000000406001900000000040540190000004004400210000000a403300039000009e80530009c00000000030680190000006003300210000000000343019f000009e80410009c0000000001068019000000c001100210000000000131019f279927940000040f0000001a0900002900000000030100190000006003300270000009e803300197000000200430008c0000000004030019000000200400803900000005054002720000198c0000613d000000000600001900000005076002100000000008790019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000019840000413d0000001f064001900000199b0000613d0000000505500210000000000751034f0000001a055000290000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010220019000001bd90000613d0000001f01400039000000600110018f0000001a02100029000000000112004b00000000010000190000000101004039001600000002001d000009ef0220009c000000390000213d0000000101100190000000390000c13d0000001601000029000000400010043f000000200130008c000000680000413d0000001a010000290000000001010433001500150010002d000000150110006b000000000100001900000001010040390000000101100190000018170000c13d00000019010000290000000101100039000000ff0310018f000000100130006c000019000000413d000018200000013d0000001f01100039000000200300008a000000000131016f000009e8030000410000001005000029000009e80450009c000000000403001900000000040540190000004004400210000000a401100039000009e80510009c00000000010380190000006001100210000000000141019f000009e80420009c0000000002038019000000c002200210000000000112019f0000000f020000292799278f0000040f000000100a00002900000000030100190000006003300270000009e803300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000019e30000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000019db0000413d000000000705004b000019f20000613d0000000506600210000000000761034f00000010066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f0003000000010355000000010220019000001b650000613d0000001f01400039000000600210018f0000001001200029000000000221004b00000000020000190000000102004039000009ef0410009c000000390000213d0000000102200190000000390000c13d000000400010043f000000200230008c000000680000413d00000010020000290000000002020433001900000002001d000000000202004b00001a200000613d0000000f0100002900000000001004350000000501000039000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000301041a0000001902300029000000000332004b000000000300001900000001030040390000000103300190000018170000c13d000000000021041b000000400100043d0000002002100039000000190300002900000000003204350000000f020000290000000000210435000009e8020000410000000003000414000009e80430009c0000000003028019000009e80410009c00000000010280190000004001100210000000c002300210000000000112019f00000a12011001c70000800d020000390000000103000039001700000003001d00000a56040000412799278f0000040f0000000101200190000000680000613d00000000040000310000001a0140006a00000a1c02000041000000e00310008c0000000003000019000000000302401900000a1c01100197000000000501004b000000000200a01900000a1c0110009c000000000203c019000000000102004b000000680000c13d000000400100043d00000a570210009c000000390000213d000000e002100039000000400020043f0000001102000029000000c00320008a0000000206000367000000000236034f000000000202043b000009ef0520009c000000680000213d00000000022104360000002003300039000000000536034f000000000505043b000009e80750009c000000680000213d00000000005204350000002003300039000000000536034f000000000505043b000009ec0750009c000000680000213d0000004007100039001500000007001d00000000005704350000002007300039000000000376034f000000000303043b000009e80530009c000000680000213d0000006005100039001200000005001d00000000003504350000002003700039000000000336034f000000000303043b000000800510003900000000003504350000004003700039000000000336034f000000000803043b000000a00310003900000000008304350000006007700039000000000776034f000000000707043b000009ef0870009c000000680000213d0000001a097000290000001f0790003900000a1c08000041000000000a47004b000000000a000019000000000a08801900000a1c0770019700000a1c0b400197000000000cb7004b00000000080080190000000007b7013f00000a1c0770009c00000000080ac019000000000708004b000000680000c13d000000000796034f000000000707043b000009ef0870009c000000390000213d0000003f08700039000e0020000000920000000e0a80017f000000400800043d000000000aa80019000000000b8a004b000000000b000019000000010b004039000009ef0ca0009c000000390000213d000000010bb00190000000390000c13d000000200b9000390000004000a0043f0000000009780436000000000ab7001900000000044a004b000000680000213d0000000006b6034f0000001f0470018f000000050a70027200001aa70000613d000000000b000019000000050cb00210000000000dc90019000000000cc6034f000000000c0c043b0000000000cd0435000000010bb00039000000000cab004b00001a9f0000413d000000000b04004b00001ab60000613d000000050aa002100000000006a6034f000000000aa900190000000304400210000000000b0a0433000000000b4b01cf000000000b4b022f000000000606043b0000010004400089000000000646022f00000000044601cf0000000004b4019f00000000004a043500000000047900190000000000040435000000c00410003900000000008404350000001506000029000000000606043300000000050504330000000002020433000000120700002900000000070704330000000001010433000000400a00043d0000002008a0003900000a2c090000410000000000980435000000c0011002100000002108a000390000000000180435000000e0017002100000004d07a000390000000000170435000000e0012002100000002902a0003900000000001204350000005101a000390000000000510435000009ec016001970000002d02a000390000000000120435000000510100003900000000001a043500110000000a001d00000a1701a0009c000000390000213d00000011050000290000008001500039001000000001001d000000400010043f00000000040404330000000002030433000000a0015000390000000000210435000000c0035000390000000002040433000000000502004b00001aec0000613d000000000500001900000000063500190000002005500039000000000745001900000000070704330000000000760435000000000625004b00001ae50000413d000000000332001900000000000304350000002003200039000000100400002900000000003404350000005f022000390000000e0320017f0000000002430019000000000332004b00000000030000190000000103004039000009ef0420009c000000390000213d0000000103300190000000390000c13d000000400020043f000009e802000041000009e80310009c0000000001028019000000400110021000000010030000290000000003030433000009e80430009c00000000030280190000006003300210000000000113019f0000000003000414000009e80430009c0000000003028019000000c002300210000000000112019f000009f1011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000400000001001d00000015010000290000000001010433000609ec0010019b00000012010000290000000001010433000b09e80010019b000000400100043d000900000001001d00000a180110009c000000390000213d0000000903000029000000c001300039000000400010043f000000a0013000390000006002000039000300000001001d00000000002104350000008001300039000200000001001d000d00000002001d00000000002104350000006001300039000700000001001d00000000000104350000004001300039000100000001001d00000000000104350000000001030436000a00000001001d00000000000104350000000b01000029000000000010043500000a3d01000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000f00000001001d000000060100002900000000001004350000001701000029000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b0000000b020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000500000001001d000000000101041a001200000001001d000009ef0110019800001ebb0000613d000009ef0110009c000000120100002900001ec00000613d00001ebd0000013d000000400200043d0000001f0430018f000000050530027200001b720000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b00001b6a0000413d000000000604004b00001b810000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000008e30000013d000000400100043d00000a3f02000041000016930000013d00000a3f010000410000001303000029000000000013043500000004013000390000000000710435000009e801000041000009e80230009c0000000003018019000000400130021000000a38011001c70000279b00010430000000150100002900000005011002100000003f0210003900003fe00720018f0000001302700029000000130820006c00000000080000190000000108004039000009ef0920009c000000390000213d0000000108800190000000390000c13d000000400020043f0000001302000029000000150800002900000000028204360000001f0810018f000000050910027200001bae0000613d000000000a000031000000020aa00367000000000b000019000000050cb00210000000000dc20019000000000cca034f000000000c0c043b0000000000cd0435000000010bb00039000000000c9b004b00001ba60000413d000000000808004b00001bb00000613d000000400800043d0000000007780019000f00000008001d000000000887004b00000000080000190000000108004039000009ef0970009c000000390000213d0000000108800190000000390000c13d000000400070043f0000000f0700002900000015080000290000000000870435000000000708004b00001bc70000613d0000006007000039000000000800001900000020088000390000000f098000290000000000790435000000000918004b00001bc20000413d0000000001030433000000000701004b00001c8c0000c13d000000ff0e000039000000400400043d0000000003040436000000400030043f000000ff01e0018f000000ff0510008c00001d4f0000c13d00000a40010000410000000000130435000009e801000041000009e80230009c00000000030180190000004001300210000009ee011001c70000279b00010430000000400200043d0000001f0430018f000000050530027200001be60000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b00001bde0000413d000000000604004b00001bf50000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000008e30000013d00000a43040000410000001a0700002900000000004704350000001405000029000000020550036700000018060000290000000204600367000000000404043b000000000505043b000009e8055001970000000000530435000009ec03400197000000000031043500000064017000390000008003000039000000000031043500000044017000390000000c0300002900000000003104350000001b01000029000000000101043300000084037000390000000000130435000000a403700039000000000401004b00001c180000613d0000000004000019000000000534001900000020044000390000001b0640002900000000060604330000000000650435000000000514004b00001c110000413d000000000331001900000000000304350000000003000414000000040420008c00001c220000c13d0000000103000031000000200130008c0000000004030019000000200400803900001c5a0000013d0000001f01100039000000200400008a000000000141016f000009e8040000410000001a06000029000009e80560009c000000000504001900000000050640190000004005500210000000a401100039000009e80610009c00000000010480190000006001100210000000000151019f000009e80530009c0000000003048019000000c003300210000000000113019f279927940000040f00000000030100190000006003300270000009e803300197000000200430008c000000000403001900000020040080390000001f0540018f000000050640027200001c470000613d000000000700001900000005087002100000001a09800029000000000881034f000000000808043b00000000008904350000000107700039000000000867004b00001c3f0000413d000000000705004b00001c560000613d0000000506600210000000000761034f0000001a066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f0003000000010355000000010220019000001d320000613d0000001f01400039000000600110018f0000001a02100029000000000112004b00000000010000190000000101004039001900000002001d000009ef0220009c000000390000213d0000000101100190000000390000c13d0000001901000029000000400010043f000000200130008c000000680000413d0000001a010000290000000001010433001a00150010002d0000001a0110006b000000000100001900000001010040390000000101100190000018170000c13d0000000301000039000000000101041a001509ec0010019c0000000001000019001600000000001d00001d6b0000c13d001b001a0010002d0000001b0110006b000000000100001900000001010040390000000101100190000018170000c13d279925650000040f0000001b03000029000000000131043600000016020000290000000000210435000000400200043d000000000332043600000000010104330000000000130435000009e801000041000009e80320009c0000000002018019000000400120021000000a45011001c70000279a0001042e000000ff0e0000390000000007000019000000000c00001900001c9f0000013d00000016090000290000000a0b00002900000000009b04350000000f090000290000000009090433000000000119004b000000000c070019000000000e0a0019000015d60000a13d0000001a010000290000ffff0110018f00000000078100190000000001030433000000000817004b00001db70000813d000000000b0e0019000000000857004b000018170000213d0000000308700039000000000981004b000021130000413d000000000968004b000018170000613d000000000981004b000018d00000a13d00000000093800190000000009090433001a00000009001d0000000009470019000000000a090433000000ff0fb0018f000000ff09f0008c000000000e0a001900001c990000613d000000ff09a0018f0000000009f9004b000000000e0b001900001c990000613d0000000009c7004b000018170000413d000000000ec7004900100020000000920000001009e0006c000018170000213d000000000171004b00001dbf0000413d000000400100043d001900000001001d0000000001c7004b00001cc50000c13d0000001901000029000000000101043600001cd50000013d0000001f09e0019000000020099061bf0000001901900029000000000be10019000000000db1004b00001cd10000813d000000000c3c0019000000000c9c001900000000c90c043400000000019104360000000009b1004b00001ccd0000413d00000019090000290000000000e904350000001f01100039000000100110017f001600000001001d0000001601000029000000400010043f0000001301000029000000000b01043300000000010b004b000000000c070019000000000e0a001900001c990000613d000000010ff0003900000000010000190000000509100210000000200c9000390000001309c00029000000000d090433000000ff0ed0018f000000000def004b00001cef0000613d000000000d0e004b00001d270000613d00000001011000390000000009b1004b000000000c070019000000000e0a001900001ce00000413d00001c990000013d0000000f090000290000000009090433000000000919004b000015d60000a13d0000000f0cc000290000001609000029000000200b900039000a0000000c001d000000000f0c0433000000000e0f043300000000090e004b00001d030000613d000000000c0000190000000009bc0019000000200cc00039000000000dfc0019000000000d0d04330000000000d904350000000009ec004b00001cfc0000413d000000000bbe001900000000000b04350000001909000029000000000e09043300000000090e004b00001d110000613d000000000c0000190000000009bc0019000000200cc00039000000190dc00029000000000d0d04330000000000d904350000000009ec004b00001d0a0000413d0000000009be00190000000000090435000000160c0000290000000009c90049000000200b90008a0000000000bc04350000001f09900039000000100b90017f0000000009cb0019000000000bb9004b000000000b000019000000010b004039000009ef0c90009c000000390000213d000000010bb00190000000390000c13d000000400090043f0000000f090000290000000009090433000000000919004b00001c900000213d000015d60000013d0000000000f904350000000f090000290000000009090433000000000919004b000015d60000a13d0000000f0b0000290000000009bc0019000000190c0000290000000000c9043500000000090b043300001c950000013d000000400200043d0000001f0430018f000000050530027200001d3f0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b00001d370000413d000000000604004b00001d4e0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000008e30000013d00000013050000290000000005050433000000000605004b00001e090000613d000000010710003900000000010000190000000506100210000000200660003900000013086000290000000009080433000000ff0990018f000000000a97004b00001dc60000613d000000000909004b00001dfe0000613d0000000101100039000000000651004b00001d550000413d00001e090000013d0000000003010433000000000303004b000015d60000613d0000000003040433000000ff0330018f0000000000320435000f00130000002d001300000001001d0000180d0000013d0000001402000029000000020220036700000018030000290000000201300367000000000101043b000000000202043b000000190500002900000084035000390000001704000029000000000043043500000064035000390000001a040000290000000000430435000009e80220019700000044035000390000000000230435000000200350003900000a4402000041001800000003001d0000000000230435000009ec01100197000000240250003900000000001204350000008401000039000000000015043500000a180150009c000000390000213d0000001901000029000000c001100039000000400010043f00000a140100004100000000001004390000000001000412000000040010044300000040010000390000002400100443000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a15011001c70000800502000039279927940000040f00000001022001900000229c0000613d000000000101043b001600000001001d00000a1a010000410000000000100439000000150100002900000004001004430000000001000414000009e80210009c000009e801008041000000c00110021000000a1b011001c70000800202000039279927940000040f00000001022001900000229c0000613d000000400200043d001400000002001d000000000101043b000000000101004b00001e2e0000c13d000000140100002900000a3c0110009c000000390000213d00000014020000290000002001200039000000400010043f00000000000204350000000001000019001600000000001d00001c770000013d0000000004c7004b000018170000413d0000000006c70049000000200500008a000000000456004b000018170000213d000000000171004b00001e1b0000813d000000400100043d000000440210003900000a5903000041000000000032043500000024021000390000001103000039000010b80000013d0000000f050000290000000005050433000000000515004b000015d60000a13d0000000f05600029000000200630003900000000080504330000000007080433000000000907004b00001dd80000613d0000000009000019000000000a6900190000002009900039000000000b890019000000000b0b04330000000000ba0435000000000a79004b00001dd10000413d000000000667001900000000000604350000000007040433000000000807004b00001de50000613d000000000800001900000000096800190000002008800039000000000a480019000000000a0a04330000000000a90435000000000978004b00001dde0000413d000000000467001900000000000404350000000004340049000000200640008a00000000006304350000001f04400039000000200600008a000000000664016f0000000004360019000000000664004b00000000060000190000000106004039000009ef0740009c000000390000213d0000000106600190000000390000c13d000000400040043f0000000f040000290000000004040433000000000414004b000015d60000a13d00000000003504350000000f03000029000000000303043300001e070000013d00000000007804350000000f030000290000000003030433000000000313004b000015d60000a13d0000000f05000029000000000356001900000000004304350000000003050433000000000113004b000015d60000a13d000000150100006b0000180d0000613d000000000100001900000013030000290000000003030433000000000313004b000015d60000a13d000000050310021000000000032300190000000004030433000000010440008a000000ff0440018f00000000004304350000000101100039000000ff0110018f000000150310006c00001e0c0000413d0000180d0000013d000000400400043d0000000001c7004b00001bcc0000613d0000001f0860019000000020088061bf00000000018400190000000007610019000000000971004b00001e2a0000813d00000000033c0019000000000383001900000000380304340000000001810436000000000871004b00001e260000413d00000000006404350000001f01100039000000000351016f00001bcd0000013d000000140100002900000a3b0110009c000000390000213d00000014020000290000004001200039000000400010043f00000020010000390000000002120436000000000100003100000002011003670000000001100350000000000101043b001b00000002001d00000000001204350000001501000029000000040110008c00001e610000c13d0000000103000031000000200130008c00000020030080390000000301000367000000140200002900000000003204350000001f0230018f000000050330027200001e510000613d000000000400001900000005054002100000001b06500029000000000551034f000000000505043b00000000005604350000000104400039000000000534004b00001e490000413d000000000402004b00001e9b0000613d0000000503300210000000000131034f0000001b033000290000000302200210000000000403043300000000042401cf000000000424022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000141019f000000000013043500001e9b0000013d000009e8010000410000001803000029000009e80230009c0000000003018019000000400230021000000019030000290000000003030433000009e80430009c00000000030180190000006003300210000000000223019f0000001604000029000009e80340009c0000000004018019000000c001400210000000000112019f0000001502000029279927940000040f000300000001035500000000030100190000006003300270000109e80030019d000009e804300197000000200340008c0000002004008039000000140300002900000000004304350000001f0340018f000000050440027200001e880000613d000000000500001900000005065002100000001b07600029000000000661034f000000000606043b00000000006704350000000105500039000000000645004b00001e800000413d000000000503004b00001e970000613d0000000504400210000000000141034f0000001b044000290000000303300210000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f000000000014043500000001012001900000000001000019001600000000001d00001c770000613d00000014010000290000000002010433000000200120008c0000000001000019001600000000001d00001c770000413d00000a1c01000041000000200320008c0000000003000019000000000301401900000a1c02200197000000000402004b000000000100a01900000a1c0220009c000000000103c019000000000101004b000000680000c13d0000001b010000290000000001010433001600000001001d000000170100006b000000000100001900001c770000c13d0000000201000039000000000101041a0000001a0210006c0000001a0100a029000000160210006b00000000030100190000001603004029000000000103001900001db50000013d0000000f01000029000000000101041a000009ef011001970000000902000029000000000012043500000012010000290000004001100270000800ff0010019400001ef20000613d0000000801000029000000ff0110008c00001f2a0000613d00000005010000290000000101100039000000000301041a000000400200043d000c00000002001d001500000003001d0000000002320436001a00000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000150200006b00001ee70000613d000000000101043b0000000002000019000000000301041a000009ec033001970000001a040000290000000004340436001a00000004001d00000001011000390000000102200039000000150320006c00001ede0000413d0000001a010000290000000c0110006a0000001f011000390000000e0210017f0000000c01200029000000000221004b00000000020000190000000102004039000009ef0310009c00001f210000a13d000000390000013d0000000f01000029000000000101041a0000004001100270000800ff0010019400001f2a0000613d0000000f010000290000000101100039000000000301041a000000400200043d000c00000002001d001500000003001d0000000002320436001a00000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000150200006b00001f170000613d000000000101043b0000000002000019000000000301041a000009ec033001970000001a040000290000000004340436001a00000004001d00000001011000390000000102200039000000150320006c00001f0e0000413d0000001a010000290000000c0110006a0000001f011000390000000e0210017f0000000c01200029000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f00000002010000290000000c0200002900000000002104350000000a010000290000000802000029000000000021043500000012010000290000004801100270000c00ff0010019400001f5c0000613d0000000c01000029000000ff0110008c00001f9a0000613d00000005010000290000000201100039000000000301041a000000400200043d000f00000002001d001500000003001d0000000002320436001a00000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000150200006b00001f510000613d000000000101043b0000000002000019000000000301041a000009ec033001970000001a040000290000000004340436001a00000004001d00000001011000390000000102200039000000150320006c00001f480000413d0000001a010000290000000f0110006a0000001f011000390000000e0210017f0000000f01200029000000000221004b00000000020000190000000102004039000009ef0310009c00001f8c0000a13d000000390000013d0000000f01000029000000000101041a001200000001001d0000004801100270000c00ff0010019400001f9a0000613d0000000f010000290000000201100039000000000301041a000000400200043d000f00000002001d001500000003001d0000000002320436001a00000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000000680000613d000000150200006b00001f820000613d000000000101043b0000000002000019000000000301041a000009ec033001970000001a040000290000000004340436001a00000004001d00000001011000390000000102200039000000150320006c00001f790000413d0000001a010000290000000f0110006a0000001f011000390000000e0210017f0000000f01200029000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f00000003010000290000000f02000029000000000021043500000001010000290000000c02000029000000000021043500000012010000290000005001100270000000ff0110018f000000070200002900000000001204350000000a010000290000000001010433000000ff0110019000001fa20000c13d00000007010000290000000001010433000000ff01100190000010450000613d0000001b010000290000000012010434000000000202004b00001fad0000c13d000000400300043d00000a3c0130009c000000390000213d0000002001300039000000400010043f000000000003043500001fb00000013d000000000101043300000020011000390000000003010433000000400100043d000800000001001d00000a580110009c000000390000213d000000090100002900000000010104330000000804000029000000a002400039000000400020043f0000008002400039000700000002001d00000006050000290000000000520435000009ef011001970000006002400039000600000002001d00000000001204350000004001400039000500000001001d000000040200002900000000002104350000000b0100002900000000021404360000001101000029000400000002001d00000000001204350000000001030433000000000201004b0015000d0000002d000021930000613d0000000404300039000000040500008a000000000700001900000000020000190000000008000019000000000657004b000018170000213d0000000309700039000000000691004b000021130000413d000000000639001900000000060604330000ffff0a60018f0000000106a0008c00001b820000a13d000000010600008a000000000b69004b000018170000613d000000000b91004b000018d00000a13d00000000074700190000000007070433000000ff0770018f000000ff0b70008c000020250000613d000000010b800039000000ff0bb0018f000000010770020f000000000c270170000000000b08c019000000000700c019000000000227019f00000000079a0019000000000817004b00000000080b001900001fd30000413d000000400200043d001500000002001d000000000117004b000020280000c13d000000ff01b0018f001b00000001001d000000010110008c000000150100002900000020011000390000202b0000c13d000000150200002900000a3b0220009c000000390000213d00000015050000290000004002500039000000400020043f0000006002000039000000000021043500000017020000290000000000250435000000000202004b000015d60000613d000000000031043500000015010000290000000001010433000000000101004b000015d60000613d000000400100043d00000a3b0210009c000000390000213d0000004002100039000000400020043f00000017020000290000000002210436000000000500003100000002055003670000000005500350000000000505043b00000000005204350000000003030433000000040330008c000018d00000413d0000000003010433000000000303004b000015d60000613d0000000003040433000000ff0330018f0000000000320435000d00150000002d001500000001001d000021930000013d000000400100043d00000a400200004100000c400000013d00000a3f01000041000000150300002900001b870000013d0000001b0200002900000005072002100000003f0270003900003fe00820018f0000001502800029000000150920006c00000000090000190000000109004039000009ef0a20009c000000390000213d0000000109900190000000390000c13d000000400020043f00000015020000290000001b0900002900000000009204350000001f0270018f0000000509700272000020490000613d000000000a000031000000020aa00367000000000b000019000000050cb00210000000000dc10019000000000cca034f000000000c0c043b0000000000cd0435000000010bb00039000000000c9b004b000020410000413d000000000202004b0000204b0000613d000000400900043d0000000002890019000d00000009001d000000000892004b00000000080000190000000108004039000009ef0920009c000000390000213d0000000108800190000000390000c13d000000400020043f0000000d020000290000001b080000290000000000820435000000000208004b000020620000613d0000006002000039000000000800001900000020088000390000000d098000290000000000290435000000000978004b0000205d0000413d000000000b03043300000000020b004b000020680000c13d000000ff0e000039000000400400043d000021110000013d000000ff0e0000390000000007000019000000000c000019000000000d0e0019000000000257004b000018170000213d000000030870003900000000028b004b000021130000413d000000000268004b000018170000613d00000000028b004b000018d00000a13d00000000023800190000000002020433001200000002001d0000000002470019000000000e020433000000ff0fd0018f000000ff02f0008c001a0000000e001d000021010000613d0000001a02000029000000ff0220018f0000000002f2004b000000000e0d0019000021010000613d0000000002c7004b000018170000413d000000000dc700490000000e02d0006c000018170000213d00000000027b004b00001dbf0000413d000000400200043d001700000002001d0000000002c7004b000020910000c13d0000001702000029000000000d020436000020a10000013d0000001f0ed00190000000200ee061bf0000001702e000290000000009d20019000000000b92004b0000209d0000813d000000000b3c0019000000000ceb001900000000cb0c04340000000002b20436000000000b92004b000020990000413d00000017090000290000000000d904350000001f022000390000000e0d20017f0000004000d0043f00000015020000290000000009020433000000000209004b000000000c0700190000001a0e000029000021010000613d0000000102f00039000000000f000019000000050bf00210000000200cb00039000000150ec00029000000000b0e0433000000ff0bb0018f000000000ab2004b000020b90000613d000000000a0b004b000020f30000613d000000010ff00039000000000a9f004b000000000c0700190000001a0e000029000020aa0000413d000021010000013d0000000d0200002900000000020204330000000002f2004b000015d60000a13d0000000d09c000290000002002d00039000f00000009001d000000000e09043300000000090e0433000000000a09004b000020cc0000613d000000000c000019000000000a2c0019000000200cc00039000000000bec0019000000000b0b04330000000000ba0435000000000a9c004b000020c50000413d0000000002290019000000000002043500000017090000290000000009090433000000000a09004b000020da0000613d000000000c000019000000000a2c0019000000200cc00039000000170bc00029000000000b0b04330000000000ba0435000000000a9c004b000020d30000413d000000000229001900000000000204350000000002d20049000000200920008a00000000009d04350000001f022000390000000e0920017f0000000002d90019000000000992004b00000000090000190000000109004039000009ef0a20009c000000390000213d0000000109900190000000390000c13d000000400020043f0000000d0200002900000000020204330000000002f2004b000015d60000a13d0000000f020000290000000000d204350000000d020000290000000002020433000020fd0000013d00000000002e04350000000d0200002900000000020204330000000002f2004b000015d60000a13d0000000d0900002900000000029c0019000000170a0000290000000000a2043500000000020904330000000002f2004b000000000c0700190000001a0e000029000015d60000a13d00000012020000290000ffff0220018f0000000007820019000000000b0304330000000002b7004b0000206b0000413d0000000002c7004b000018170000413d0000000005c700490000000e0250006c000018170000213d00000000027b004b00001dbf0000413d000000400400043d0000000002c7004b0000211a0000c13d0000000003040436000021290000013d000000400100043d000000440210003900000a5c03000041000000000032043500000024021000390000001403000039000010b80000013d0000001f0750019000000020077061bf00000000027400190000000006520019000000000862004b000021260000813d00000000033c0019000000000373001900000000370304340000000002720436000000000762004b000021220000413d00000000005404350000001f022000390000000e0320017f000000400030043f000000ff02e0018f000000ff0520008c00001bd10000613d00000015050000290000000006050433000000000506004b000021820000613d000000010720003900000000050000190000000502500210000000200220003900000015082000290000000009080433000000ff0990018f000000000a97004b000021400000613d000000000909004b000021770000613d0000000105500039000000000265004b000021330000413d000021820000013d0000000d060000290000000006060433000000000656004b000015d60000a13d0000000d06200029000000200230003900000000080604330000000007080433000000000907004b000021520000613d0000000009000019000000000a2900190000002009900039000000000b890019000000000b0b04330000000000ba0435000000000a79004b0000214b0000413d000000000227001900000000000204350000000007040433000000000807004b0000215f0000613d000000000800001900000000092800190000002008800039000000000a480019000000000a0a04330000000000a90435000000000978004b000021580000413d000000000227001900000000000204350000000002320049000000200420008a00000000004304350000001f022000390000000e0420017f0000000002340019000000000442004b00000000040000190000000104004039000009ef0720009c000000390000213d0000000104400190000000390000c13d000000400020043f0000000d020000290000000002020433000000000252004b000015d60000a13d00000000003604350000000d020000290000000002020433000021800000013d00000000007804350000000d030000290000000003030433000000000353004b000015d60000a13d0000000d03000029000000000232001900000000004204350000000002030433000000000252004b000015d60000a13d0000001b0200006b000021930000613d000000000200001900000015030000290000000003030433000000000323004b000015d60000a13d000000050320021000000000031300190000000004030433000000010440008a000000ff0440018f00000000004304350000000102200039000000ff0220018f0000001b0320006c000021850000413d0000000a010000290000000001010433000000ff0110018f00000001020000290000000002020433000000ff0220018f0000000001120019000900000001001d000000ff0110008c000018170000213d000000090100002900000005021002100000003f0120003900007fe00110018f000000400300043d0000000001130019001200000003001d000000000331004b00000000030000190000000103004039000009ef0410009c000000390000213d0000000103300190000000390000c13d000000400010043f000000120100002900000009030000290000000001310436001700000001001d0000001f0120018f0000000502200272000021be0000613d00000000030000310000000203300367000000000400001900000005054002100000001706500029000000000553034f000000000505043b00000000005604350000000104400039000000000524004b000021b60000413d000000000101004b000021c00000613d000000090100006b000b00000000001d0000229d0000c13d000000400100043d001b00000001001d000000200110003900000011020000290000000002020433000000000302004b000021d20000613d000000000300001900000000041300190000002003300039000000110530002900000000050504330000000000540435000000000423004b000021cb0000413d0000000001120019000000000001043500000010020000290000000002020433000000000302004b000021e00000613d000000000300001900000000041300190000002003300039000000100530002900000000050504330000000000540435000000000423004b000021d90000413d000000000112001900000000000104350000001b030000290000000001310049000000200210008a00000000002304350000001f011000390000000e0210017f0000000001320019000000000221004b00000000020000190000000102004039000009ef0310009c000000390000213d0000000102200190000000390000c13d000000400010043f00000003020000290000000002020433000000020300002900000000040304330000006003000039001500000003001d00000000033104360000006005100039000000000604043300000000006504350000008005100039000000000706004b000022060000613d000000000700001900000020044000390000000008040433000009ec0880019700000000058504360000000107700039000000000867004b000021ff0000413d0000000004150049000000000043043500000000040204330000000003450436000000000504004b000022140000613d000000000500001900000020022000390000000006020433000009ec0660019700000000036304360000000105500039000000000645004b0000220d0000413d000000000213004900000040041000390000000000240435000000120200002900000000040204330000000002430436000000000304004b000022250000613d000000000300001900000012050000290000002005500039001200000005001d000000000505043300000000025204360000000103300039000000000543004b0000221d0000413d0000000002120049000009e803000041000009e80410009c00000000010380190000004001100210000009e80420009c00000000020380190000006002200210000000000112019f0000000002000414000009e80420009c0000000002038019000000c002200210000000000121019f000009f1011001c70000800d02000039000000010300003900000a5f040000412799278f0000040f0000000101200190000000680000613d0020001b0000002d0000000b02000029001900190020002d000000190120006b000000000100001900000001010040390000000101100190000018170000c13d001f00190000002d00000002020003670000001801200360000000000101043b000009ec0310009c000000680000213d0000001302200360000000000302043b000009e80230009c000000680000213d0000000002000415001300000002001d0000000302000039001200000002001d000000000202041a001809ec0020019c00000000040000190000000002000019000024750000613d000000400500043d00000084025000390000001604000029000000000042043500000064025000390000001904000029000000000042043500000044025000390000000000320435000000200350003900000a6002000041001100000003001d00000000002304350000002402500039000000000012043500000084010000390000000000150435001700000005001d00000a180150009c000000390000213d0000001701000029000000c001100039000000400010043f00000a140100004100000000001004390000001401000029000000040010044300000040010000390000002400100443000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a15011001c70000800502000039279927940000040f00000001022001900000229c0000613d000000000101043b001400000001001d00000a1a010000410000000000100439000000180100002900000004001004430000000001000414000009e80210009c000009e801008041000000c00110021000000a1b011001c70000800202000039279927940000040f00000001022001900000229c0000613d000000400200043d001a00000002001d000000000101043b000000000101004b000023a20000c13d0000001a0100002900000a3c0110009c000000390000213d0000001a020000290000002001200039000000400010043f000000000002043500000000010004150000001e0110008a00000020011000c90000000002000019000024710000013d000000000001042f001b00000000001d000b00000000001d000022a60000013d0000001b010000290000000101100039000000ff0210018f001b00000002001d000000090120006c000021c30000813d0000000a010000290000000001010433000000ff0110018f0000001b0210006b000022b20000813d0000000201000029000000000201043300000000010204330000001b0110006c0000001b01000029000022ba0000213d000015d60000013d0000001b01100069000000ff0210008c000018170000213d000000030200002900000000020204330000000003020433000000000313004b000015d60000a13d0000000501100210000000000121001900000020011000390000000001010433000f09ec0010019b000000400100043d00000a3c0210009c000000390000213d0000002002100039000000400020043f000000000001043500000015020000290000000002020433000000000302004b000022db0000613d00000000030000190000000504300210000000200440003900000015054000290000000005050433000000ff0550018f0000001b0550006c000022d50000613d0000000103300039000000000423004b000022ca0000413d000022db0000013d0000000d010000290000000001010433000000000131004b000015d60000a13d0000000d014000290000000001010433000000400600043d00000a5d02000041000000000026043500000004026000390000004003000039000000000032043500000008030000290000000003030433000009e80330019700000044046000390000000000340435000000040300002900000000050304330000006403600039000000a0040000390000000000430435000000e40460003900000000030504330000000000340435001a00000006001d0000010404600039000000000603004b000022fa0000613d000000000600001900000000074600190000002006600039000000000856001900000000080804330000000000870435000000000736004b000022f30000413d00000000054300190000000000050435000000050500002900000000050504330000001a070000290000008406700039000000000056043500000006050000290000000005050433000009ef05500197000000a40670003900000000005604350000001f033000390000000e0330017f000000000443001900000000022400490000000703000029000000000303043300000024057000390000000000250435000000c402700039000009ec03300197000000000032043500000000030104330000000002340436000000000403004b0000231d0000613d000000000400001900000000052400190000002004400039000000000614001900000000060604330000000000650435000000000534004b000023160000413d0000000001230019000000000001043500000000010004140000000f04000029000000040440008c000023280000c13d0000000103000031000000200130008c00000000040300190000002004008039000023600000013d0000001f033000390000000e0330017f0000001a0500002900000000025200490000000002320019000009e80320009c000009e80400004100000000020480190000006002200210000009e80350009c000000000304001900000000030540190000004003300210000000000232019f000009e80310009c0000000001048019000000c001100210000000000121019f0000000f020000292799278f0000040f00000000030100190000006003300270000009e803300197000000200430008c0000000004030019000000200400803900000005054002720000234d0000613d000000000600001900000005076002100000001a08700029000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000023450000413d0000001f064001900000235c0000613d0000000505500210000000000751034f0000001a055000290000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000102200190000023db0000613d0000001f01400039000000600210018f0000001a01200029000000000221004b00000000020000190000000102004039000009ef0410009c000000390000213d0000000102200190000000390000c13d000000400010043f000000200130008c000000680000413d000000120100002900000000010104330000001b0110006c000015d60000a13d0000001a0100002900000000040104330000001b0300002900000005013002100000001701100029000c00000001001d001a00000004001d000000000041043500000012010000290000000001010433000000000131004b000015d60000a13d0000001a0100006b000022a00000613d0000000f0100002900000000001004350000000501000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000301041a0000001a02300029000000000332004b000000000300001900000001030040390000000103300190000018170000c13d000000000021041b000000120100002900000000010104330000001b0110006c000015d60000a13d0000000c010000290000000001010433000b000b0010002d0000000b0110006b000000000100001900000001010040390000000101100190000022a00000613d000018170000013d0000001a0100002900000a3b0110009c000000390000213d0000001a020000290000004001200039000000400010043f00000020010000390000000002120436000000000100003100000002011003670000000001100350000000000101043b001b00000002001d00000000001204350000001801000029000000040110008c000023f80000c13d0000000101000031000000200210008c000000200100803900000003020003670000001a0300002900000000001304350000001f0310018f0000000504100272000023c50000613d000000000100001900000005051002100000001b06500029000000000552034f000000000505043b00000000005604350000000101100039000000000541004b000023bd0000413d00000000010004150000001d0110008a00000020011000c9000000000503004b000024340000613d0000000501400210000000000212034f0000001b011000290000000303300210000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f000000000021043500000000010004150000001d0110008a00000020011000c9000024340000013d000000400200043d0000001f0430018f0000000505300272000023e80000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000023e00000413d000000000604004b000023f70000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000008e30000013d000009e8010000410000001103000029000009e80230009c0000000003018019000000400230021000000017030000290000000003030433000009e80430009c00000000030180190000006003300210000000000223019f0000001404000029000009e80340009c0000000004018019000000c001400210000000000112019f00000018020000292799278f0000040f000300000001035500000000030100190000006003300270000109e80030019d000009e804300197000000200340008c00000020040080390000001a0300002900000000004304350000001f0340018f00000005044002720000241f0000613d000000000500001900000005065002100000001b07600029000000000661034f000000000606043b00000000006704350000000105500039000000000645004b000024170000413d000000000503004b0000242e0000613d0000000504400210000000000141034f0000001b044000290000000303300210000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f000000000014043500000000010004150000001c0110008a00000020011000c900000001022001900000000002000019000024710000613d0000001a020000290000000003020433000000200230008c0000000002000019000024710000413d00000a1c02000041000000200430008c0000000004000019000000000402401900000a1c03300197000000000503004b000000000200a01900000a1c0330009c000000000204c019000000000202004b000000680000c13d0000001b020000290000000002020433000000160300006b000024710000c13d0000000203000039000000000303041a000000190430006c000000190300a029000000000432004b00000000020380190000000501100270000000000102001f001b00000002001d000000000102004b00000000040000190000000002000019000024750000613d0000001201000029000000000101041a000009ec0110019700000000001004350000000501000039000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000000680000613d000000000101043b000000000301041a0000001b02300029000000000332004b000000000300001900000001030040390000000103300190000018170000c13d000000000021041b0000001b040000290000000002000019000024750000013d0000000501100270000000000100001f0019001f0000002d00000000040000190000000001000415000000130110006900000000010000020000001901400029000000000341004b000000000300001900000001030040390000000103300190000018170000c13d000000400300043d00000a3b0430009c000000390000213d0000004004300039000000400040043f00000000041304360000002101300029000000000021043500000000030304330000002002000029000000400100043d0000000003310436000000000404043300000040051000390000001506000029000000000065043500000000004304350000006004100039000000000302043300000000003404350000008004100039000000000503004b0000249d0000613d000000000500001900000000064500190000002005500039000000000725001900000000070704330000000000760435000000000635004b000024960000413d000000000243001900000000000204350000009f023000390000000e0220017f000009e803000041000009e80420009c0000000002038019000009e80410009c000000000103801900000040011002100000006002200210000000000112019f0000279a0001042e000000040110008a00000a1c020000410000003f0310008c0000000003000019000000000302201900000a1c01100197000000000401004b000000000200801900000a1c0110009c000000000203c019000000000102004b000024c00000613d00000002020003670000000401200370000000000101043b000009ec0310009c000024c00000213d0000002402200370000000000202043b000009e80320009c000024c00000213d000000000001042d00000000010000190000279b000104300000000031010434000009e80110019700000000011204360000000002030433000009ec022001970000000000210435000000000001042d0000000043010434000009ef0330019700000000033204360000000004040433000000ff0440018f000000000043043500000040031000390000000003030433000000ff0330018f0000004004200039000000000034043500000060031000390000000003030433000000ff0330018f00000060042000390000000000340435000000800310003900000000040304330000008003200039000000c0050000390000000000530435000000c00320003900000000050404330000000000530435000000e003200039000000000605004b000024ec0000613d000000000600001900000020044000390000000007040433000009ec0770019700000000037304360000000106600039000000000756004b000024e50000413d000000a00110003900000000040104330000000001230049000000a002200039000000000012043500000000020404330000000001230436000000000302004b000024fd0000613d000000000300001900000020044000390000000005040433000009ec0550019700000000015104360000000103300039000000000523004b000024f60000413d000000000001042d000000200300003900000000033104360000000054020434000009ef0440019700000000004304350000000004050433000000ff0440018f0000004005100039000000000045043500000040042000390000000004040433000000ff0440018f0000006005100039000000000045043500000060042000390000000004040433000000ff0440018f0000008005100039000000000045043500000080042000390000000005040433000000a004100039000000c0060000390000000000640435000000e004100039000000000605043300000000006404350000010004100039000000000706004b000025240000613d000000000700001900000020055000390000000008050433000009ec0880019700000000048404360000000107700039000000000867004b0000251d0000413d0000000003340049000000a0022000390000000002020433000000c001100039000000000031043500000000030204330000000001340436000000000403004b000025350000613d000000000400001900000020022000390000000005020433000009ec0550019700000000015104360000000104400039000000000534004b0000252e0000413d000000000001042d00000000030104330000000002320436000000000403004b000025420000613d000000000400001900000000052400190000002004400039000000000614001900000000060604330000000000650435000000000534004b0000253b0000413d000000000123001900000000000104350000001f01300039000000200300008a000000000131016f0000000001120019000000000001042d000009e8022001970000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000025580000613d000000000101043b000000000001042d00000000010000190000279b0001043000000a800210009c0000255f0000813d000000c001100039000000400010043f000000000001042d00000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b00010430000000400100043d00000a810210009c0000256b0000813d0000004002100039000000400020043f000000000001042d00000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b000104300005000000000002000500000001001d000000400300043d00000a810130009c000025be0000813d0000004001300039000000400010043f000300000003001d0000000001030436000200000001001d0000000000010435000009e801200197000400000001001d000000000010043500000a4201000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000025bc0000613d000000000101043b000100000001001d0000000501000029000009ec0110019700000000001004350000000401000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000025bc0000613d000000000101043b00000004020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000025bc0000613d000000000101043b000000000301041a000009e802300198000025b00000c13d0000000101000029000000000201041a000009e802200197000000030100002900000000002104350000002002300270000009ec02200198000025b90000c13d0000000102000029000000000202041a0000002002200270000009ec0220019700000002030000290000000000230435000000000001042d00000000010000190000279b0001043000000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b00010430000000400100043d00000a800210009c000025d60000813d000000c002100039000000400020043f000000a00210003900000060030000390000000000320435000000800210003900000000003204350000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000000001042d00000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b000104300003000000000002000000000301041a000000400200043d000300000002001d000100000003001d0000000002320436000200000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f00000001022001900000260a0000613d0000000105000029000000000205004b0000000204000029000025fb0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000025f40000413d000000030100002900000000021400490000001f03200039000000200200008a000000000223016f0000000004120019000000000224004b00000000020000190000000102004039000009ef0340009c0000260c0000213d00000001022001900000260c0000c13d000000400040043f000000000001042d00000000010000190000279b0001043000000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b00010430000d000000000002000a00000001001d000000400100043d000d00000001001d00000a800110009c000027530000813d0000000d03000029000000c001300039000000400010043f000000a0043000390000006001000039000600000004001d00000000001404350000008004300039000700000004001d00000000001404350000006001300039000800000001001d00000000000104350000004001300039000500000001001d00000000000104350000000001030436000b00000001001d0000000000010435000009e801200197000900000001001d000000000010043500000a3d01000041000000200010043f000009e8030000410000000001000414000009e80210009c0000000001038019000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000027510000613d000000000101043b000c00000001001d0000000a01000029000009ec0110019700000000001004350000000101000039000000200010043f0000000001000414000009e80210009c000009e801008041000000c00110021000000a12011001c70000801002000039279927940000040f0000000102200190000027510000613d000000000101043b00000009020000290000000000200435000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000027510000613d000000000501043b000000000305041a000009ef01300198000026610000613d000009ef0110009c00000000010300190000000c04000029000026660000613d000026630000013d0000000c04000029000000000104041a000009ef011001970000000d0200002900000000001204350000004001300270000000ff021001900000269b0000613d000000ff0120008c000026d70000613d000300000002001d000a00000003001d000900000005001d0000000101500039000000000301041a000000400200043d000400000002001d000100000003001d0000000002320436000200000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000027510000613d0000000105000029000000000205004b00000002040000290000268d0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000026860000413d000000040600002900000000016400490000001f01100039000000200200008a000000000221016f0000000001620019000000000221004b00000000020000190000000102004039000009ef0310009c0000000c040000290000000905000029000026ce0000a13d000027530000013d000000000104041a0000004001100270000000ff01100190000026d70000613d000300000001001d000900000005001d000a00000003001d0000000101400039000000000301041a000000400200043d000400000002001d000100000003001d0000000002320436000200000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000027510000613d0000000105000029000000000205004b0000000204000029000026c10000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000434043600000001011000390000000102200039000000000352004b000026ba0000413d000000040600002900000000016400490000001f01100039000000200200008a000000000221016f0000000001620019000000000221004b00000000020000190000000102004039000009ef0310009c0000000c040000290000000905000029000027530000213d0000000102200190000027530000c13d000000400010043f000000070100002900000000006104350000000b01000029000000030200002900000000002104350000000a030000290000004801300270000000ff021001900000270a0000613d000000ff0120008c000027470000613d000c00000002001d000a00000003001d0000000201500039000000000301041a000000400200043d000900000002001d000400000003001d0000000002320436000700000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000027510000613d0000000404000029000000000204004b0000000705000029000026fd0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000535043600000001011000390000000102200039000000000342004b000026f60000413d000000090400002900000000014500490000001f01100039000000200200008a000000000221016f0000000001420019000000000221004b00000000020000190000000102004039000009ef0310009c0000000c030000290000273b0000a13d000027530000013d000000000204041a0000004801200270000000ff01100190000027470000613d000c00000001001d000a00000002001d0000000201400039000000000301041a000000400200043d000900000002001d000400000003001d0000000002320436000700000002001d0000000000100435000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a3e011001c70000801002000039279927940000040f0000000102200190000027510000613d0000000404000029000000000204004b00000007050000290000272f0000613d000000000101043b0000000002000019000000000301041a000009ec03300197000000000535043600000001011000390000000102200039000000000342004b000027280000413d000000090400002900000000014500490000001f01100039000000200200008a000000000221016f0000000001420019000000000221004b00000000020000190000000102004039000009ef0310009c0000000c03000029000027530000213d0000000102200190000027530000c13d000000400010043f00000006010000290000000000410435000000050100002900000000003104350000000a010000290000005001100270000000ff0110018f000000080200002900000000001204350000000b010000290000000001010433000000ff011001900000274f0000c13d00000008010000290000000001010433000000ff01100190000027590000613d0000000d01000029000000000001042d00000000010000190000279b0001043000000a5e0100004100000000001004350000004101000039000000040010043f00000a38010000410000279b00010430000000400100043d00000a6d020000410000000000210435000009e802000041000009e80310009c00000000010280190000004001100210000009ee011001c70000279b00010430000009e801100197000000000010043500000a3d01000041000000200010043f000009e8010000410000000002000414000009e80320009c0000000002018019000000c00120021000000a12011001c70000801002000039279927940000040f0000000102200190000027760000613d000000000101043b000000000101041a00000a6a011001980000000001000019000000010100c039000000000001042d00000000010000190000279b00010430000000000001042f000009e803000041000009e80410009c00000000010380190000004001100210000009e80420009c00000000020380190000006002200210000000000112019f0000000002000414000009e80420009c0000000002038019000000c002200210000000000112019f000009f1011001c70000801002000039279927940000040f00000001022001900000278d0000613d000000000101043b000000000001042d00000000010000190000279b0001043000002792002104210000000102000039000000000001042d0000000002000019000000000001042d00002797002104230000000102000039000000000001042d0000000002000019000000000001042d00002799000004320000279a0001042e0000279b00010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000df00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff416ecebf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e000000002000000000000000000000000000001000000010000000000000000000000000000000000000000000000000000000000000000000000000061d027b200000000000000000000000000000000000000000000000000000000d15b0d4800000000000000000000000000000000000000000000000000000000f2fde38a00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000faaebd2100000000000000000000000000000000000000000000000000000000fd9be52200000000000000000000000000000000000000000000000000000000d15b0d4900000000000000000000000000000000000000000000000000000000d80e9bd900000000000000000000000000000000000000000000000000000000f0f44260000000000000000000000000000000000000000000000000000000008da5cb5a000000000000000000000000000000000000000000000000000000008da5cb5b000000000000000000000000000000000000000000000000000000009c33abf700000000000000000000000000000000000000000000000000000000c14c43490000000000000000000000000000000000000000000000000000000061d027b3000000000000000000000000000000000000000000000000000000006750cd4c00000000000000000000000000000000000000000000000000000000715018a60000000000000000000000000000000000000000000000000000000029460b0a0000000000000000000000000000000000000000000000000000000043ea4fa80000000000000000000000000000000000000000000000000000000043ea4fa9000000000000000000000000000000000000000000000000000000004d9632000000000000000000000000000000000000000000000000000000000054fd4d500000000000000000000000000000000000000000000000000000000029460b0b0000000000000000000000000000000000000000000000000000000039e3f938000000000000000000000000000000000000000000000000000000004389e58f000000000000000000000000000000000000000000000000000000001881d94c000000000000000000000000000000000000000000000000000000001881d94d00000000000000000000000000000000000000000000000000000000200175f70000000000000000000000000000000000000000000000000000000020efd7220000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000188183f40200000000000000000000000000000000000040000000000000000000000000e1758bd800000000000000000000000000000000000000000000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000ffffffffffffff3f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65641806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008c379a000000000000000000000000000000000000000000000000000000000465bc8340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000200000000000000000000000000000000000060000000000000000000000000820b7fd51bf79c54350bab98400651b3314ff6e79b33528821871d94a66698836b7a93100000000000000000000000000000000000000000000000000000000034084fb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000008000000000000000004f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000080000000000000000002000000000000000000000000000000000000200000008000000000000000003c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff010000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000c0927c56000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000c000000000000000000dc652a80000000000000000000000000000000000000000000000000000000053616665436173743a2076616c756520646f65736e27742066697420696e203132382062697473000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000c0000000000000000041705130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000c000000000000000006780cfaf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000010000000000000000000000000000000000000000000000000000000000006592671c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbf000000000000000000000000000000000000000000000000ffffffffffffffdfa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49020000000000000000000000000000000000002000000000000000000000000004eb6e0c00000000000000000000000000000000000000000000000000000000d3d3d9bc0000000000000000000000000000000000000000000000000000000030bb3aac0000000000000000000000000000000000000000000000000000000017ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec709eb66400000000000000000000000000000000000000000000000000000000d4244221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000c667af3e00000000000000000000000000000000000000000000000000000000491ff913b5444f4136b0d4075f020cfe3a5f60de926ec0b091612401a22b78420000000000000000000000000000000000000044000000800000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff0000000000000000000000000000000000000000ffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff0000000049cfac430000000000000000000000000000000000000000000000000000000020e9d05a000000000000000000000000000000000000000000000000000000002b001e1c6683bf79cc52891bd7215b204c787d18134fc7f3d21b4f32a49e47de000000000000000000000000000000000000000000000000ffffffffffffff9fba97c1fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000800000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000008000000000000000000000000000000000000000000000000000000084000000000000000000000000717e8a420000000000000000000000000000000000000000000000000000000061ed099e74a97a1d7f8bb0952a88ca8b7b8ebd00c126ea04671f92a81213318a000000000000000000000000000000000000000000000000ffffffffffffff1f000000000000000000000000000000000000000000000000ffffffffffffff5f736c6963655f6f75744f66426f756e64730000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000746f55696e74385f6f75744f66426f756e647300000000000000000000000000746f55696e7431365f6f75744f66426f756e647300000000000000000000000095d376d7000000000000000000000000000000000000000000000000000000004e487b710000000000000000000000000000000000000000000000000000000007ea52d82345d6e838192107d8fd7123d9c2ec8e916cd0aad13fd2b60db24644d51c5486000000000000000000000000000000000000000000000000000000004f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65720000000000000000000000000000000000000064000000800000000000000000ffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000ff00000000000000000000503667ae00000000000000000000000000000000000000000000000000000000aaf3aaa0c11056e86ac56eb653e25b005ca1a7d4dcd21ba24647f7ab63f3b560467409c300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff00ff0000000000000000447516e10000000000000000000000000000000000000000000000000000000082118522aa536ac0e96cc5c689407ae42b89d592aa133890a01f1509842f5081ce2c37510000000000000000000000000000000000000000000000000000000038682fa900000000000000000000000000000000000000000000000000000000422113660000000000000000000000000000000000000000000000000000000083aa17da00000000000000000000000000000000000000000000000000000000ffffffffffffffff0000000000000000000000000000000000000000000000000200000000000000000000000000000000000080000000000000000000000000779cb2dd9d2bb1be1737d05435d744facbfb84a2a4912e21379d39beddcdc805f0c10d0400000000000000000000000000000000000000000000000000000000885762a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000008000000000000000006f742073756363656564000000000000000000000000000000000000000000005361666545524332303a204552433230206f7065726174696f6e20646964206ee081464b7278501267de69fa85b7b9560b0ae05d5fbfaab9b1986c70356e2efe416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000e695d04400000000000000000000000000000000000000000000000000000000ffffffff0000000000000000000000000000000000000000000000000000000001ffc9a70000000000000000000000000000000000000000000000000000000097f0258400000000000000000000000000000000000000000000000000000000b6e9ace300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff40000000000000000000000000000000000000000000000000ffffffffffffffc0600e1f139d2de4bdf92998c5a8889525576bc5adeb07de6dc67cf6d830319d69
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005c6cff4b7c49805f8295ff73c204ac83f3bc4ae70000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000016bcc41e90000
-----Decoded View---------------
Arg [0] : _endpoint (address): 0x5c6cfF4b7C49805F8295Ff73C204ac83f3bC4AE7
Arg [1] : _treasuryGasLimit (uint256): 200000
Arg [2] : _treasuryGasForFeeCap (uint256): 400000000000000
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c6cff4b7c49805f8295ff73c204ac83f3bc4ae7
Arg [1] : 0000000000000000000000000000000000000000000000000000000000030d40
Arg [2] : 00000000000000000000000000000000000000000000000000016bcc41e90000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$9,244.96
Net Worth in ETH
4.583402
Token Allocations
ETH
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ABSTRACT | 100.00% | $2,011.09 | 4.597 | $9,244.96 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.