ETH Price: $1,586.81 (-2.71%)

Contract

0x3c1Dec865b6f69d6F33ec690A168449f7a8102B0

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
58867772025-04-04 13:31:3911 days ago1743773499  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZKSyncLST

Compiler Version
v0.8.25+commit.b61c2a91

ZkSolc Version
v1.5.12

Optimization Enabled:
Yes with Mode 3

Other Settings:
paris EvmVersion
File 1 of 54 : ZKSyncLST.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {LiquidStakingTokenCompose} from "./LiquidStakingTokenCompose.sol";
import {IL2BaseToken} from "./interfaces/IL2BaseToken.sol";
import {IL1Receiver} from "./vendor/layerzero/syncpools/interfaces/IL1Receiver.sol";

/**
 * @title  ZKSyncLST
 * @notice An implementation of the LiquidStakingToken contract on ZkSync Era that sends slow sync messages to the L2 system.
 * @dev    This contract facilitates interactions between mainnet PirexEth contracts and the ZKSync.
 * @author Dinero Protocol
 */
contract ZKSyncLST is LiquidStakingTokenCompose {
    /**
     * @notice Contract constructor to initialize LiquidStakingTokenVault with necessary parameters and configurations.
     * @dev    This constructor sets up the LiquidStakingTokenVault contract, configuring key parameters and initializing state variables.
     * @param  _endpoint   address  The address of the LOCAL LayerZero endpoint.
     * @param  _srcEid     uint32   The source endpoint ID.
     */
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(
        address _endpoint,
        uint32 _srcEid
    ) LiquidStakingTokenCompose(_endpoint, _srcEid) {}

    /**
     * @dev Internal function to send a slow sync message
     * @param _value Amount of ETH to send
     * @param _data Data to send
     */
    function _sendSlowSyncMessage(
        address,
        uint256 _value,
        uint256,
        bytes memory _data
    ) internal override {
        bytes memory message = abi.encodeCall(
            IL1Receiver.onMessageReceived,
            _data
        );

        IL2BaseToken(getMessenger()).withdrawWithMessage{value: _value}(
            getReceiver(),
            message
        );
    }
}

File 2 of 54 : LiquidStakingTokenCompose.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {LiquidStakingToken} from "./LiquidStakingToken.sol";
import {Origin} from "./vendor/layerzero-upgradeable/oapp/interfaces/IOAppReceiver.sol";
import {OFTComposeMsgCodec} from "./vendor/layerzero/oft/libs/OFTComposeMsgCodec.sol";
import {MsgCodec} from "./libraries/MsgCodec.sol";

/**
 * @title  LiquidStakingTokenCompose
 * @notice An DineroERC20Rebase OApp contract for handling LST operations between L2 and mainnet.
 * @dev    This contract facilitates interactions between mainnet PirexEth contracts and the L2 system.
 * @author redactedcartel.finance
 */
abstract contract LiquidStakingTokenCompose is LiquidStakingToken {
    /**
     * @dev Library: MsgCodec - Provides encoding and decoding of messages.
     */
    using MsgCodec for bytes;

    /**
     * @notice Contract constructor to initialize LiquidStakingToken with necessary parameters and configurations.
     * @dev    This constructor sets up the LiquidStakingToken contract, configuring key parameters and initializing state variables.
     * @param  _endpoint   address  The address of the LOCAL LayerZero endpoint.
     * @param  _srcEid     uint32   The source endpoint ID.
     */
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(
        address _endpoint,
        uint32 _srcEid
    ) LiquidStakingToken(_endpoint, _srcEid) {}

    /**
     * @notice Handler for processing layerzero messages from L2.
     * @dev    Only accept and handle the deposit and rebase  messages from mainnet, which mints and stakes LiquidStakingToken.
     * @dev    _origin   Origin   The origin information containing the source endpoint and sender address.
     * @dev    _guid     bytes32  The unique identifier for the received LayerZero message.
     * @param  _message  bytes    The payload of the received message.
     * @dev              address  The address of the executor for the received message.
     * @dev              bytes    Additional arbitrary data provided by the corresponding executor.
     */
    function _lzReceive(
        Origin calldata _origin,
        bytes32 _guid,
        bytes calldata _message,
        address,
        bytes calldata
    ) internal virtual override nonReentrant {
        _acceptNonce(_origin.srcEid, _origin.sender, _origin.nonce);

        uint256 amountReceived = _handleMessageReceived(_guid, _message);

        (bool isComposed, ) = _message.isComposed();
        if (isComposed) {
            _sendCompose(
                _origin.srcEid,
                _origin.nonce,
                _guid,
                amountReceived,
                _message
            );
        }
    }

    /**
     * @dev Decode the received message.
     * @param _message bytes The message to decode.
     * @return messageType uint256 The message type.
     * @return amount uint256 The amount.
     * @return assetsPerShare uint256 The assets per share.
     * @return receiver address The receiver address.
     * @return syncedIds bytes32[] The synced IDs.
     */
    function _decodeReceivedMessage(
        bytes calldata _message
    )
        internal
        pure
        override
        returns (
            uint256 messageType,
            uint256 amount,
            uint256 assetsPerShare,
            address receiver,
            bytes32[] memory syncedIds
        )
    {
        return _message.decodeL1Msg();
    }

    /**
     * @dev Send compose message to the destination endpoint.
     * @param _srcEid endpoint ID of the source.
     * @param _nonce nonce of the message.
     * @param _guid GUID of the message.
     * @param _amountReceived amount received.
     * @param _message message to compose.
     */
    function _sendCompose(
        uint32 _srcEid,
        uint64 _nonce,
        bytes32 _guid,
        uint256 _amountReceived,
        bytes calldata _message
    ) internal virtual {
        // @dev composeMsg format for the OFT.
        bytes memory composeMsg = OFTComposeMsgCodec.encode(
            _nonce,
            _srcEid,
            _amountReceived,
            abi.encodePacked(
                OFTComposeMsgCodec.addressToBytes32(address(this)),
                _message.composeMsg()
            )
        );

        endpoint.sendCompose(
            _message.composeTo(),
            _guid,
            0 /* the index of the composed message*/,
            composeMsg
        );
    }
}

File 3 of 54 : IL2BaseToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

interface IL2BaseToken {
    function withdrawWithMessage(
        address _l1Receiver,
        bytes calldata _additionalData
    ) external payable;
}

File 4 of 54 : IL1Receiver.sol
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;

interface IL1Receiver {
    function onMessageReceived(bytes calldata message) external payable;
}

File 5 of 54 : LiquidStakingToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {DineroERC20RebaseUpgradeable} from "./DineroERC20RebaseUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import {OAppUpgradeable} from "contracts/vendor/layerzero-upgradeable/oapp/OAppUpgradeable.sol";
import {MessagingFee, MessagingReceipt} from "contracts/vendor/layerzero-upgradeable/oapp/OAppSenderUpgradeable.sol";
import {OAppOptionsType3Upgradeable} from "contracts/vendor/layerzero-upgradeable/oapp/libs/OAppOptionsType3Upgradeable.sol";
import {Origin} from "contracts/vendor/layerzero-upgradeable/oapp/interfaces/IOAppReceiver.sol";
import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol";
import {Constants} from "./libraries/Constants.sol";
import {Errors} from "./libraries/Errors.sol";
import {L2SyncPool} from "./L2SyncPool.sol";
import {BaseMessengerUpgradeable} from "contracts/vendor/layerzero/syncpools/utils/BaseMessengerUpgradeable.sol";
import {BaseReceiverUpgradeable} from "contracts/vendor/layerzero/syncpools/utils/BaseReceiverUpgradeable.sol";
import {IRateProvider} from "./interfaces/IRateProvider.sol";
import {IRateLimiter} from "contracts/vendor/layerzero/syncpools/interfaces/IRateLimiter.sol";
import {IWrappedLiquidStakedToken} from "./interfaces/IWrappedLiquidStakedToken.sol";

/**
 * @title  LiquidStakingToken
 * @notice An DineroERC20Rebase OApp contract for handling LST operations between L2 and mainnet.
 * @dev    This contract facilitates interactions between mainnet PirexEth contracts and the L2 system.
 * @author redactedcartel.finance
 */
abstract contract LiquidStakingToken is
    DineroERC20RebaseUpgradeable,
    L2SyncPool,
    BaseMessengerUpgradeable,
    BaseReceiverUpgradeable,
    OAppUpgradeable,
    OAppOptionsType3Upgradeable,
    ReentrancyGuardUpgradeable,
    PausableUpgradeable
{
    /**
     * @dev Library: FixedPointMathLib - Provides fixed-point arithmetic for uint256.
     */
    using FixedPointMathLib for uint256;

    /**
     * @notice The endpoint ID for L1.
     * @dev This constant defines the source endpoint ID for the L1.
     */
    uint32 internal immutable L1_EID;

    /// @custom:storage-location erc7201:redacted.storage.LiquidStakingToken
    struct L2TokenStorage {
        /**
         * @notice Total assets actively staked in the vault.
         * @dev This variable holds the total assets actively staked, follows totalAssets in the mainnet lockbox.
         */
        uint256 totalStaked;
        /**
         * @notice The last assets per share value.
         * @dev This variable holds the last assets per share value received form deposit or rebase.
         */
        uint256 lastAssetsPerShare;
        /**
         * @notice The unsynced pending deposit amount.
         * @dev This variable holds the pending deposit amount that has not been synced and is not staked in the mainnet vault and will not be rebased.
         */
        uint256 unsyncedPendingDeposit;
        /**
         * @notice The synced pending deposit amount.
         * @dev This variable holds the pending deposit amount that has been synced and is not staked in the mainnet vault and will not be rebased.
         */
        uint256 syncedPendingDeposit;
        /**
         * @notice The total unsynced shares.
         * @dev This variable holds the total unsynced shares.
         */
        uint256 unsyncedShares;
        /**
         * @notice The rebase fee that is charged on each rebase.
         * @dev This variable holds the rebase fee that is charged on each rebase.
         */
        uint256 rebaseFee;
        /**
         * @notice The sync deposit fee that is charged on each sync pool L2 deposit.
         * @dev This variable holds the sync deposit fee that is charged on each sync pool L2 deposit.
         */
        uint256 syncDepositFee;
        /**
         * @notice The treasury address that receives the treasury fee.
         * @dev This variable holds the address of the treasury, which receives the treasury fee when a rebase occurs.
         */
        address treasury;
        /**
         * @notice Last pending sync index.
         * @dev This variable holds the last pending sync index.
         */
        uint256 lastPendingSyncIndex;
        /**
         * @notice Last completed sync index.
         * @dev This variable holds the last completed sync index.
         */
        uint256 lastCompletedSyncIndex;
        /**
         * @notice Sync index to pending amount mapping.
         * @dev This mapping holds the sync index to pending amount mapping.
         */
        mapping(uint256 => uint256) syncIndexPendingAmount;
        /**
         * @notice Sync ID to index mapping.
         * @dev This mapping holds the sync ID to index mapping.
         */
        mapping(bytes32 => uint256) syncIdIndex;
        /**
         * @notice The nonce for the received messages.
         * @dev Mapping to track the maximum received nonce for each source endpoint and sender
         */
        mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) receivedNonce;
        /**
         * @notice Mapping to track the accounts that can pause the contract.
         * @dev This mapping holds the accounts that can pause the contract.
         */
        mapping(address => bool) canPause;
        /**
         * @dev The address of the Wrapped Liquid Staked Token contract.
         * @dev This variable holds the address of the Wrapped Liquid Staked Token contract.
         */
        address wLST;
    }

    // keccak256(abi.encode(uint256(keccak256(redacted.storage.LiquidStakingToken)) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant LiquidStakingTokenStorageLocation =
        0xdd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09100;

    function _getLiquidStakingTokenStorage()
        internal
        pure
        returns (L2TokenStorage storage $)
    {
        assembly {
            $.slot := LiquidStakingTokenStorageLocation
        }
    }

    // Events

    /**
     * @notice Emitted on sending withdrawal message.
     * @param  guid         bytes32  GUID of the OFT message.
     * @param  fromAddress  address  Address of the sender on the src chain.
     * @param  toAddress    address  Address of the recipient on the src chain.
     * @param  amount       uint256  Withdrawal amount (in LiquidStakingToken).
     */
    event Withdrawal(
        bytes32 indexed guid,
        address indexed fromAddress,
        address indexed toAddress,
        uint256 amount
    );

    /**
     * @notice Emitted on receiving the deposit message.
     * @param  guid         bytes32  GUID of the OFT message.
     * @param  toAddress    address  Address of the recipient on L2.
     * @param  shares       uint256  Deposit amount (in shares).
     * @param  amount       uint256  Deposit amount (in LiquidStakingToken).
     */
    event Deposit(
        bytes32 indexed guid,
        address indexed toAddress,
        uint256 shares,
        uint256 amount
    );

    /**
     * @notice Emitted on minting tokens from SyncPool.
     * @param  toAddress    address  Address of the recipient on L2.
     * @param  shares       uint256  Deposit amount (in shares).
     * @param  amount       uint256  Deposit amount (in LiquidStakingToken).
     */
    event Mint(address indexed toAddress, uint256 shares, uint256 amount);

    /**
     * @notice Emitted on receiving rebase message.
     * @param  guid             bytes32  GUID of the OFT message.
     * @param  treasury         address  Address of the treasury.
     * @param  assetsPerShare   uint256  The current assets per share.
     * @param  amount           uint256  Deposit amount (in LiquidStakingToken).
     * @param  fee              uint256  Fee amount (in LiquidStakingToken).
     * @param  feeShares        uint256  Fee amount (in shares).
     */
    event Rebase(
        bytes32 indexed guid,
        address indexed treasury,
        uint256 assetsPerShare,
        uint256 amount,
        uint256 fee,
        uint256 feeShares
    );

    /**
     * @notice Emitted when the pause is set.
     * @param  account  address  The account that can pause the contract.
     * @param  allowed  bool     The allowed status.
     */
    event canPauseSet(address indexed account, bool allowed);

    /**
     * @notice Contract constructor to initialize LiquidStakingTokenVault with necessary parameters and configurations.
     * @dev    This constructor sets up the LiquidStakingTokenVault contract, configuring key parameters and initializing state variables.
     * @param  _endpoint   address  The address of the LOCAL LayerZero endpoint.
     * @param  _srcEid     uint32   The source endpoint ID.
     */
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(address _endpoint, uint32 _srcEid) OAppUpgradeable(_endpoint) {
        L1_EID = _srcEid;
        _disableInitializers();
    }

    /**
     * @dev modifier to allow only the owner or the canPause address to pause the contract
     */
    modifier onlyCanPause() {
        if (!_canPause(_msgSender())) revert Errors.NotAllowed();
        _;
    }

    /**
     * @notice Initialize the LiquidStakingToken contract.
     * @param _delegate address The delegate capable of making OApp configurations inside of the endpoint.
     * @param _owner    address The owner of the contract.
     * @param _treasury address The treasury address.
     * @param _l2ExchangeRateProvider Address of the exchange rate provider
     * @param _rateLimiter address The rate limiter address.
     * @param _messenger Address of the messenger contract (most of the time, the L2 native bridge address)
     * @param _receiver Address of the receiver contract (most of the time, the L1 receiver contract)
     * @param _bridgeQuoter Address of the bridge quoter contract
     * @param _name     string  The name of the token.
     * @param _symbol   string  The symbol of the token.
     */
    function initialize(
        address _delegate,
        address _owner,
        address _treasury,
        address _l2ExchangeRateProvider,
        address _rateLimiter,
        address _messenger,
        address _receiver,
        address _bridgeQuoter,
        string memory _name,
        string memory _symbol
    ) external initializer {
        __LiquidStakingToken_init(_delegate, _owner, _treasury, _name, _symbol);
        __L2BaseSyncPool_init(
            _l2ExchangeRateProvider,
            _rateLimiter,
            _bridgeQuoter
        );
        __BaseMessenger_init(_messenger);
        __BaseReceiver_init(_receiver);
    }

    function __LiquidStakingToken_init(
        address _delegate,
        address _owner,
        address _treasury,
        string memory _name,
        string memory _symbol
    ) internal onlyInitializing {
        __ReentrancyGuard_init();
        __Pausable_init();
        __Ownable_init(_owner);
        __OAppCore_init(_delegate);
        __DineroERC20Rebase_init(_name, _symbol);

        _setTreasury(_treasury);
    }

    /**
     * @notice Handler for processing layerzero messages from L2.
     * @dev    Only accept and handle the deposit and rebase  messages from mainnet, which mints and stakes LiquidStakingToken.
     * @dev    _origin   Origin   The origin information containing the source endpoint and sender address.
     * @dev    _guid     bytes32  The unique identifier for the received LayerZero message.
     * @param  _message  bytes    The payload of the received message.
     * @dev              address  The address of the executor for the received message.
     * @dev              bytes    Additional arbitrary data provided by the corresponding executor.
     */
    function _lzReceive(
        Origin calldata _origin,
        bytes32 _guid,
        bytes calldata _message,
        address,
        bytes calldata
    ) internal virtual override nonReentrant {
        _acceptNonce(_origin.srcEid, _origin.sender, _origin.nonce);

        _handleMessageReceived(_guid, _message);
    }

    /**
     * @notice Handler for processing layerzero messages.
     * @dev    Only accept and handle the deposit and rebase  messages from mainnet, which mints and stakes LiquidStakingToken.
     * @dev    _guid     bytes32  The unique identifier for the received LayerZero message.
     * @param  _message  bytes    The payload of the received message.
     * @dev              address  The address of the executor for the received message.
     * @dev              bytes    Additional arbitrary data provided by the corresponding executor.
     */
    function _handleMessageReceived(
        bytes32 _guid,
        bytes calldata _message
    ) internal virtual returns (uint256 amountReceived) {
        (
            uint256 _messageType,
            uint256 _amount,
            uint256 _assetsPerShare,
            address _receiver,
            bytes32[] memory _syncedIds
        ) = _decodeReceivedMessage(_message);

        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        if (
            _messageType == Constants.MESSAGE_TYPE_DEPOSIT ||
            _messageType == Constants.MESSAGE_TYPE_DEPOSIT_WRAP
        ) {
            _updateTotalStaked(_assetsPerShare);

            uint256 shares = getTotalShares() == 0
                ? _amount
                : convertToShares(_amount);

            if (_messageType == Constants.MESSAGE_TYPE_DEPOSIT_WRAP) {
                _mintShares(address(this), shares);
                $.totalStaked += _amount;

                uint256 amount = convertToAssets(shares, true);
                _approve(address(this), $.wLST, amount, false);
                uint256 wAmount = IWrappedLiquidStakedToken($.wLST).wrap(
                    amount
                );
                IWrappedLiquidStakedToken($.wLST).transfer(_receiver, wAmount);
            } else {
                _mintShares(_receiver, shares);
                $.totalStaked += _amount;
            }

            IRateLimiter(getRateLimiter()).updateRateLimit(
                address(this),
                address(this),
                shares,
                0
            );

            emit Deposit(_guid, _receiver, shares, _amount);
        } else if (_messageType == Constants.MESSAGE_TYPE_REBASE) {
            _updateTotalStaked(_assetsPerShare);

            uint256 fee = _amount.mulDivDown(
                $.rebaseFee,
                Constants.FEE_DENOMINATOR
            );

            uint256 shares;
            if (fee > 0 && _totalAssets() > fee) {
                shares = fee.mulDivDown(getTotalShares(), _totalAssets() - fee);

                _mintShares($.treasury, shares);

                IRateLimiter(getRateLimiter()).updateRateLimit(
                    address(this),
                    address(this),
                    shares,
                    0
                );
            } else {
                fee = 0;
            }

            emit Rebase(
                _guid,
                $.treasury,
                _assetsPerShare,
                _amount,
                fee,
                shares
            );
        } else {
            revert Errors.NotAllowed();
        }

        if (_syncedIds.length > 0) {
            uint256 staked = _updateSyncQueue(_syncedIds);
            if (staked > 0) {
                $.totalStaked += staked;
                $.syncedPendingDeposit -= staked;
            }
        }

        return _amount;
    }

    /**
     * @dev Decode the received message.
     * @param _message bytes The message to decode.
     * @return messageType uint256 The message type.
     * @return amount uint256 The amount.
     * @return assetsPerShare uint256 The assets per share.
     * @return receiver address The receiver address.
     * @return syncedIds bytes32[] The synced IDs.
     */
    function _decodeReceivedMessage(
        bytes calldata _message
    )
        internal
        pure
        virtual
        returns (
            uint256 messageType,
            uint256 amount,
            uint256 assetsPerShare,
            address receiver,
            bytes32[] memory syncedIds
        )
    {
        return
            abi.decode(
                _message,
                (uint256, uint256, uint256, address, bytes32[])
            );
    }

    /**
     * @notice Mint LiquidStakingToken tokens to the recipient.
     * @dev    Only the Sync Pool contract can mint LiquidStakingToken tokens.
     * @param _to               address The recipient of the minted tokens.
     * @param _assetsPerShare   uint256 The assets per share value.
     * @param _amount           uint256 The amount of assets to mint.
     */
    function _mint(
        address _to,
        uint256 _assetsPerShare,
        uint256 _amount
    ) internal {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        if ($.lastAssetsPerShare < _assetsPerShare)
            _updateTotalStaked(_assetsPerShare);

        uint256 _totalShares = getTotalShares();
        uint256 shares = _totalShares == 0 ? _amount : convertToShares(_amount);
        uint256 depositFee = $.syncDepositFee;

        if (depositFee > 0) {
            uint256 feeShares = shares.mulDivDown(
                depositFee,
                Constants.FEE_DENOMINATOR
            );

            _mintShares($.treasury, feeShares);
            $.unsyncedShares += feeShares;

            shares -= feeShares;
        }

        _mintShares(_to, shares);

        $.unsyncedShares += shares;
        $.unsyncedPendingDeposit += _amount;

        emit Mint(_to, shares, _amount);
    }

    /**
     * @dev Add msg id to sync queue.
     * @param _msgReceipt bytes32  The unique identifier for the message.
     * @param _amount     uint256  Sync amount
     */
    function _addToSyncQueue(
        MessagingReceipt memory _msgReceipt,
        uint256 _amount
    ) internal {
        // add to sync queue
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        $.lastPendingSyncIndex += 1;

        uint256 id = $.lastPendingSyncIndex;

        $.syncIdIndex[_msgReceipt.guid] = id;
        $.syncIndexPendingAmount[id] = _amount;
        $.syncedPendingDeposit += _amount;
        $.unsyncedPendingDeposit -= _amount;
    }

    /**
     * @notice Perform withdraw and burn of LiquidStakingToken tokens relaying the withdrawal message to Mainnet.
     * @param _receiver address  The recipient of the withdrawal on Mainnet.
     * @param _refundAddress The address to receive any excess funds sent to layer zero.
     * @param _amount   uint256  Withdrawal amount (in assets).
     * @param _options  bytes    Additional options for the message.
     */
    function withdraw(
        address _receiver,
        address _refundAddress,
        uint256 _amount,
        bytes calldata _options
    ) external payable virtual nonReentrant whenNotPaused {
        if (_receiver == address(0)) revert Errors.ZeroAddress();
        // revert if the receiver is a smart contract on the source chain
        if (_receiver.code.length > 0) revert Errors.InvalidReceiver();
        if (_amount == 0) revert Errors.ZeroAmount();

        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        uint256 shares = previewWithdraw(_amount);

        IRateLimiter(getRateLimiter()).updateRateLimit(
            address(this),
            address(this),
            0,
            shares
        );

        _burnShares(msg.sender, shares);

        bytes memory payload = abi.encode(
            Constants.MESSAGE_TYPE_WITHDRAW,
            _amount,
            _receiver
        );

        bytes memory combinedOptions = combineOptions(L1_EID, 0, _options);

        uint256 synced = $.syncedPendingDeposit;

        if (synced > 0) {
            uint256 remaining = _withdrawPendingDeposit(_amount);
            if (remaining > 0) {
                $.totalStaked -= remaining;
            }
        } else {
            $.totalStaked -= _amount;
        }

        MessagingReceipt memory msgReceipt = _lzSend(
            L1_EID,
            payload,
            combinedOptions,
            MessagingFee(msg.value, 0),
            payable(_refundAddress)
        );

        emit Withdrawal(msgReceipt.guid, msg.sender, _receiver, _amount);
    }

    /**
     * @notice Deposit tokens on Layer 2
     * This will mint tokenOut on Layer 2 using the exchange rate for tokenIn to tokenOut.
     * The amount deposited and minted will be stored in the token data which can be synced to Layer 1.
     * Will revert if:
     * - The amountIn is zero
     * - The token is unauthorized (that is, the l1Address is address(0))
     * - The amountOut is less than the minAmountOut
     * @param tokenIn Address of the token
     * @param amountIn Amount of tokens to deposit
     * @param minAmountOut Minimum amount of tokens to mint on Layer 2
     * @param shouldWrap Whether to wrap the tokenIn before depositing
     * @return amountOut Amount of tokens minted on Layer 2
     */
    function deposit(
        address tokenIn,
        uint256 amountIn,
        uint256 minAmountOut,
        bool shouldWrap
    )
        public
        payable
        virtual
        override
        nonReentrant
        whenNotPaused
        returns (uint256)
    {
        return super.deposit(tokenIn, amountIn, minAmountOut, shouldWrap);
    }

    /**
     * @notice Quote gas cost for withdrawal messages
     * @param  _receiver  address  The recipient of the withdrawal on Mainnet.
     * @param  _amount    uint256  The withdrawal amount.
     * @param  _options   bytes    Additional options for the message.
     */
    function quoteWithdraw(
        address _receiver,
        uint256 _amount,
        bytes calldata _options
    ) external view virtual returns (MessagingFee memory msgFee) {
        bytes memory _payload = abi.encode(
            Constants.MESSAGE_TYPE_WITHDRAW,
            _amount,
            _receiver
        );

        bytes memory _combinedOptions = combineOptions(L1_EID, 0, _options);

        return _quote(L1_EID, _payload, _combinedOptions, false);
    }

    /**
     * @dev Quote the messaging fee for a sync
     * @param  _tokenIn  address  Address of the input token
     * @param  _options   bytes    Additional options for the message.
     */
    function quoteSync(
        address _tokenIn,
        bytes calldata _options
    ) external view virtual returns (MessagingFee memory msgFee) {
        Token storage token = _getL2SyncPoolStorage().tokens[_tokenIn];

        bytes memory _payload = abi.encode(
            Constants.MESSAGE_TYPE_SYNC,
            _tokenIn,
            token.unsyncedAmountIn,
            token.unsyncedAmountOut
        );

        bytes memory _combinedOptions = combineOptions(L1_EID, 0, _options);

        return _quote(L1_EID, _payload, _combinedOptions, false);
    }

    /**
     * @notice Internal function to set the canPause address.
     * @param _address the address to check if it can pause the contract.
     */
    function _canPause(address _address) internal view returns (bool) {
        return
            _getLiquidStakingTokenStorage().canPause[_address] ||
            _address == owner();
    }

    /**
     * @notice Function to set the canPause address.
     * @param _address the address to check if it can pause the contract.
     */
    function setCanPause(address _address, bool _allowed) external onlyOwner {
        _getLiquidStakingTokenStorage().canPause[_address] = _allowed;
    }

    /**
     * @notice Check if an address can pause the contract.
     * @param _address the address to check if it can pause the contract.
     */
    function canPause(address _address) external view returns (bool) {
        return _canPause(_address);
    }

    /**
     * @notice Pause SyncPool deposits and withdrawals.
     */
    function pause() external onlyCanPause {
        _pause();
    }

    /**
     * @notice Unpause SyncPool deposits and withdrawals.
     */
    function unpause() external onlyCanPause {
        _unpause();
    }

    /**
     * @notice Set the rebase fee.
     * @param _rebaseFee uint256 Rebase fee.
     */
    function setRebaseFee(uint256 _rebaseFee) external onlyOwner {
        if (_rebaseFee > Constants.MAX_REBASE_FEE) revert Errors.InvalidFee();

        _getLiquidStakingTokenStorage().rebaseFee = _rebaseFee;
    }

    /**
     * @notice Set the rebase fee.
     * @param _syncDepositFee uint256 Rebase fee.
     */
    function setSyncDepositFee(uint256 _syncDepositFee) external onlyOwner {
        if (_syncDepositFee > Constants.MAX_DEPOSIT_FEE)
            revert Errors.InvalidFee();

        _getLiquidStakingTokenStorage().syncDepositFee = _syncDepositFee;
    }

    /**
     * @notice Set the treasury address.
     * @param _treasury address Treasury address.
     */
    function setTreasury(address _treasury) external onlyOwner {
        _setTreasury(_treasury);
    }

    /**
     * @notice Set the Wrapped Liquid Staked Token address.
     * @param _wLST address Wrapped Liquid Staked Token address.
     */
    function setWrappedLST(address _wLST) external onlyOwner {
        if (_wLST == address(0)) revert Errors.ZeroAddress();

        _getLiquidStakingTokenStorage().wLST = _wLST;
    }

    /**
     * @return the total amount (in wei) of Pirex Ether controlled by the protocol.
     */
    function totalAssets() public view returns (uint256) {
        return _totalAssets();
    }

    /**
     * @return The treasury address that receives the treasury fee.
     */
    function treasury() public view returns (address) {
        return _getLiquidStakingTokenStorage().treasury;
    }

    /**
     * @return The rebase fee that is charged on each rebase.
     */
    function rebaseFee() public view returns (uint256) {
        return _getLiquidStakingTokenStorage().rebaseFee;
    }

    /**
     * @return The sync deposit fee that is charged on each sync pool L2 deposit.
     */
    function syncDepositFee() public view returns (uint256) {
        return _getLiquidStakingTokenStorage().syncDepositFee;
    }

    /**
     * @return The last assets per share value.
     */
    function lastAssetsPerShare() public view returns (uint256) {
        return _getLiquidStakingTokenStorage().lastAssetsPerShare;
    }

    /**
     * @param  idx  uint256  Sync index
     * @return Pending amount.
     */
    function syncIndexPendingAmount(
        uint256 idx
    ) external view returns (uint256) {
        return _getLiquidStakingTokenStorage().syncIndexPendingAmount[idx];
    }

    /**
     * @notice Returns the current sync indexes.
     * @return lastPendingSyncIndex The last pending sync index.
     * @return lastCompletedSyncIndex The last completed sync index.
     */
    function syncIndexes()
        external
        view
        returns (uint256 lastPendingSyncIndex, uint256 lastCompletedSyncIndex)
    {
        return (
            _getLiquidStakingTokenStorage().lastPendingSyncIndex,
            _getLiquidStakingTokenStorage().lastCompletedSyncIndex
        );
    }

    /**
     * @return The total staked amount.
     */
    function totalStaked() external view returns (uint256) {
        return _getLiquidStakingTokenStorage().totalStaked;
    }

    /**
     * @param includeUnsynced bool Include unsynced pending deposit.
     * @return The total amount (in wei) of pending deposit.
     */
    function pendingDeposit(
        bool includeUnsynced
    ) public view returns (uint256) {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        return
            $.syncedPendingDeposit +
            (includeUnsynced ? $.unsyncedPendingDeposit : 0);
    }

    /**
     * @return the total amount (in wei) of Pirex Ether controlled by the protocol.
     */
    function _totalAssets() internal view override returns (uint256) {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        return
            $.totalStaked + $.unsyncedPendingDeposit + $.syncedPendingDeposit;
    }

    /**
     * @notice Set the treasury address.
     * @param _treasury address Treasury address.
     */
    function _setTreasury(address _treasury) internal {
        if (_treasury == address(0)) revert Errors.ZeroAddress();

        _getLiquidStakingTokenStorage().treasury = _treasury;
    }

    /**
     * @notice Update the total staked amount.
     * @param _assetsPerShare  uint256 The assets per share value.
     */
    function _updateTotalStaked(uint256 _assetsPerShare) internal {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        uint256 _lastAssetsPerShare = $.lastAssetsPerShare;
        uint256 _totalStaked = $.totalStaked;

        if (_lastAssetsPerShare > 0)
            _totalStaked.mulDivDown(_assetsPerShare, _lastAssetsPerShare);

        $.lastAssetsPerShare = _assetsPerShare;
    }

    /**
     * @notice Withdraw from the pending deposit.
     * @param _withdrawAmount uint256 The amount to withdraw.
     * @return The remaining amount to withdraw from total staked.
     */
    function _withdrawPendingDeposit(
        uint256 _withdrawAmount
    ) internal returns (uint256) {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        uint256 lastPendingIndex = $.lastPendingSyncIndex;
        uint256 lastCompletedIndex = $.lastCompletedSyncIndex;
        uint256 remaining = _withdrawAmount;

        for (uint256 i = lastCompletedIndex + 1; i <= lastPendingIndex; i++) {
            uint256 pendingAmount = $.syncIndexPendingAmount[i];

            if (pendingAmount > remaining) {
                $.syncIndexPendingAmount[i] -= remaining;
                remaining = 0;
                break;
            }

            remaining -= pendingAmount;
            $.syncIndexPendingAmount[i] = 0;
            $.lastCompletedSyncIndex++;
        }

        $.syncedPendingDeposit -= (_withdrawAmount - remaining);

        return remaining;
    }

    /**
     * @notice Update the sync queue.
     * @param _syncedIds bytes The last synced ids.
     * @return The staked amount.
     */
    function _updateSyncQueue(
        bytes32[] memory _syncedIds
    ) internal returns (uint256) {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        uint256 staked;
        uint256 index;
        uint256 pendingAmount;
        uint256 syncIdsLen = _syncedIds.length;
        uint256 lastPendingIndex = $.lastPendingSyncIndex;
        uint256 lastCompletedIndex = $.lastCompletedSyncIndex;

        for (uint256 i; i < syncIdsLen; i++) {
            index = $.syncIdIndex[_syncedIds[i]];
            pendingAmount = $.syncIndexPendingAmount[index];

            if (pendingAmount > 0) {
                $.syncIndexPendingAmount[index] = 0;
                staked += pendingAmount;
            }
        }

        // update last completed index
        uint256 startIndex = lastCompletedIndex + 1;
        uint256 maxSyncIndex = syncIdsLen + lastCompletedIndex >
            lastPendingIndex
            ? lastPendingIndex
            : syncIdsLen + lastCompletedIndex;
        for (uint256 i = startIndex; i <= maxSyncIndex; i++) {
            if ($.syncIndexPendingAmount[i] > 0) {
                $.lastCompletedSyncIndex = i - 1;
                break;
            }

            if (i == maxSyncIndex && $.syncIndexPendingAmount[i] == 0) {
                $.lastCompletedSyncIndex = i;
            }
        }

        return staked;
    }

    /**
     * @dev Internal function to sync tokens to L1
     * This will send an additional message to the messenger contract after the LZ message
     * This message will contain the ETH that the LZ message anticipates to receive
     * @param _l2TokenIn Address of the token on Layer 2
     * @param _l1TokenIn Address of the token on Layer 1
     * @param _amountIn Amount of tokens deposited on Layer 2
     * @param _amountOut Amount of tokens minted on Layer 2
     * @param _totalAmountIn Total amount of tokens deposited on Layer 2
     * @param _extraOptions Extra options for the messaging protocol
     * @param _fee Messaging fee
     * @return receipt Messaging receipt
     */
    function _sync(
        address _l2TokenIn,
        address _l1TokenIn,
        uint256 _amountIn,
        uint256 _amountOut,
        uint256 _totalAmountIn,
        bytes calldata _extraOptions,
        MessagingFee calldata _fee
    )
        internal
        virtual
        override
        nonReentrant
        whenNotPaused
        returns (MessagingReceipt memory)
    {
        // send fast sync message
        MessagingReceipt memory receipt = _lzSend(
            L1_EID,
            abi.encode(
                Constants.MESSAGE_TYPE_SYNC,
                _l1TokenIn,
                _amountIn,
                _amountOut
            ),
            combineOptions(L1_EID, 0, _extraOptions),
            MessagingFee(_fee.nativeFee, 0),
            payable(msg.sender)
        );

        _addToSyncQueue(receipt, _amountOut);

        bytes memory data = abi.encode(
            endpoint.eid(),
            receipt.guid,
            _l1TokenIn,
            _amountIn,
            _amountOut
        );

        // send slow sync message
        _sendSlowSyncMessage(_l2TokenIn, _amountIn, _fee.nativeFee, data);

        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        uint256 unsyncedShares = $.unsyncedShares;
        uint256 syncedShares = _totalAmountIn == _amountIn
            ? unsyncedShares
            : unsyncedShares.mulDivDown(_amountIn, _totalAmountIn);

        IRateLimiter(getRateLimiter()).updateRateLimit(
            address(this),
            Constants.ETH_ADDRESS,
            syncedShares,
            0
        );
        $.unsyncedShares -= syncedShares;

        return receipt;
    }

    /**
     * @dev Internal function to send tokenOut to an account
     * @param _account Address of the account
     * @param _amount Amount of tokens to send
     * @param shouldWrap bool Whether to wrap the tokens before sending
     */
    function _sendTokenOut(
        address _account,
        uint256 _amount,
        bool shouldWrap
    ) internal override {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        uint256 assetsPerShare = IRateProvider(getL2ExchangeRateProvider())
            .getAssetsPerShare();

        if (shouldWrap) {
            _mint(address(this), assetsPerShare, _amount);
            _approve(address(this), $.wLST, _amount, false);
            uint256 wAmount = IWrappedLiquidStakedToken($.wLST).wrap(_amount);
            IWrappedLiquidStakedToken($.wLST).transfer(_account, wAmount);
        } else {
            _mint(_account, assetsPerShare, _amount);
        }
    }

    /**
     * @dev Internal function to send a slow sync message
     * This function should be overridden to send a slow sync message to the L1 receiver contract
     * @param _l2TokenIn Address of the token on Layer 2
     * @param _amountIn Amount of tokens deposited on Layer 2
     * @param _fastSyncNativeFee The amount of ETH already used as native fee in the fast sync
     * @param _message Message to send
     */
    function _sendSlowSyncMessage(
        address _l2TokenIn,
        uint256 _amountIn,
        uint256 _fastSyncNativeFee,
        bytes memory _message
    ) internal virtual;

    /**
     * @dev Internal function to get the minimum gas limit
     * This function should be overridden to set a minimum gas limit to forward during the execution of the message
     * by the L1 receiver contract. This is mostly needed if the underlying contract have some try/catch mechanism
     * as this could be abused by gas-griefing attacks.
     * @return minGasLimit Minimum gas limit
     */
    function _minGasLimit() internal view virtual returns (uint32) {
        return 0;
    }

    /**
     * @notice Set the last received nonce for the specified source endpoint and sender.
     * @dev this should be used to fix the nonce if there's a problem in the execution of a particular message.
     * @param _srcEid Source endpoint ID.
     * @param _sender Sender's address in bytes32 format.
     * @param _nonce The nonce to be set.
     */
    function setNonce(
        uint32 _srcEid,
        bytes32 _sender,
        uint64 _nonce
    ) external onlyOwner {
        _getLiquidStakingTokenStorage().receivedNonce[_srcEid][
            _sender
        ] = _nonce;
    }

    /**
     * @dev Public function to get the next expected nonce for a given source endpoint and sender.
     * @param _srcEid Source endpoint ID.
     * @param _sender Sender's address in bytes32 format.
     * @return uint64 Next expected nonce.
     */
    function nextNonce(
        uint32 _srcEid,
        bytes32 _sender
    ) public view override returns (uint64) {
        return
            _getLiquidStakingTokenStorage().receivedNonce[_srcEid][_sender] + 1;
    }

    /**
     * @dev Internal function to accept nonce from the specified source endpoint and sender.
     * @param _srcEid Source endpoint ID.
     * @param _sender Sender's address in bytes32 format.
     * @param _nonce The nonce to be accepted.
     */
    function _acceptNonce(
        uint32 _srcEid,
        bytes32 _sender,
        uint64 _nonce
    ) internal {
        L2TokenStorage storage $ = _getLiquidStakingTokenStorage();

        if (_nonce != $.receivedNonce[_srcEid][_sender] + 1)
            revert Errors.InvalidNonce();

        $.receivedNonce[_srcEid][_sender] += 1;
    }
}

File 6 of 54 : MsgCodec.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

library MsgCodec {
    // Offset constants for decoding messages
    uint256 private constant MESSAGE_TYPE_OFFSET = 32;
    uint256 private constant COMPOSE_TYPE_OFFSET = 64;
    uint256 private constant COMPOSE_RECEIVER_OFFSET = 32;

    /**
     * @dev Retrieves the message type from the message.
     * @param _msg The message.
     * @return The message type.
     */
    function messageType(bytes calldata _msg) internal pure returns (uint8) {
        return abi.decode(_msg[:MESSAGE_TYPE_OFFSET], (uint8));
    }

    /**
     * @dev Retrieve the relavant parameters from the message.
     * @param _msg The message.
     * @return msgType The message type.
     * @return amount The amount.
     * @return assetsPerShare The assets per share.
     * @return receiver The token receiver.
     * @return syncedIds The synced IDs.
     */
    function decodeL1Msg(
        bytes calldata _msg
    )
        internal
        pure
        returns (
            uint8 msgType,
            uint256 amount,
            uint256 assetsPerShare,
            address receiver,
            bytes32[] memory syncedIds
        )
    {
        (, uint256 composeMsgLen) = isComposed(_msg);

        (msgType, amount, assetsPerShare, receiver, syncedIds) = abi.decode(
            _msg[COMPOSE_TYPE_OFFSET:_msg.length - composeMsgLen],
            (uint8, uint256, uint256, address, bytes32[])
        );
    }

    /**
     * @dev Retrieve the relavant parameters from the sync message.
     * @param _msg The message.
     * @return token The deposited token.
     * @return amountIn The amount in.
     * @return amountOut The amount out.
     */
    function decodeSync(
        bytes calldata _msg
    )
        internal
        pure
        returns (address token, uint256 amountIn, uint256 amountOut)
    {
        (token, amountIn, amountOut) = abi.decode(
            _msg[MESSAGE_TYPE_OFFSET:],
            (address, uint256, uint256)
        );
    }

    /**
     * @dev Retrieve the relavant parameters from the withdraw message.
     * @param _msg The message.
     * @return amount The amount.
     * @return receiver The receiver address.
     */
    function decodeWithdraw(
        bytes calldata _msg
    ) internal pure returns (uint256 amount, address receiver) {
        (amount, receiver) = abi.decode(
            _msg[MESSAGE_TYPE_OFFSET:],
            (uint256, address)
        );
    }

    /**
     * @dev Retrieve the compose message.
     * @param _payload The LayerZero msg payload.
     * @return The compose message.
     */
    function composeMsg(
        bytes calldata _payload
    ) internal pure returns (bytes memory) {
        (bool composed, uint256 composeMsgLen) = isComposed(_payload);
        uint256 payloadLen = _payload.length;

        return composed ? 
            _payload[COMPOSE_RECEIVER_OFFSET + payloadLen - composeMsgLen:]
            : new bytes(0);
    }

    /**
     * @dev Check if the message is composed.
     * @param _payload The LayerZero msg payload.
     * @return Boolean if paylaod is composed and the length of the compose message.
     */
    function isComposed(
        bytes calldata _payload
    ) internal pure returns (bool, uint256) {
        (bool isCompose, uint256 composeMsgLen) = abi.decode(
            _payload[:COMPOSE_TYPE_OFFSET],
            (bool, uint256)
        );

        return (isCompose, composeMsgLen);
    }

    /**
     * @dev Encode the message.
     * @param _msg The message.
     * @param _composeMsg The compose message.
     * @return The encoded message.
     */
    function encode(
        bytes memory _msg,
        bytes memory _composeMsg
    ) internal pure returns (bytes memory) {
        uint256 composeMsgLen = _composeMsg.length;
        bool isCompose = composeMsgLen != 0;

        return
            abi.encodePacked(
                abi.encode(isCompose, composeMsgLen),
                _msg,
                _composeMsg
            );
    }

    /**
     * @dev Encode the compose message receiver.
     * The compose message must reserve its first 32 bytes for the receiver.
     * @param _payload The LayerZero msg payload.
     * @return The receiver address.
     */
    function composeTo(
        bytes calldata _payload
    ) internal pure returns (address) {
        (, uint256 composeMsgLen) = isComposed(_payload);
        uint256 payloadLen = _payload.length;
        uint256 start = payloadLen - composeMsgLen;
        uint256 end = start + 32;

        return address(uint160(uint256(bytes32(_payload[start:end]))));
    }
}

File 7 of 54 : IOAppReceiver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { ILayerZeroReceiver, Origin } from "contracts/vendor/layerzero/protocol/interfaces/ILayerZeroReceiver.sol";

interface IOAppReceiver is ILayerZeroReceiver {
    /**
     * @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.
     * @return sender The address responsible for 'sending' composeMsg's to the Endpoint.
     *
     * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
     * @dev The default sender IS the OApp implementer.
     */
    function composeMsgSender() external view returns (address sender);
}

File 8 of 54 : OFTComposeMsgCodec.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

library OFTComposeMsgCodec {
    // Offset constants for decoding composed messages
    uint8 private constant NONCE_OFFSET = 8;
    uint8 private constant SRC_EID_OFFSET = 12;
    uint8 private constant AMOUNT_LD_OFFSET = 44;
    uint8 private constant COMPOSE_FROM_OFFSET = 76;

    /**
     * @dev Encodes a OFT composed message.
     * @param _nonce The nonce value.
     * @param _srcEid The source endpoint ID.
     * @param _amountLD The amount in local decimals.
     * @param _composeMsg The composed message.
     * @return _msg The encoded Composed message.
     */
    function encode(
        uint64 _nonce,
        uint32 _srcEid,
        uint256 _amountLD,
        bytes memory _composeMsg // 0x[composeFrom][composeMsg]
    ) internal pure returns (bytes memory _msg) {
        _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg);
    }

    /**
     * @dev Retrieves the nonce from the composed message.
     * @param _msg The message.
     * @return The nonce value.
     */
    function nonce(bytes calldata _msg) internal pure returns (uint64) {
        return uint64(bytes8(_msg[:NONCE_OFFSET]));
    }

    /**
     * @dev Retrieves the source endpoint ID from the composed message.
     * @param _msg The message.
     * @return The source endpoint ID.
     */
    function srcEid(bytes calldata _msg) internal pure returns (uint32) {
        return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET]));
    }

    /**
     * @dev Retrieves the amount in local decimals from the composed message.
     * @param _msg The message.
     * @return The amount in local decimals.
     */
    function amountLD(bytes calldata _msg) internal pure returns (uint256) {
        return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET]));
    }

    /**
     * @dev Retrieves the composeFrom value from the composed message.
     * @param _msg The message.
     * @return The composeFrom value.
     */
    function composeFrom(bytes calldata _msg) internal pure returns (bytes32) {
        return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]);
    }

    /**
     * @dev Retrieves the composed message.
     * @param _msg The message.
     * @return The composed message.
     */
    function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) {
        return _msg[COMPOSE_FROM_OFFSET:];
    }

    /**
     * @dev Converts an address to bytes32.
     * @param _addr The address to convert.
     * @return The bytes32 representation of the address.
     */
    function addressToBytes32(address _addr) internal pure returns (bytes32) {
        return bytes32(uint256(uint160(_addr)));
    }

    /**
     * @dev Converts bytes32 to an address.
     * @param _b The bytes32 value to convert.
     * @return The address representation of bytes32.
     */
    function bytes32ToAddress(bytes32 _b) internal pure returns (address) {
        return address(uint160(uint256(_b)));
    }
}

File 9 of 54 : L2SyncPool.sol
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;

import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {MessagingFee, MessagingReceipt} from "./vendor/layerzero/protocol/interfaces/ILayerZeroEndpointV2.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IL2ExchangeRateProvider} from "./vendor/layerzero/syncpools/interfaces/IL2ExchangeRateProvider.sol";
import {IRateLimiter} from "./vendor/layerzero/syncpools/interfaces/IRateLimiter.sol";
import {IBridgeQuoter} from "./interfaces/IBridgeQuoter.sol";
import {Constants} from "./libraries/Constants.sol";
import {Errors} from "./libraries/Errors.sol";

/**
 * @title L2 Base Sync Pool
 * @dev Base contract for Layer 2 sync pools
 * A sync pool is an OApp that allows users to deposit tokens on Layer 2, and then sync them to Layer 1
 * The L2 sync pool takes care of deposits on the L2 and syncing to the L1 using the L1 sync pool.
 * Once enough tokens have been deposited, anyone can trigger a sync to Layer 1.
 */
abstract contract L2SyncPool is OwnableUpgradeable {
    struct L2SyncPoolStorage {
        /**
         * @notice The address of the exchange rate provider contract.
         * @dev This variable holds the address of the exchange rate provider contract, which is used to get the conversion rate.
         */
        IL2ExchangeRateProvider l2ExchangeRateProvider;
        /**
         * @notice The address of the rate limiter contract.
         * @dev This variable holds the address of the rate limiter contract, which is used to limit mint and withdrawal.
         */
        IRateLimiter rateLimiter;
        /**
         * @notice The address of the bridge quoter contract.
         * @dev This variable holds the address of the bridge quoter contract, which is used to get the min amount receive when bridging to L1.
         */
        IBridgeQuoter bridgeQuoter;
        /**
         * @notice The token data.
         * @dev This mapping holds the token data, which includes the amount of tokens deposited and minted, and the minimum amount required to sync.
         */
        mapping(address => Token) tokens;
        /**
         * @notice The sync keeper.
         * @dev This mapping holds the sync keepers, which are allowed to trigger a sync to Layer 1.
         */
        mapping(address => bool) syncKeeper;
    }

    /**
     * @dev Token data
     * @param unsyncedAmountIn Amount of tokens deposited on Layer 2
     * @param unsyncedAmountOut Amount of tokens minted on Layer 2
     * @param minSyncAmount Minimum amount of tokens required to sync
     * @param maxSyncAmount Maximum amount of tokens required to sync
     * @param l1Address Address of the token on Layer 1, address(0) is unauthorized
     */
    struct Token {
        uint256 unsyncedAmountIn;
        uint256 unsyncedAmountOut;
        uint256 minSyncAmount;
        uint256 maxSyncAmount;
        address l1Address;
    }

    // keccak256(abi.encode(uint256(keccak256(syncpools.storage.l2syncpool)) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant L2SyncPoolStorageLocation =
        0xc064a301e926254981c9bd3b3225923d097271573deb3cc61ae7f6a144f10a00;

    function _getL2SyncPoolStorage()
        internal
        pure
        returns (L2SyncPoolStorage storage $)
    {
        assembly {
            $.slot := L2SyncPoolStorageLocation
        }
    }

    event L2ExchangeRateProviderSet(address l2ExchangeRateProvider);
    event RateLimiterSet(address rateLimiter);
    event MinSyncAmountSet(address tokenIn, uint256 minSyncAmount);
    event MaxSyncAmountSet(address tokenIn, uint256 maxSyncAmount);
    event L1TokenInSet(address tokenIn, address l1TokenIn);
    event Deposit(address indexed tokenIn, uint256 amountIn, uint256 amountOut);
    event Sync(address indexed tokenIn, uint256 amountIn, uint256 amountOut);
    event SyncKeeperSet(address syncKeeper, bool status);
    event BridgeQuoterSet(address bridgeQuoter);

    /**
     * @dev Modifier to allow only the sync keeper to call the function
     */
    modifier onlySyncKeeper() {
        if (!_getL2SyncPoolStorage().syncKeeper[msg.sender]) {
            revert Errors.UnauthorizedCaller();
        }
        _;
    }

    /**
     * @dev Initialize the L2 Base Sync Pool
     * @param l2ExchangeRateProvider Address of the exchange rate provider
     * @param rateLimiter Address of the rate limiter
     * @param bridgeQuoter Address of the bridge quoter
     */
    function __L2BaseSyncPool_init(
        address l2ExchangeRateProvider,
        address rateLimiter,
        address bridgeQuoter
    ) internal {
        __L2BaseSyncPool_init_unchained(
            l2ExchangeRateProvider,
            rateLimiter,
            bridgeQuoter
        );
    }

    function __L2BaseSyncPool_init_unchained(
        address l2ExchangeRateProvider,
        address rateLimiter,
        address bridgeQuoter
    ) internal {
        _setL2ExchangeRateProvider(l2ExchangeRateProvider);
        _setRateLimiter(rateLimiter);
        _setBridgeQuoter(bridgeQuoter);
    }

    /**
     * @dev Get the exchange rate provider
     * @return l2ExchangeRateProvider Address of the exchange rate provider
     */
    function getL2ExchangeRateProvider() public view virtual returns (address) {
        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        return address($.l2ExchangeRateProvider);
    }

    /**
     * @dev Get the rate limiter
     * @return rateLimiter Address of the rate limiter
     */
    function getRateLimiter() public view virtual returns (address) {
        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        return address($.rateLimiter);
    }

    /**
     * @dev Get token data
     * If the l1Address is address(0), the token is unauthorized
     * @param tokenIn Address of the token
     * @return token Token data
     */
    function getTokenData(
        address tokenIn
    ) public view virtual returns (Token memory) {
        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        return $.tokens[tokenIn];
    }

    /**
     * @dev Check if the address is a sync keeper
     * @param syncKeeper Address of the sync keeper
     * @return status True if the address is a sync keeper
     */
    function isSyncKeeper(
        address syncKeeper
    ) public view virtual returns (bool) {
        return _getL2SyncPoolStorage().syncKeeper[syncKeeper];
    }

    /**
     * @notice Deposit tokens on Layer 2
     * This will mint tokenOut on Layer 2 using the exchange rate for tokenIn to tokenOut.
     * The amount deposited and minted will be stored in the token data which can be synced to Layer 1.
     * @param tokenIn Address of the token
     * @param amountIn Amount of tokens to deposit
     * @param minAmountOut Minimum amount of tokens to mint on Layer 2
     * @param shouldWrap True if the token should be wrapped
     * @return amountOut Amount of tokens minted on Layer 2
     */
    function deposit(
        address tokenIn,
        uint256 amountIn,
        uint256 minAmountOut,
        bool shouldWrap
    ) public payable virtual returns (uint256 amountOut) {
        amountOut = _deposit(tokenIn, amountIn, minAmountOut);

        _sendTokenOut(msg.sender, amountOut, shouldWrap);
    }

    /**
     * @dev Deposit tokens on Layer 2
     * This will mint tokenOut on Layer 2 using the exchange rate for tokenIn to tokenOut.
     * The amount deposited and minted will be stored in the token data which can be synced to Layer 1.
     * Will revert if:
     * - The amountIn is zero
     * - The token is unauthorized (that is, the l1Address is address(0))
     * - The amountOut is less than the minAmountOut
     * @param tokenIn Address of the token
     * @param amountIn Amount of tokens to deposit
     * @param minAmountOut Minimum amount of tokens to mint on Layer 2
     * @return amountOut Amount of tokens minted on Layer 2
     */
    function _deposit(
        address tokenIn,
        uint256 amountIn,
        uint256 minAmountOut
    ) internal virtual returns (uint256 amountOut) {
        if (amountIn == 0) revert Errors.ZeroAmount();

        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();

        Token storage token = $.tokens[tokenIn];
        if (token.l1Address == address(0)) revert Errors.UnauthorizedToken();

        uint256 amountReceived = amountIn;
        if (tokenIn != Constants.ETH_ADDRESS) {
            // get the actual amount sent and the expected amount received after bridging
            (amountIn, amountReceived) = $.bridgeQuoter.getAmountOut(
                tokenIn,
                amountIn
            );

            // as only WETH deposits are allowed, the amount received should be greater than the amount sent
            // otherwise, therer might be some temporary pool imbalance
            if (amountReceived > amountIn) revert Errors.InvalidRate(); 
        }

        amountOut = $.l2ExchangeRateProvider.getPostFeeAmount(
            tokenIn,
            amountReceived
        );

        if (amountOut < minAmountOut) revert Errors.InsufficientAmountOut();

        emit Deposit(tokenIn, amountIn, minAmountOut);

        _receiveTokenIn(tokenIn, amountIn);

        token.unsyncedAmountIn += amountIn;

        if (
            token.maxSyncAmount != 0 &&
            token.unsyncedAmountIn > token.maxSyncAmount
        ) {
            revert Errors.MaxSyncAmountExceeded();
        }

        token.unsyncedAmountOut += amountOut;
    }

    /**
     * @dev Sync tokens to Layer 1
     * This will send a message to the destination endpoint with the token data to
     * sync the tokens minted on Layer 2 to Layer 1.
     * Will revert if:
     * - The token is unauthorized (that is, the l1Address is address(0))
     * - The amount to sync is zero or less than the minSyncAmount
     * @dev It is very important to listen for the Sync event to know when and how much tokens were synced
     * especially if an action is required on another chain (for example, executing the message). If an action
     * was required but was not executed, the tokens won't be sent to the L1.
     * @param tokenIn Address of the token
     * @param extraOptions Extra options for the messaging protocol
     * @param fee Fast sync messaging fee, does not consider token bridge fees
     * @return unsyncedAmountIn Amount of tokens deposited on Layer 2
     * @return unsyncedAmountOut Amount of tokens minted on Layer 2
     */
    function sync(
        address tokenIn,
        bytes calldata extraOptions,
        MessagingFee calldata fee
    )
        public
        payable
        virtual
        onlySyncKeeper
        returns (uint256 unsyncedAmountIn, uint256 unsyncedAmountOut)
    {
        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        Token storage token = $.tokens[tokenIn];

        address l1TokenIn = token.l1Address;
        if (l1TokenIn == address(0)) revert Errors.UnauthorizedToken();

        unsyncedAmountIn = token.unsyncedAmountIn;
        unsyncedAmountOut = token.unsyncedAmountOut;

        if (unsyncedAmountIn == 0 || unsyncedAmountIn < token.minSyncAmount) {
            revert Errors.InsufficientAmountToSync();
        }

        token.unsyncedAmountIn = 0;
        token.unsyncedAmountOut = 0;

        emit Sync(tokenIn, unsyncedAmountIn, unsyncedAmountOut);

        _sync(
            tokenIn,
            l1TokenIn,
            unsyncedAmountIn,
            unsyncedAmountOut,
            unsyncedAmountIn,
            extraOptions,
            fee
        );

        return (unsyncedAmountIn, unsyncedAmountOut);
    }

    /**
     * @dev Sync tokens to Layer 1
     * This will send a message to the destination endpoint with the token data to
     * sync the tokens minted on Layer 2 to Layer 1.
     * Will revert if:
     * - The token is unauthorized (that is, the l1Address is address(0))
     * - The amount to sync is zero or less than the minSyncAmount
     * @dev It is very important to listen for the Sync event to know when and how much tokens were synced
     * especially if an action is required on another chain (for example, executing the message). If an action
     * was required but was not executed, the tokens won't be sent to the L1.
     * @param tokenIn Address of the token
     * @param amount Amount of tokens to sync
     * @param extraOptions Extra options for the messaging protocol
     * @param fee Fast sync messaging fee, does not consider token bridge fees
     * @return syncedAmountIn Amount of synced tokens deposited on Layer 2
     * @return syncedAmountOut Amount of synced tokens minted on Layer 2
     */
    function sync(
        address tokenIn,
        uint256 amount,
        bytes calldata extraOptions,
        MessagingFee calldata fee
    ) public payable virtual onlySyncKeeper returns (uint256, uint256) {
        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        Token storage token = $.tokens[tokenIn];

        if (token.l1Address == address(0)) revert Errors.UnauthorizedToken();

        uint256 unsyncedAmountIn = token.unsyncedAmountIn;

        if (
            unsyncedAmountIn == 0 ||
            unsyncedAmountIn < token.minSyncAmount ||
            amount > unsyncedAmountIn
        ) {
            revert Errors.InsufficientAmountToSync();
        }

        // Reduce unsyncedAmountOut proportionally to unsyncedAmountIn
        uint256 amountOut = (token.unsyncedAmountOut * amount) /
            unsyncedAmountIn;

        token.unsyncedAmountIn -= amount;
        token.unsyncedAmountOut -= amountOut;

        emit Sync(tokenIn, amount, amountOut);

        _sync(
            tokenIn,
            token.l1Address,
            amount,
            amountOut,
            unsyncedAmountIn,
            extraOptions,
            fee
        );

        return (amount, amountOut);
    }

    /**
     * @dev Set the exchange rate provider
     * @param l2ExchangeRateProvider Address of the exchange rate provider
     */
    function setL2ExchangeRateProvider(
        address l2ExchangeRateProvider
    ) public virtual onlyOwner {
        _setL2ExchangeRateProvider(l2ExchangeRateProvider);
    }

    /**
     * @dev Set the rate limiter
     * @param rateLimiter Address of the rate limiter
     */
    function setRateLimiter(address rateLimiter) public virtual onlyOwner {
        _setRateLimiter(rateLimiter);
    }

    /**
     * @dev Set the minimum amount of tokens required to sync
     * @param tokenIn Address of the token
     * @param minSyncAmount Minimum amount of tokens required to sync
     */
    function setMinSyncAmount(
        address tokenIn,
        uint256 minSyncAmount
    ) public virtual onlyOwner {
        if (minSyncAmount == 0) revert Errors.ZeroAmount();

        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        $.tokens[tokenIn].minSyncAmount = minSyncAmount;

        emit MinSyncAmountSet(tokenIn, minSyncAmount);
    }

    /**
     * @dev Set the maximum amount of tokens to sync
     * @param tokenIn Address of the token
     * @param maxSyncAmount Maximum amount of tokens to sync
     */
    function setMaxSyncAmount(
        address tokenIn,
        uint256 maxSyncAmount
    ) public virtual onlyOwner {
        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        $.tokens[tokenIn].maxSyncAmount = maxSyncAmount;

        emit MaxSyncAmountSet(tokenIn, maxSyncAmount);
    }

    /**
     * @dev Set the Layer 1 address of the token
     * @param l2TokenIn Address of the token on Layer 2
     * @param l1TokenIn Address of the token on Layer 1
     */
    function setL1TokenIn(
        address l2TokenIn,
        address l1TokenIn
    ) public virtual onlyOwner {
        if (l1TokenIn == address(0)) revert Errors.ZeroAddress();

        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        $.tokens[l2TokenIn].l1Address = l1TokenIn;

        emit L1TokenInSet(l2TokenIn, l1TokenIn);
    }

    /**
     * @dev Set the sync keeper
     * @param syncKeeper Address of the sync keeper
     * @param status True to set as a sync keeper
     */
    function setSyncKeeper(
        address syncKeeper,
        bool status
    ) public virtual onlyOwner {
        _getL2SyncPoolStorage().syncKeeper[syncKeeper] = status;

        emit SyncKeeperSet(syncKeeper, status);
    }

    /**
     * @dev Set bridge quoter
     * @param bridgeQuoter Bridge quoter contract to get the min amount receive when bridging to L1
     */
    function setBridgeQuoter(address bridgeQuoter) public virtual onlyOwner {
        _setBridgeQuoter(bridgeQuoter);
    }

    /**
     * @dev Internal function to set bridge quoter
     * @param bridgeQuoter Bridge quoter contract
     */
    function _setBridgeQuoter(address bridgeQuoter) internal {
        _getL2SyncPoolStorage().bridgeQuoter = IBridgeQuoter(bridgeQuoter);

        emit BridgeQuoterSet(bridgeQuoter);
    }

    /**
     * @dev Internal function to set the exchange rate provider
     * @param l2ExchangeRateProvider Address of the exchange rate provider
     */
    function _setL2ExchangeRateProvider(
        address l2ExchangeRateProvider
    ) internal virtual {
        if (l2ExchangeRateProvider == address(0)) revert Errors.ZeroAddress();

        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        $.l2ExchangeRateProvider = IL2ExchangeRateProvider(
            l2ExchangeRateProvider
        );

        emit L2ExchangeRateProviderSet(l2ExchangeRateProvider);
    }

    /**
     * @dev Internal function to set the rate limiter
     * @param rateLimiter Address of the rate limiter
     */
    function _setRateLimiter(address rateLimiter) internal virtual {
        if (rateLimiter == address(0)) revert Errors.ZeroAddress();

        L2SyncPoolStorage storage $ = _getL2SyncPoolStorage();
        $.rateLimiter = IRateLimiter(rateLimiter);

        emit RateLimiterSet(rateLimiter);
    }

    /**
     * @dev Internal function to receive tokens on Layer 2
     * @param tokenIn Address of the token
     * @param amountIn Amount of tokens to receive
     */
    function _receiveTokenIn(
        address tokenIn,
        uint256 amountIn
    ) internal virtual {
        if (tokenIn == Constants.ETH_ADDRESS) {
            if (amountIn != msg.value) revert Errors.InvalidAmountIn();
        } else {
            if (msg.value != 0) revert Errors.InvalidAmountIn();

            // warning: not safe with transfer tax tokens
            SafeERC20.safeTransferFrom(
                IERC20(tokenIn),
                msg.sender,
                address(this),
                amountIn
            );
        }
    }

    /**
     * @dev Internal function to sync tokens to Layer 1
     * @param l2TokenIn Address of the token on Layer 2
     * @param l1TokenIn Address of the token on Layer 1
     * @param amountIn Amount of tokens deposited on Layer 2
     * @param amountOut Amount of tokens minted on Layer 2
     * @param totalAmountIn Total amount of tokens deposited on Layer 2
     * @param extraOptions Extra options for the messaging protocol
     * @param fee Messaging fee
     * @return receipt Messaging receipt
     */
    function _sync(
        address l2TokenIn,
        address l1TokenIn,
        uint256 amountIn,
        uint256 amountOut,
        uint256 totalAmountIn,
        bytes calldata extraOptions,
        MessagingFee calldata fee
    ) internal virtual returns (MessagingReceipt memory);

    /**
     * @dev Internal function to send tokenOut to an account
     * @param account Address of the account
     * @param amount Amount of tokens to send
     * @param shouldWrap True if the token should be wrapped
     */
    function _sendTokenOut(
        address account,
        uint256 amount,
        bool shouldWrap
    ) internal virtual;
}

File 10 of 54 : DineroERC20RebaseUpgradeable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {ERC20PermitUpgradeable, Initializable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol";
import {Errors} from "./libraries/Errors.sol";

/**
 * @title Interest-bearing ERC20-like token for L2LiquidStakingToken assets.
 *
 * This contract is abstract. To make the contract deployable override the
 * `_totalAssets` function. `L2LiquidStakingToken.sol` contract inherits DineroERC20Rebase and defines
 * the `_totalAssets` function.
 *
 * DineroERC20Rebase balances are dynamic and represent the holder's share in the total amount
 * of Pirex assets controlled by the protocol. Account shares aren't normalized, so the
 * contract also stores the sum of all shares to calculate each account's token balance
 * which equals to:
 *
 *   shares[account] * _totalAssets() / totalShares
 *
 * For example, assume that we have:
 *
 *   _totalAssets() -> 10 ETH
 *   sharesOf(user1) -> 100
 *   sharesOf(user2) -> 400
 *
 * Therefore:
 *
 *   balanceOf(user1) -> 2 tokens which corresponds 2 ETH
 *   balanceOf(user2) -> 8 tokens which corresponds 8 ETH
 *
 * Since balances of all token holders change when the amount of total pooled assets
 * changes, this token cannot fully implement ERC20 standard: it only emits `Transfer`
 * events upon explicit transfer between holders. In contrast, when total amount of
 * pooled assets increases, no `Transfer` events are generated: doing so would require
 * emitting an event for each token holder and thus running an unbounded loop.
 */
abstract contract DineroERC20RebaseUpgradeable is
    Initializable,
    ERC20PermitUpgradeable
{
    /**
     * @dev Library: FixedPointMathLib - Provides fixed-point arithmetic for uint256.
     */
    using FixedPointMathLib for uint256;

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice An executed shares transfer from `sender` to `recipient`.
     *
     * @dev emitted in pair with an ERC20-defined `Transfer` event.
     */
    event TransferShares(
        address indexed from,
        address indexed to,
        uint256 sharesValue
    );

    /**
     * @notice An executed `burnShares` request
     *
     * @dev Reports simultaneously burnt shares amount
     * and corresponding DineroERC20Rebase amount.
     * The DineroERC20Rebase amount is calculated twice: before and after the burning incurred rebase.
     *
     * @param account holder of the burnt shares
     * @param preRebaseTokenAmount amount of DineroERC20Rebase the burnt shares corresponded to before the burn
     * @param postRebaseTokenAmount amount of DineroERC20Rebase the burnt shares corresponded to after the burn
     * @param sharesAmount amount of burnt shares
     */
    event SharesBurnt(
        address indexed account,
        uint256 preRebaseTokenAmount,
        uint256 postRebaseTokenAmount,
        uint256 sharesAmount
    );

    /*//////////////////////////////////////////////////////////////
                            ERC20 REBASE STORAGE
    //////////////////////////////////////////////////////////////*/

    /// @custom:storage-location erc7201:redacted.storage.DineroERC20Rebase
    struct DineroERC20RebaseStorage {
        /**
         * @notice Total amount of shares in existence.
         *
         * @dev The sum of all accounts' shares can be an arbitrary number, therefore
         * it is necessary to store it in order to calculate each account's relative share.
         */
        uint256 totalShares;
        /**
         * @dev DineroERC20Rebase balances are dynamic and are calculated based on the accounts' shares
         * and the total amount of assets controlled by the protocol. Account shares aren't
         * normalized, so the contract also stores the sum of all shares to calculate
         * each account's token balance which equals to:
         *
         *   shares[account] * _totalAssets() / totalShares()
         */
        mapping(address => uint256) shares;
    }

    // keccak256(abi.encode(uint256(keccak256(redacted.storage.DineroERC20Rebase)) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant DineroERC20RebaseStorageLocation =
        0xddf967707f52bbdea6c202114c491d81e6de0cb9ded430e88a276a6f8d3e3800;

    function _getDineroERC20RebaseStorage()
        private
        pure
        returns (DineroERC20RebaseStorage storage $)
    {
        assembly {
            $.slot := DineroERC20RebaseStorageLocation
        }
    }

    /*//////////////////////////////////////////////////////////////
                               INITIALIZER
    //////////////////////////////////////////////////////////////*/

    function __DineroERC20Rebase_init(
        string memory name_,
        string memory symbol_
    ) internal onlyInitializing {
        // Set decoded values for name and symbol.
        __ERC20_init_unchained(name_, symbol_);

        // Set the name for EIP-712 signature.
        __ERC20Permit_init(name_);
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 OVERRIDES
    //////////////////////////////////////////////////////////////*/

    /**
     * @return the amount of tokens in existence.
     *
     * @dev Always equals to `_totalAssets()` since token amount
     * is pegged to the total amount of assets controlled by the protocol.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalAssets();
    }

    /**
     * @return the amount of tokens owned by the `_account`.
     *
     * @dev Balances are dynamic and equal the `_account`'s share in the amount of the
     * total assets controlled by the protocol. See `sharesOf`.
     */
    function balanceOf(
        address _account
    ) public view override returns (uint256) {
        return convertToAssets(_sharesOf(_account), true);
    }

    /**
     * @notice Moves `_amount` tokens from `_sender` to `_recipient`.
     * Emits a `Transfer` event.
     * Emits a `TransferShares` event.
     */
    function _update(
        address _sender,
        address _recipient,
        uint256 _amount
    ) internal override {
        uint256 sharesToTransfer = convertToShares(_amount);

        if (sharesToTransfer == 0) revert Errors.InvalidAmount();

        _transferShares(_sender, _recipient, sharesToTransfer);
        _emitTransferEvents(_sender, _recipient, _amount, sharesToTransfer);
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 REBASE FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Moves `_shares` token shares from the caller's account to the `_recipient` account.
     *
     * @return amount of transferred tokens.
     * Emits a `TransferShares` event.
     * Emits a `Transfer` event.
     *
     * Requirements:
     *
     * - `_recipient` cannot be the zero address.
     * - the caller must have at least `_shares` shares.
     * - the contract must not be paused.
     *
     * @dev The `_shares` argument is the amount of shares, not tokens.
     */
    function transferShares(
        address _recipient,
        uint256 _shares
    ) external returns (uint256) {
        _transferShares(msg.sender, _recipient, _shares);
        uint256 assets = convertToAssets(_shares, true);
        _emitTransferEvents(msg.sender, _recipient, assets, _shares);
        return assets;
    }

    /**
     * @notice Moves `_shares` token shares from the `_sender` account to the `_recipient` account.
     *
     * @return amount of transferred tokens.
     * Emits a `TransferShares` event.
     * Emits a `Transfer` event.
     *
     * Requirements:
     *
     * - `_sender` and `_recipient` cannot be the zero addresses.
     * - `_sender` must have at least `_shares` shares.
     * - the caller must have allowance for `_sender`'s tokens of at least `getPooledPxEthByShares(_shares)`.
     * - the contract must not be paused.
     *
     * @dev The `_shares` argument is the amount of shares, not tokens.
     */
    function transferSharesFrom(
        address _sender,
        address _recipient,
        uint256 _shares
    ) external returns (uint256) {
        uint256 assets = convertToAssets(_shares, false);
        _spendAllowance(_sender, msg.sender, assets);
        _transferShares(_sender, _recipient, _shares);
        _emitTransferEvents(_sender, _recipient, assets, _shares);
        return assets;
    }

    /**
     * @return the amount of shares owned by `_account`.
     */
    function getTotalShares() public view returns (uint256) {
        return _getDineroERC20RebaseStorage().totalShares;
    }

    /**
     * @return the amount of shares owned by `_account`.
     */
    function sharesOf(address _account) external view returns (uint256) {
        return _sharesOf(_account);
    }

    /**
     * @return the amount of assets that corresponds to `_shares` token shares.
     * @param floor if true, the result is rounded down, otherwise it's rounded up.
     */
    function convertToAssets(
        uint256 _shares,
        bool floor
    ) public view returns (uint256) {
        uint256 totalShares = _getDineroERC20RebaseStorage().totalShares;

        return
            totalShares == 0 ? 0 : floor
                ? _shares.mulDivDown(_totalAssets(), totalShares)
                : _shares.mulDivUp(_totalAssets(), totalShares);
    }

    /**
     * @return the amount of shares that corresponds to `_assets` (pxEth).
     */
    function convertToShares(uint256 _assets) public view returns (uint256) {
        return _convertToShares(_assets, true);
    }

    /**
     * @return the amount of shares that corresponds to `_assets` (pxEth) rounding up.
     */
    function previewWithdraw(uint256 _assets) public view returns (uint256) {
        return _convertToShares(_assets, false);
    }

    /*//////////////////////////////////////////////////////////////
                               INTERNAL LOGIC
    //////////////////////////////////////////////////////////////*/
    /**
     * @return the total amount (in wei) of Pirex assets controlled by the protocol.
     * @dev This is used for calculating tokens from shares and vice versa.
     * @dev This function is required to be implemented in a derived contract.
     */
    function _totalAssets() internal view virtual returns (uint256);

    /**
     * @return the amount of shares owned by `_account`.
     */
    function _sharesOf(address _account) internal view returns (uint256) {
        return _getDineroERC20RebaseStorage().shares[_account];
    }

    /**
     * @notice Moves `_shares` shares from `_sender` to `_recipient`.
     *
     * Requirements:
     *
     * - `_sender` cannot be the zero address.
     * - `_recipient` cannot be the zero address or the `DineroERC20Rebase` token contract itself
     * - `_sender` must hold at least `_shares` shares.
     * - the contract must not be paused.
     */
    function _transferShares(
        address _sender,
        address _recipient,
        uint256 _shares
    ) internal {
        if (_sender == address(0) || _recipient == address(0))
            revert Errors.ZeroAddress();
        if (_recipient == address(this) || _sender == _recipient)
            revert Errors.NotAllowed();

        DineroERC20RebaseStorage storage $ = _getDineroERC20RebaseStorage();

        uint256 currentSenderShares = $.shares[_sender];

        if (_shares > currentSenderShares) revert Errors.InvalidAmount();

        $.shares[_sender] = currentSenderShares - _shares;
        $.shares[_recipient] += _shares;
    }

    /**
     * @notice Creates `_shares` shares and assigns them to `_recipient`, increasing the total amount of shares.
     * @dev This doesn't increase the token total supply.
     *
     * NB: The method doesn't check protocol pause relying on the external enforcement.
     *
     * Requirements:
     *
     * - `_recipient` cannot be the zero address.
     * - the contract must not be paused.
     */
    function _mintShares(
        address _recipient,
        uint256 _shares
    ) internal returns (uint256) {
        if (_recipient == address(0)) revert Errors.ZeroAddress();

        DineroERC20RebaseStorage storage $ = _getDineroERC20RebaseStorage();

        $.totalShares += _shares;

        $.shares[_recipient] = $.shares[_recipient] + _shares;

        return $.totalShares;

        // Notice: we're not emitting a Transfer event from the zero address here since shares mint
        // works by taking the amount of tokens corresponding to the minted shares from all other
        // token holders, proportionally to their share. The total supply of the token doesn't change
        // as the result. This is equivalent to performing a send from each other token holder's
        // address to `address`, but we cannot reflect this as it would require sending an unbounded
        // number of events.
    }

    /**
     * @notice Destroys `_shares` shares from `_account`'s holdings, decreasing the total amount of shares.
     * @dev This doesn't decrease the token total supply.
     *
     * Requirements:
     *
     * - `_account` cannot be the zero address.
     * - `_account` must hold at least `_shares` shares.
     * - the contract must not be paused.
     */
    function _burnShares(
        address _account,
        uint256 _shares
    ) internal returns (uint256) {
        if (_account == address(0)) revert Errors.ZeroAddress();

        DineroERC20RebaseStorage storage $ = _getDineroERC20RebaseStorage();

        uint256 accountShares = $.shares[_account];
        if (_shares > accountShares) revert Errors.InvalidAmount();

        uint256 preRebaseTokenAmount = convertToAssets(_shares, true);

        $.totalShares -= _shares;

        $.shares[_account] = accountShares - _shares;

        uint256 postRebaseTokenAmount = convertToAssets(_shares, true);

        emit SharesBurnt(
            _account,
            preRebaseTokenAmount,
            postRebaseTokenAmount,
            _shares
        );

        return $.totalShares;

        // Notice: we're not emitting a Transfer event to the zero address here since shares burn
        // works by redistributing the amount of tokens corresponding to the burned shares between
        // all other token holders. The total supply of the token doesn't change as the result.
        // This is equivalent to performing a send from `address` to each other token holder address,
        // but we cannot reflect this as it would require sending an unbounded number of events.

        // We're emitting `SharesBurnt` event to provide an explicit rebase log record nonetheless.
    }

    /**
     * @dev Emits {Transfer} and {TransferShares} events
     */
    function _emitTransferEvents(
        address _from,
        address _to,
        uint256 _assets,
        uint256 _shares
    ) internal {
        emit Transfer(_from, _to, _assets);
        emit TransferShares(_from, _to, _shares);
    }

    /**
     * @dev Converts `_assets` (pxEth) to shares.
     *
     * @param _assets amount of assets to convert to shares.
     * @param floor if true, the result is rounded down, otherwise it's rounded up.
     */
    function _convertToShares(
        uint256 _assets,
        bool floor
    ) internal view returns (uint256) {
        uint256 totalShares = _getDineroERC20RebaseStorage().totalShares;
        uint256 totalPooledPxEth = _totalAssets();

        if (totalPooledPxEth == 0) return 0;

        return
            floor
                ? _assets.mulDivDown(totalShares, totalPooledPxEth)
                : _assets.mulDivUp(totalShares, totalPooledPxEth);
    }
}

File 11 of 54 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

/**
 * @title  Constants
 * @notice Library containing various constants for the L2LiquidStakingToken system.
 * @author redactedcartel.finance
 */
library Constants {
    /**
     * @notice Message type constant for deposit.
     * @dev This constant defines the message type for deposit operations.
     */
    uint8 constant MESSAGE_TYPE_DEPOSIT = 1;

    /**
     * @notice Message type constant for deposit.
     * @dev This constant defines the message type for deposit operations.
     */
    uint8 constant MESSAGE_TYPE_DEPOSIT_WRAP = 2;

    /**
     * @notice Message type constant for withdrawal.
     * @dev This constant defines the message type for withdrawal operations.
     */
    uint8 constant MESSAGE_TYPE_WITHDRAW = 3;

    /**
     * @notice Message type constant for rebase.
     * @dev This constant defines the message type for rebase operations.
     */
    uint8 constant MESSAGE_TYPE_REBASE = 4;

    /**
     * @notice Message type constant for sync.
     * @dev This constant defines the message type for sync operations.
     */
    uint8 constant MESSAGE_TYPE_SYNC = 5;

    /**
     * @notice The destination endpoint ID for Mainnet.
     * @dev This constant holds the destination endpoint ID for Mainnet.
     */
    uint32 constant MAINNET_EID = 30101;

    /**
     * @notice Fee denominator for precise fee calculations.
     * @dev This constant holds the fee denominator for precise fee calculations.
     */
    uint256 constant FEE_DENOMINATOR = 1_000_000;

    /**
     * @notice Max rebase fee.
     * @dev This constant holds the maximum rebase fee that can be set.
     */
    uint256 constant MAX_REBASE_FEE = 200_000;

    /**
     * @notice Max deposit fee.
     * @dev This constant holds the maximum sync deposit fee that can be set.
     */
    uint256 constant MAX_DEPOSIT_FEE = 200_000;

    /**
     * @dev The address of the ETH token.
     */
    address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
}

File 12 of 54 : Errors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

library Errors {
    /**
     * @dev Zero address specified
     */
    error ZeroAddress();

    /**
     * @dev Zero amount specified
     */
    error ZeroAmount();

    /**
     * @dev Invalid fee specified
     */
    error InvalidFee();

    /**
     * @dev not same as deposit size
     */
    error InvalidAmount();

    /**
     * @dev Invalid nonce
     */
    error InvalidNonce();

    /**
     * @dev not allowed
     */
    error NotAllowed();

    /**
     * @dev Only ETH allowed
     */
    error OnlyETH();

    /**
     * @dev Invalid rate
     */
    error InvalidRate();

    /**
     * @dev Withdraw limit exceeded
     */
    error WithdrawLimitExceeded();

    /**
     * @dev Unauthorized caller on SyncPool
     */
    error UnauthorizedCaller();

    /**
     * @dev Native transfer failed on SyncPool
     */
    error NativeTransferFailed();

    /**
     * @dev Insufficient amount out
     */
    error InsufficientAmountOut();
    
    /**
     * @dev Insufficient amount to sync
     */
    error InsufficientAmountToSync();
    
    /**
     * @dev Unauthorized token
     */
    error UnauthorizedToken();

    /**
     * @dev Invalid amount in
     */
    error InvalidAmountIn();

    /**
     * @dev Max sync amount exceeded, to prevent going over the bridge limit
     */
    error MaxSyncAmountExceeded();

    /**
     * @dev Unsupported destination chain
     */
    error UnsupportedEid();

    /**
     * @dev Multichain eposits can't be wrapped
     */
    error MultichainDepositsCannotBeWrapped();

    /**
     * @dev OFT lockbox not set for multichain deposit
     */
    error OFTLockboxNotSet();

    /**
     * @dev Invalid receiver address
     */
    error InvalidReceiver();
}

File 13 of 54 : IRateProvider.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IL2ExchangeRateProvider} from "contracts/vendor/layerzero/syncpools/interfaces/IL2ExchangeRateProvider.sol";

interface IRateProvider is IL2ExchangeRateProvider {
    function getConversionAmount(
        address tokenIn,
        uint256 amountIn
    ) external returns (uint256 amountOut);

    function getAssetsPerShare() external returns (uint256 assetsPerShare);
}

File 14 of 54 : IWrappedLiquidStakedToken.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IWrappedLiquidStakedToken {
    function wrap(uint256 _amount) external returns (uint256);
    function unwrap(uint256 _amount) external returns (uint256);
    function getLSTAddress() external view returns (address);
    function transfer(address recipient, uint256 amount) external returns (bool);
}

File 15 of 54 : OAppSenderUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { MessagingParams, MessagingFee, MessagingReceipt } from "contracts/vendor/layerzero/protocol/interfaces/ILayerZeroEndpointV2.sol";
import { OAppCoreUpgradeable } from "./OAppCoreUpgradeable.sol";

/**
 * @title OAppSender
 * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.
 */
abstract contract OAppSenderUpgradeable is OAppCoreUpgradeable {
    using SafeERC20 for IERC20;

    // Custom error messages
    error NotEnoughNative(uint256 msgValue);
    error LzTokenUnavailable();

    // @dev The version of the OAppSender implementation.
    // @dev Version is bumped when changes are made to this contract.
    uint64 internal constant SENDER_VERSION = 1;

    /**
     * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
     * accommodate the different version of Ownable.
     */
    function __OAppSender_init() internal onlyInitializing {}

    function __OAppSender_init_unchained() internal onlyInitializing {}

    /**
     * @notice Retrieves the OApp version information.
     * @return senderVersion The version of the OAppSender.sol contract.
     * @return receiverVersion The version of the OAppReceiver.sol contract.
     *
     * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.
     * ie. this is a SEND only OApp.
     * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions
     */
    function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {
        return (SENDER_VERSION, 0);
    }

    /**
     * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation.
     * @param _dstEid The destination endpoint ID.
     * @param _message The message payload.
     * @param _options Additional options for the message.
     * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens.
     * @return fee The calculated MessagingFee for the message.
     *      - nativeFee: The native fee for the message.
     *      - lzTokenFee: The LZ token fee for the message.
     */
    function _quote(
        uint32 _dstEid,
        bytes memory _message,
        bytes memory _options,
        bool _payInLzToken
    ) internal view virtual returns (MessagingFee memory fee) {
        return
            endpoint.quote(
                MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken),
                address(this)
            );
    }

    /**
     * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message.
     * @param _dstEid The destination endpoint ID.
     * @param _message The message payload.
     * @param _options Additional options for the message.
     * @param _fee The calculated LayerZero fee for the message.
     *      - nativeFee: The native fee.
     *      - lzTokenFee: The lzToken fee.
     * @param _refundAddress The address to receive any excess fee values sent to the endpoint.
     * @return receipt The receipt for the sent message.
     *      - guid: The unique identifier for the sent message.
     *      - nonce: The nonce of the sent message.
     *      - fee: The LayerZero fee incurred for the message.
     */
    function _lzSend(
        uint32 _dstEid,
        bytes memory _message,
        bytes memory _options,
        MessagingFee memory _fee,
        address _refundAddress
    ) internal virtual returns (MessagingReceipt memory receipt) {
        // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint.
        uint256 messageValue = _payNative(_fee.nativeFee);
        if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee);

        return
            endpoint.send{ value: messageValue }(
            // solhint-disable-next-line check-send-result
                MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0),
                _refundAddress
            );
    }

    /**
     * @dev Internal function to pay the native fee associated with the message.
     * @param _nativeFee The native fee to be paid.
     * @return nativeFee The amount of native currency paid.
     *
     * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction,
     * this will need to be overridden because msg.value would contain multiple lzFees.
     * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency.
     * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees.
     * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time.
     */
    function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) {
        if (msg.value != _nativeFee) revert NotEnoughNative(msg.value);
        return _nativeFee;
    }

    /**
     * @dev Internal function to pay the LZ token fee associated with the message.
     * @param _lzTokenFee The LZ token fee to be paid.
     *
     * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint.
     * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend().
     */
    function _payLzToken(uint256 _lzTokenFee) internal virtual {
        // @dev Cannot cache the token because it is not immutable in the endpoint.
        address lzToken = endpoint.lzToken();
        if (lzToken == address(0)) revert LzTokenUnavailable();

        // Pay LZ token fee by sending tokens to the endpoint.
        IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee);
    }
}

File 16 of 54 : OAppUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers
// solhint-disable-next-line no-unused-import
import { OAppSenderUpgradeable, MessagingFee, MessagingReceipt } from "./OAppSenderUpgradeable.sol";
// @dev Import the 'Origin' so it's exposed to OApp implementers
// solhint-disable-next-line no-unused-import
import { OAppReceiverUpgradeable, Origin } from "./OAppReceiverUpgradeable.sol";
import { OAppCoreUpgradeable } from "./OAppCoreUpgradeable.sol";

/**
 * @title OApp
 * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality.
 */
abstract contract OAppUpgradeable is OAppSenderUpgradeable, OAppReceiverUpgradeable {
    /**
     * @dev Constructor to initialize the OApp with the provided endpoint and owner.
     * @param _endpoint The address of the LOCAL LayerZero endpoint.
     */
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(address _endpoint) OAppCoreUpgradeable(_endpoint) {}

    /**
     * @dev Initializes the OApp with the provided delegate.
     * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
     *
     * @dev The delegate typically should be set as the owner of the contract.
     * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
     * accommodate the different version of Ownable.
     */
    function __OApp_init(address _delegate) internal onlyInitializing {
        __OAppCore_init(_delegate);
    }

    function __OApp_init_unchained() internal onlyInitializing {}

    /**
     * @notice Retrieves the OApp version information.
     * @return senderVersion The version of the OAppSender.sol implementation.
     * @return receiverVersion The version of the OAppReceiver.sol implementation.
     */
    function oAppVersion()
        public
        pure
        virtual
        override(OAppSenderUpgradeable, OAppReceiverUpgradeable)
        returns (uint64 senderVersion, uint64 receiverVersion)
    {
        return (SENDER_VERSION, RECEIVER_VERSION);
    }
}

File 17 of 54 : IRateLimiter.sol
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;

interface IRateLimiter {
    function updateRateLimit(address sender, address tokenIn, uint256 amountIn, uint256 amountOut) external;
}

File 18 of 54 : BaseMessengerUpgradeable.sol
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

/**
 * @title Base Messenger
 * @dev Base contract for setting the messenger contract
 */
abstract contract BaseMessengerUpgradeable is OwnableUpgradeable {
    struct BaseMessengerStorage {
        address messenger;
    }

    // keccak256(abi.encode(uint256(keccak256(syncpools.storage.basemessenger)) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant BaseMessengerStorageLocation =
        0x2d365d82646798ae645c4baa2dc2ee228626f61d8b5395bf298ba125a3c6b100;

    function _getBaseMessengerStorage() internal pure returns (BaseMessengerStorage storage $) {
        assembly {
            $.slot := BaseMessengerStorageLocation
        }
    }

    event MessengerSet(address messenger);

    function __BaseMessenger_init(address messenger) internal onlyInitializing {
        __BaseMessenger_init_unchained(messenger);
    }

    function __BaseMessenger_init_unchained(address messenger) internal onlyInitializing {
        _setMessenger(messenger);
    }

    /**
     * @dev Get the messenger address
     * @return The messenger address
     */
    function getMessenger() public view virtual returns (address) {
        BaseMessengerStorage storage $ = _getBaseMessengerStorage();
        return $.messenger;
    }

    /**
     * @dev Set the messenger address
     * @param messenger The messenger address
     */
    function setMessenger(address messenger) public virtual onlyOwner {
        _setMessenger(messenger);
    }

    /**
     * @dev Internal function to set the messenger address
     * @param messenger The messenger address
     */
    function _setMessenger(address messenger) internal {
        BaseMessengerStorage storage $ = _getBaseMessengerStorage();
        $.messenger = messenger;

        emit MessengerSet(messenger);
    }
}

File 19 of 54 : BaseReceiverUpgradeable.sol
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

/**
 * @title Base Receiver
 * @dev Base contract for setting the receiver contract
 */
abstract contract BaseReceiverUpgradeable is OwnableUpgradeable {
    struct BaseReceiverStorage {
        address receiver;
    }

    // keccak256(abi.encode(uint256(keccak256(syncpools.storage.basereceiver)) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant BaseReceiverStorageLocation =
        0x487698e326934c06370ca3c28e3bca79fe27d578048e9d42af7fa98f2e481e00;

    function _getBaseReceiverStorage() internal pure returns (BaseReceiverStorage storage $) {
        assembly {
            $.slot := BaseReceiverStorageLocation
        }
    }

    event ReceiverSet(address receiver);

    function __BaseReceiver_init(address receiver) internal onlyInitializing {
        __BaseReceiver_init_unchained(receiver);
    }

    function __BaseReceiver_init_unchained(address receiver) internal onlyInitializing {
        _setReceiver(receiver);
    }

    /**
     * @dev Get the receiver address
     * @return The receiver address
     */
    function getReceiver() public view virtual returns (address) {
        BaseReceiverStorage storage $ = _getBaseReceiverStorage();
        return $.receiver;
    }

    /**
     * @dev Set the receiver address
     * @param receiver The receiver address
     */
    function setReceiver(address receiver) public virtual onlyOwner {
        _setReceiver(receiver);
    }

    /**
     * @dev Internal function to set the receiver address
     * @param receiver The receiver address
     */
    function _setReceiver(address receiver) internal {
        BaseReceiverStorage storage $ = _getBaseReceiverStorage();
        $.receiver = receiver;

        emit ReceiverSet(receiver);
    }
}

File 20 of 54 : OAppOptionsType3Upgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { IOAppOptionsType3, EnforcedOptionParam } from "../interfaces/IOAppOptionsType3.sol";

/**
 * @title OAppOptionsType3
 * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options.
 */
abstract contract OAppOptionsType3Upgradeable is IOAppOptionsType3, OwnableUpgradeable {
    struct OAppOptionsType3Storage {
        // @dev The "msgType" should be defined in the child contract.
        mapping(uint32 => mapping(uint16 => bytes)) enforcedOptions;
    }

    // keccak256(abi.encode(uint256(keccak256("layerzerov2.storage.oappoptionstype3")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant OAppOptionsType3StorageLocation =
        0x8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea0000;

    uint16 internal constant OPTION_TYPE_3 = 3;

    function _getOAppOptionsType3Storage() internal pure returns (OAppOptionsType3Storage storage $) {
        assembly {
            $.slot := OAppOptionsType3StorageLocation
        }
    }

    /**
     * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
     * accommodate the different version of Ownable.
     */
    function __OAppOptionsType3_init() internal onlyInitializing {}

    function __OAppOptionsType3_init_unchained() internal onlyInitializing {}

    function enforcedOptions(uint32 _eid, uint16 _msgType) public view returns (bytes memory) {
        OAppOptionsType3Storage storage $ = _getOAppOptionsType3Storage();
        return $.enforcedOptions[_eid][_msgType];
    }

    /**
     * @dev Sets the enforced options for specific endpoint and message type combinations.
     * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options.
     *
     * @dev Only the owner/admin of the OApp can call this function.
     * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc.
     * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType.
     * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay
     * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose().
     */
    function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner {
        OAppOptionsType3Storage storage $ = _getOAppOptionsType3Storage();
        for (uint256 i = 0; i < _enforcedOptions.length; i++) {
            // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining.
            _assertOptionsType3(_enforcedOptions[i].options);
            $.enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options;
        }

        emit EnforcedOptionSet(_enforcedOptions);
    }

    /**
     * @notice Combines options for a given endpoint and message type.
     * @param _eid The endpoint ID.
     * @param _msgType The OAPP message type.
     * @param _extraOptions Additional options passed by the caller.
     * @return options The combination of caller specified options AND enforced options.
     *
     * @dev If there is an enforced lzReceive option:
     * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether}
     * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function.
     * @dev This presence of duplicated options is handled off-chain in the verifier/executor.
     */
    function combineOptions(
        uint32 _eid,
        uint16 _msgType,
        bytes calldata _extraOptions
    ) public view virtual returns (bytes memory) {
        OAppOptionsType3Storage storage $ = _getOAppOptionsType3Storage();
        bytes memory enforced = $.enforcedOptions[_eid][_msgType];

        // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options.
        if (enforced.length == 0) return _extraOptions;

        // No caller options, return enforced
        if (_extraOptions.length == 0) return enforced;

        // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined.
        if (_extraOptions.length >= 2) {
            _assertOptionsType3(_extraOptions);
            // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced.
            return bytes.concat(enforced, _extraOptions[2:]);
        }

        // No valid set of options was found.
        revert InvalidOptions(_extraOptions);
    }

    /**
     * @dev Internal function to assert that options are of type 3.
     * @param _options The options to be checked.
     */
    function _assertOptionsType3(bytes calldata _options) internal pure virtual {
        uint16 optionsType = uint16(bytes2(_options[0:2]));
        if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options);
    }
}

File 21 of 54 : PausableUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)

pragma solidity ^0.8.20;

import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
    /// @custom:storage-location erc7201:openzeppelin.storage.Pausable
    struct PausableStorage {
        bool _paused;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;

    function _getPausableStorage() private pure returns (PausableStorage storage $) {
        assembly {
            $.slot := PausableStorageLocation
        }
    }

    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    /**
     * @dev The operation failed because the contract is paused.
     */
    error EnforcedPause();

    /**
     * @dev The operation failed because the contract is not paused.
     */
    error ExpectedPause();

    /**
     * @dev Initializes the contract in unpaused state.
     */
    function __Pausable_init() internal onlyInitializing {
        __Pausable_init_unchained();
    }

    function __Pausable_init_unchained() internal onlyInitializing {
        PausableStorage storage $ = _getPausableStorage();
        $._paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        PausableStorage storage $ = _getPausableStorage();
        return $._paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        if (paused()) {
            revert EnforcedPause();
        }
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        if (!paused()) {
            revert ExpectedPause();
        }
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        PausableStorage storage $ = _getPausableStorage();
        $._paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        PausableStorage storage $ = _getPausableStorage();
        $._paused = false;
        emit Unpaused(_msgSender());
    }
}

File 22 of 54 : ReentrancyGuardUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuardUpgradeable is Initializable {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
    struct ReentrancyGuardStorage {
        uint256 _status;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;

    function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
        assembly {
            $.slot := ReentrancyGuardStorageLocation
        }
    }

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    function __ReentrancyGuard_init() internal onlyInitializing {
        __ReentrancyGuard_init_unchained();
    }

    function __ReentrancyGuard_init_unchained() internal onlyInitializing {
        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
        $._status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if ($._status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        $._status = ENTERED;
    }

    function _nonReentrantAfter() private {
        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        $._status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
        return $._status == ENTERED;
    }
}

File 23 of 54 : FixedPointMathLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant MAX_UINT256 = 2**256 - 1;

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // Divide x * y by the denominator.
            z := div(mul(x, y), denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // If x * y modulo the denominator is strictly greater than 0,
            // 1 is added to round up the division of x * y by the denominator.
            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            let y := x // We start y at x, which will help us make our initial estimate.

            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // We check y >= 2^(k + 8) but shift right by k bits
            // each branch to ensure that if x >= 256, then y >= 256.
            if iszero(lt(y, 0x10000000000000000000000000000000000)) {
                y := shr(128, y)
                z := shl(64, z)
            }
            if iszero(lt(y, 0x1000000000000000000)) {
                y := shr(64, y)
                z := shl(32, z)
            }
            if iszero(lt(y, 0x10000000000)) {
                y := shr(32, y)
                z := shl(16, z)
            }
            if iszero(lt(y, 0x1000000)) {
                y := shr(16, y)
                z := shl(8, z)
            }

            // Goal was to get z*z*y within a small factor of x. More iterations could
            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).
            // We ensured y >= 256 so that the relative difference between y and y+1 is small.
            // That's not possible if x < 256 but we can just verify those cases exhaustively.

            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.

            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.

            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.

            // There is no overflow risk here since y < 2^136 after the first branch above.
            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // If x+1 is a perfect square, the Babylonian method cycles between
            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.
            z := sub(z, lt(div(x, z), z))
        }
    }

    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Mod x by y. Note this will return
            // 0 instead of reverting if y is zero.
            z := mod(x, y)
        }
    }

    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Divide x by y. Note this will return
            // 0 instead of reverting if y is zero.
            r := div(x, y)
        }
    }

    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Add 1 to x * y if x % y > 0. Note this will
            // return 0 instead of reverting if y is zero.
            z := add(gt(mod(x, y), 0), div(x, y))
        }
    }
}

File 24 of 54 : IBridgeQuoter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IBridgeQuoter {
    function getAmountOut(
        address token,
        uint256 amountIn
    ) external view returns (uint256 amountSent, uint256 amountReceived);
}

File 25 of 54 : ILayerZeroReceiver.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

import { Origin } from "./ILayerZeroEndpointV2.sol";

interface ILayerZeroReceiver {
    function allowInitializePath(Origin calldata _origin) external view returns (bool);

    function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64);

    function lzReceive(
        Origin calldata _origin,
        bytes32 _guid,
        bytes calldata _message,
        address _executor,
        bytes calldata _extraData
    ) external payable;
}

File 26 of 54 : ILayerZeroEndpointV2.sol
// 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;
}

File 27 of 54 : IL2ExchangeRateProvider.sol
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;

interface IL2ExchangeRateProvider {
    function getConversionAmount(address tokenIn, uint256 amountIn) external returns (uint256 amountOut);
    function getPostFeeAmount(address tokenIn, uint256 amountIn) external view returns (uint256);
}

File 28 of 54 : IOAppOptionsType3.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @dev Struct representing enforced option parameters.
 */
struct EnforcedOptionParam {
    uint32 eid; // Endpoint ID
    uint16 msgType; // Message Type
    bytes options; // Additional options
}

/**
 * @title IOAppOptionsType3
 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options.
 */
interface IOAppOptionsType3 {
    // Custom error message for invalid options
    error InvalidOptions(bytes options);

    // Event emitted when enforced options are set
    event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions);

    /**
     * @notice Sets enforced options for specific endpoint and message type combinations.
     * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options.
     */
    function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external;

    /**
     * @notice Combines options for a given endpoint and message type.
     * @param _eid The endpoint ID.
     * @param _msgType The OApp message type.
     * @param _extraOptions Additional options passed by the caller.
     * @return options The combination of caller specified options AND enforced options.
     */
    function combineOptions(
        uint32 _eid,
        uint16 _msgType,
        bytes calldata _extraOptions
    ) external view returns (bytes memory options);
}

File 29 of 54 : OAppCoreUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { IOAppCore, ILayerZeroEndpointV2 } from "./interfaces/IOAppCore.sol";

/**
 * @title OAppCore
 * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.
 */
abstract contract OAppCoreUpgradeable is IOAppCore, OwnableUpgradeable {
    struct OAppCoreStorage {
        mapping(uint32 => bytes32) peers;
    }

    // keccak256(abi.encode(uint256(keccak256("layerzerov2.storage.oappcore")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant OAppCoreStorageLocation =
        0x72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f900;

    function _getOAppCoreStorage() internal pure returns (OAppCoreStorage storage $) {
        assembly {
            $.slot := OAppCoreStorageLocation
        }
    }

    // The LayerZero endpoint associated with the given OApp
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
    ILayerZeroEndpointV2 public immutable endpoint;

    /**
     * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.
     * @param _endpoint The address of the LOCAL Layer Zero endpoint.
     */
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(address _endpoint) {
        endpoint = ILayerZeroEndpointV2(_endpoint);
    }

    /**
     * @dev Initializes the OAppCore with the provided delegate.
     * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
     *
     * @dev The delegate typically should be set as the owner of the contract.
     * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
     * accommodate the different version of Ownable.
     */
    function __OAppCore_init(address _delegate) internal onlyInitializing {
        __OAppCore_init_unchained(_delegate);
    }

    function __OAppCore_init_unchained(address _delegate) internal onlyInitializing {
        if (_delegate == address(0)) revert InvalidDelegate();
        endpoint.setDelegate(_delegate);
    }

    /**
     * @notice Returns the peer address (OApp instance) associated with a specific endpoint.
     * @param _eid The endpoint ID.
     * @return peer The address of the peer associated with the specified endpoint.
     */
    function peers(uint32 _eid) public view override returns (bytes32) {
        OAppCoreStorage storage $ = _getOAppCoreStorage();
        return $.peers[_eid];
    }

    /**
     * @notice Sets the peer address (OApp instance) for a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @param _peer The address of the peer to be associated with the corresponding endpoint.
     *
     * @dev Only the owner/admin of the OApp can call this function.
     * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.
     * @dev Set this to bytes32(0) to remove the peer address.
     * @dev Peer is a bytes32 to accommodate non-evm chains.
     */
    function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner {
        OAppCoreStorage storage $ = _getOAppCoreStorage();
        $.peers[_eid] = _peer;
        emit PeerSet(_eid, _peer);
    }

    /**
     * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set.
     * ie. the peer is set to bytes32(0).
     * @param _eid The endpoint ID.
     * @return peer The address of the peer associated with the specified endpoint.
     */
    function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) {
        OAppCoreStorage storage $ = _getOAppCoreStorage();
        bytes32 peer = $.peers[_eid];
        if (peer == bytes32(0)) revert NoPeer(_eid);
        return peer;
    }

    /**
     * @notice Sets the delegate address for the OApp.
     * @param _delegate The address of the delegate to be set.
     *
     * @dev Only the owner/admin of the OApp can call this function.
     * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract.
     */
    function setDelegate(address _delegate) public onlyOwner {
        endpoint.setDelegate(_delegate);
    }
}

File 30 of 54 : OAppReceiverUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IOAppReceiver, Origin } from "./interfaces/IOAppReceiver.sol";
import { OAppCoreUpgradeable } from "./OAppCoreUpgradeable.sol";

/**
 * @title OAppReceiver
 * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.
 */
abstract contract OAppReceiverUpgradeable is IOAppReceiver, OAppCoreUpgradeable {
    // Custom error message for when the caller is not the registered endpoint/
    error OnlyEndpoint(address addr);

    // @dev The version of the OAppReceiver implementation.
    // @dev Version is bumped when changes are made to this contract.
    uint64 internal constant RECEIVER_VERSION = 1;

    /**
     * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
     * accommodate the different version of Ownable.
     */
    function __OAppReceiver_init() internal onlyInitializing {}

    function __OAppReceiver_init_unchained() internal onlyInitializing {}

    /**
     * @notice Retrieves the OApp version information.
     * @return senderVersion The version of the OAppSender.sol contract.
     * @return receiverVersion The version of the OAppReceiver.sol contract.
     *
     * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented.
     * ie. this is a RECEIVE only OApp.
     * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions.
     */
    function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {
        return (0, RECEIVER_VERSION);
    }

    /**
     * @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.
     * @return sender The address responsible for 'sending' composeMsg's to the Endpoint.
     *
     * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
     * @dev The default sender IS the OApp implementer.
     */
    function composeMsgSender() public view virtual returns (address sender) {
        return address(this);
    }

    /**
     * @notice Checks if the path initialization is allowed based on the provided origin.
     * @param origin The origin information containing the source endpoint and sender address.
     * @return Whether the path has been initialized.
     *
     * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received.
     * @dev This defaults to assuming if a peer has been set, its initialized.
     * Can be overridden by the OApp if there is other logic to determine this.
     */
    function allowInitializePath(Origin calldata origin) public view virtual returns (bool) {
        return peers(origin.srcEid) == origin.sender;
    }

    /**
     * @notice Retrieves the next nonce for a given source endpoint and sender address.
     * @dev _srcEid The source endpoint ID.
     * @dev _sender The sender address.
     * @return nonce The next nonce.
     *
     * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement.
     * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered.
     * @dev This is also enforced by the OApp.
     * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0.
     */
    function nextNonce(uint32, /*_srcEid*/ bytes32 /*_sender*/) public view virtual returns (uint64 nonce) {
        return 0;
    }

    /**
     * @dev Entry point for receiving messages or packets from the endpoint.
     * @param _origin The origin information containing the source endpoint and sender address.
     *  - srcEid: The source chain endpoint ID.
     *  - sender: The sender address on the src chain.
     *  - nonce: The nonce of the message.
     * @param _guid The unique identifier for the received LayerZero message.
     * @param _message The payload of the received message.
     * @param _executor The address of the executor for the received message.
     * @param _extraData Additional arbitrary data provided by the corresponding executor.
     *
     * @dev Entry point for receiving msg/packet from the LayerZero endpoint.
     */
    function lzReceive(
        Origin calldata _origin,
        bytes32 _guid,
        bytes calldata _message,
        address _executor,
        bytes calldata _extraData
    ) public payable virtual {
        // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp.
        if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender);

        // Ensure that the sender matches the expected peer for the source endpoint.
        if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender);

        // Call the internal OApp implementation of lzReceive.
        _lzReceive(_origin, _guid, _message, _executor, _extraData);
    }

    /**
     * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation.
     */
    function _lzReceive(
        Origin calldata _origin,
        bytes32 _guid,
        bytes calldata _message,
        address _executor,
        bytes calldata _extraData
    ) internal virtual;
}

File 31 of 54 : OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.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.
 *
 * The initial owner is set to the address provided by the deployer. 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 OwnableUpgradeable is Initializable, ContextUpgradeable {
    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable
    struct OwnableStorage {
        address _owner;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;

    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
        assembly {
            $.slot := OwnableStorageLocation
        }
    }

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    function __Ownable_init(address initialOwner) internal onlyInitializing {
        __Ownable_init_unchained(initialOwner);
    }

    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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) {
        OwnableStorage storage $ = _getOwnableStorage();
        return $._owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        OwnableStorage storage $ = _getOwnableStorage();
        address oldOwner = $._owner;
        $._owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 32 of 54 : ERC20PermitUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/ERC20Permit.sol)

pragma solidity ^0.8.20;

import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import {ERC20Upgradeable} from "../ERC20Upgradeable.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {EIP712Upgradeable} from "../../../utils/cryptography/EIP712Upgradeable.sol";
import {NoncesUpgradeable} from "../../../utils/NoncesUpgradeable.sol";
import {Initializable} from "../../../proxy/utils/Initializable.sol";

/**
 * @dev Implementation of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC-20 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.
 */
abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20Permit, EIP712Upgradeable, NoncesUpgradeable {
    bytes32 private constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Permit deadline has expired.
     */
    error ERC2612ExpiredSignature(uint256 deadline);

    /**
     * @dev Mismatched signature.
     */
    error ERC2612InvalidSigner(address signer, address owner);

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC-20 token name.
     */
    function __ERC20Permit_init(string memory name) internal onlyInitializing {
        __EIP712_init_unchained(name, "1");
    }

    function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}

    /**
     * @inheritdoc IERC20Permit
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        if (block.timestamp > deadline) {
            revert ERC2612ExpiredSignature(deadline);
        }

        bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        if (signer != owner) {
            revert ERC2612InvalidSigner(signer, owner);
        }

        _approve(owner, spender, value);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    function nonces(address owner) public view virtual override(IERC20Permit, NoncesUpgradeable) returns (uint256) {
        return super.nonces(owner);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {
        return _domainSeparatorV4();
    }
}

File 33 of 54 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../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 An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @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.encodeCall(token.transfer, (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.encodeCall(token.transferFrom, (from, to, 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);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @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.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @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);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @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(token).code.length > 0;
    }
}

File 34 of 54 : ContextUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @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 ContextUpgradeable is Initializable {
    function __Context_init() internal onlyInitializing {
    }

    function __Context_init_unchained() internal onlyInitializing {
    }
    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;
    }
}

File 35 of 54 : Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reininitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        assembly {
            $.slot := INITIALIZABLE_STORAGE
        }
    }
}

File 36 of 54 : IMessageLibManager.sol
// 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 _timeout) 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 _gracePeriod) 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);
}

File 37 of 54 : IMessagingComposer.sol
// 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;
}

File 38 of 54 : IMessagingContext.sol
// 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);
}

File 39 of 54 : IMessagingChannel.sol
// 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);
}

File 40 of 54 : IOAppCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { ILayerZeroEndpointV2 } from "contracts/vendor/layerzero/protocol/interfaces/ILayerZeroEndpointV2.sol";

/**
 * @title IOAppCore
 */
interface IOAppCore {
    // Custom error messages
    error OnlyPeer(uint32 eid, bytes32 sender);
    error NoPeer(uint32 eid);
    error InvalidEndpointCall();
    error InvalidDelegate();

    // Event emitted when a peer (OApp) is set for a corresponding endpoint
    event PeerSet(uint32 eid, bytes32 peer);

    /**
     * @notice Retrieves the OApp version information.
     * @return senderVersion The version of the OAppSender.sol contract.
     * @return receiverVersion The version of the OAppReceiver.sol contract.
     */
    function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);

    /**
     * @notice Retrieves the LayerZero endpoint associated with the OApp.
     * @return iEndpoint The LayerZero endpoint as an interface.
     */
    function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);

    /**
     * @notice Retrieves the peer (OApp) associated with a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @return peer The peer address (OApp instance) associated with the corresponding endpoint.
     */
    function peers(uint32 _eid) external view returns (bytes32 peer);

    /**
     * @notice Sets the peer address (OApp instance) for a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @param _peer The address of the peer to be associated with the corresponding endpoint.
     */
    function setPeer(uint32 _eid, bytes32 _peer) external;

    /**
     * @notice Sets the delegate address for the OApp Core.
     * @param _delegate The address of the delegate to be set.
     */
    function setDelegate(address _delegate) external;
}

File 41 of 54 : NoncesUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @dev Provides tracking nonces for addresses. Nonces will only increment.
 */
abstract contract NoncesUpgradeable is Initializable {
    /**
     * @dev The nonce used for an `account` is not the expected current nonce.
     */
    error InvalidAccountNonce(address account, uint256 currentNonce);

    /// @custom:storage-location erc7201:openzeppelin.storage.Nonces
    struct NoncesStorage {
        mapping(address account => uint256) _nonces;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Nonces")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant NoncesStorageLocation = 0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00;

    function _getNoncesStorage() private pure returns (NoncesStorage storage $) {
        assembly {
            $.slot := NoncesStorageLocation
        }
    }

    function __Nonces_init() internal onlyInitializing {
    }

    function __Nonces_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev Returns the next unused nonce for an address.
     */
    function nonces(address owner) public view virtual returns (uint256) {
        NoncesStorage storage $ = _getNoncesStorage();
        return $._nonces[owner];
    }

    /**
     * @dev Consumes a nonce.
     *
     * Returns the current value and increments nonce.
     */
    function _useNonce(address owner) internal virtual returns (uint256) {
        NoncesStorage storage $ = _getNoncesStorage();
        // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be
        // decremented or reset. This guarantees that the nonce never overflows.
        unchecked {
            // It is important to do x++ and not ++x here.
            return $._nonces[owner]++;
        }
    }

    /**
     * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.
     */
    function _useCheckedNonce(address owner, uint256 nonce) internal virtual {
        uint256 current = _useNonce(owner);
        if (nonce != current) {
            revert InvalidAccountNonce(owner, current);
        }
    }
}

File 42 of 54 : ERC20Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol";
import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
    /// @custom:storage-location erc7201:openzeppelin.storage.ERC20
    struct ERC20Storage {
        mapping(address account => uint256) _balances;

        mapping(address account => mapping(address spender => uint256)) _allowances;

        uint256 _totalSupply;

        string _name;
        string _symbol;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;

    function _getERC20Storage() private pure returns (ERC20Storage storage $) {
        assembly {
            $.slot := ERC20StorageLocation
        }
    }

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
        __ERC20_init_unchained(name_, symbol_);
    }

    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
        ERC20Storage storage $ = _getERC20Storage();
        $._name = name_;
        $._symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        ERC20Storage storage $ = _getERC20Storage();
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            $._totalSupply += value;
        } else {
            uint256 fromBalance = $._balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                $._balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                $._totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                $._balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        ERC20Storage storage $ = _getERC20Storage();
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        $._allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

File 43 of 54 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * 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.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) 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 FailedInnerCall();
        }
    }
}

File 44 of 54 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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 value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` 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 value) external returns (bool);
}

File 45 of 54 : EIP712Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.20;

import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import {IERC5267} from "@openzeppelin/contracts/interfaces/IERC5267.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose
 * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract
 * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to
 * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
 * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the
 * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
 */
abstract contract EIP712Upgradeable is Initializable, IERC5267 {
    bytes32 private constant TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    /// @custom:storage-location erc7201:openzeppelin.storage.EIP712
    struct EIP712Storage {
        /// @custom:oz-renamed-from _HASHED_NAME
        bytes32 _hashedName;
        /// @custom:oz-renamed-from _HASHED_VERSION
        bytes32 _hashedVersion;

        string _name;
        string _version;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.EIP712")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;

    function _getEIP712Storage() private pure returns (EIP712Storage storage $) {
        assembly {
            $.slot := EIP712StorageLocation
        }
    }

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP-712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {
        __EIP712_init_unchained(name, version);
    }

    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {
        EIP712Storage storage $ = _getEIP712Storage();
        $._name = name;
        $._version = version;

        // Reset prior values in storage if upgrading
        $._hashedName = 0;
        $._hashedVersion = 0;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        return _buildDomainSeparator();
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev See {IERC-5267}.
     */
    function eip712Domain()
        public
        view
        virtual
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        EIP712Storage storage $ = _getEIP712Storage();
        // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized
        // and the EIP712 domain is not reliable, as it will be missing name and version.
        require($._hashedName == 0 && $._hashedVersion == 0, "EIP712: Uninitialized");

        return (
            hex"0f", // 01111
            _EIP712Name(),
            _EIP712Version(),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }

    /**
     * @dev The name parameter for the EIP712 domain.
     *
     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
     * are a concern.
     */
    function _EIP712Name() internal view virtual returns (string memory) {
        EIP712Storage storage $ = _getEIP712Storage();
        return $._name;
    }

    /**
     * @dev The version parameter for the EIP712 domain.
     *
     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
     * are a concern.
     */
    function _EIP712Version() internal view virtual returns (string memory) {
        EIP712Storage storage $ = _getEIP712Storage();
        return $._version;
    }

    /**
     * @dev The hash of the name parameter for the EIP712 domain.
     *
     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.
     */
    function _EIP712NameHash() internal view returns (bytes32) {
        EIP712Storage storage $ = _getEIP712Storage();
        string memory name = _EIP712Name();
        if (bytes(name).length > 0) {
            return keccak256(bytes(name));
        } else {
            // If the name is empty, the contract may have been upgraded without initializing the new storage.
            // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.
            bytes32 hashedName = $._hashedName;
            if (hashedName != 0) {
                return hashedName;
            } else {
                return keccak256("");
            }
        }
    }

    /**
     * @dev The hash of the version parameter for the EIP712 domain.
     *
     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.
     */
    function _EIP712VersionHash() internal view returns (bytes32) {
        EIP712Storage storage $ = _getEIP712Storage();
        string memory version = _EIP712Version();
        if (bytes(version).length > 0) {
            return keccak256(bytes(version));
        } else {
            // If the version is empty, the contract may have been upgraded without initializing the new storage.
            // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.
            bytes32 hashedVersion = $._hashedVersion;
            if (hashedVersion != 0) {
                return hashedVersion;
            } else {
                return keccak256("");
            }
        }
    }
}

File 46 of 54 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @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);
}

File 47 of 54 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.20;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS
    }

    /**
     * @dev The signature derives the `address(0)`.
     */
    error ECDSAInvalidSignature();

    /**
     * @dev The signature has an invalid length.
     */
    error ECDSAInvalidSignatureLength(uint256 length);

    /**
     * @dev The signature has an S value that is in the upper half order.
     */
    error ECDSAInvalidSignatureS(bytes32 s);

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
     * return address(0) without also returning an error description. Errors are documented using an enum (error type)
     * and a bytes32 providing additional information about the error.
     *
     * If no error is returned, then the address can be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
        unchecked {
            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
            // We do not check for an overflow here since the shift operation results in 0 or 1.
            uint8 v = uint8((uint256(vs) >> 255) + 27);
            return tryRecover(hash, v, r, s);
        }
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError, bytes32) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS, s);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature, bytes32(0));
        }

        return (signer, RecoverError.NoError, bytes32(0));
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
     */
    function _throwError(RecoverError error, bytes32 errorArg) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert ECDSAInvalidSignature();
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert ECDSAInvalidSignatureLength(uint256(errorArg));
        } else if (error == RecoverError.InvalidSignatureS) {
            revert ECDSAInvalidSignatureS(errorArg);
        }
    }
}

File 48 of 54 : MessageHashUtils.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)

pragma solidity ^0.8.20;

import {Strings} from "../Strings.sol";

/**
 * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
 *
 * The library provides methods for generating a hash of a message that conforms to the
 * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
 * specifications.
 */
library MessageHashUtils {
    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing a bytes32 `messageHash` with
     * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with
     * keccak256, although any bytes32 value can be safely used because the final digest will
     * be re-hashed.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash
            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix
            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)
        }
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing an arbitrary `message` with
     * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
        return
            keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x00` (data with intended validator).
     *
     * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended
     * `validator` address. Then hashing the result.
     *
     * See {ECDSA-recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(hex"19_00", validator, data));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).
     *
     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with
     * `\x19\x01` and hashing the result. It corresponds to the hash signed by the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.
     *
     * See {ECDSA-recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, hex"19_01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            digest := keccak256(ptr, 0x42)
        }
    }
}

File 49 of 54 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 50 of 54 : IERC5267.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.20;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

File 51 of 54 : draft-IERC6093.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

File 52 of 54 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;

import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant HEX_DIGITS = "0123456789abcdef";
    uint8 private constant ADDRESS_LENGTH = 20;

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toStringSigned(int256 value) internal pure returns (string memory) {
        return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        uint256 localValue = value;
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = HEX_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
     * representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 53 of 54 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 54 of 54 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": true,
    "mode": "3"
  },
  "outputSelection": {
    "*": {
      "*": [
        "abi"
      ]
    }
  },
  "detectMissingLibraries": false,
  "forceEVMLA": false,
  "enableEraVMExtensions": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"uint32","name":"_srcEid","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ERC2612ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC2612InvalidSigner","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InsufficientAmountOut","type":"error"},{"inputs":[],"name":"InsufficientAmountToSync","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidAmountIn","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidNonce","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"InvalidRate","type":"error"},{"inputs":[],"name":"InvalidReceiver","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[],"name":"MaxSyncAmountExceeded","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"UnauthorizedCaller","type":"error"},{"inputs":[],"name":"UnauthorizedToken","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"bridgeQuoter","type":"address"}],"name":"BridgeQuoterSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"address","name":"l1TokenIn","type":"address"}],"name":"L1TokenInSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"l2ExchangeRateProvider","type":"address"}],"name":"L2ExchangeRateProviderSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxSyncAmount","type":"uint256"}],"name":"MaxSyncAmountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"messenger","type":"address"}],"name":"MessengerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"minSyncAmount","type":"uint256"}],"name":"MinSyncAmountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rateLimiter","type":"address"}],"name":"RateLimiterSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":true,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"uint256","name":"assetsPerShare","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeShares","type":"uint256"}],"name":"Rebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"ReceiverSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"preRebaseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"postRebaseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sharesAmount","type":"uint256"}],"name":"SharesBurnt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"syncKeeper","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"SyncKeeperSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"sharesValue","type":"uint256"}],"name":"TransferShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"canPauseSet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"canPause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"composeMsgSender","outputs":[{"internalType":"address","name":"sender","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"bool","name":"floor","type":"bool"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"bool","name":"shouldWrap","type":"bool"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getL2ExchangeRateProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMessenger","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRateLimiter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"}],"name":"getTokenData","outputs":[{"components":[{"internalType":"uint256","name":"unsyncedAmountIn","type":"uint256"},{"internalType":"uint256","name":"unsyncedAmountOut","type":"uint256"},{"internalType":"uint256","name":"minSyncAmount","type":"uint256"},{"internalType":"uint256","name":"maxSyncAmount","type":"uint256"},{"internalType":"address","name":"l1Address","type":"address"}],"internalType":"struct L2SyncPool.Token","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_l2ExchangeRateProvider","type":"address"},{"internalType":"address","name":"_rateLimiter","type":"address"},{"internalType":"address","name":"_messenger","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_bridgeQuoter","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"syncKeeper","type":"address"}],"name":"isSyncKeeper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastAssetsPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_srcEid","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"includeUnsynced","type":"bool"}],"name":"pendingDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"quoteSync","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"quoteWithdraw","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bridgeQuoter","type":"address"}],"name":"setBridgeQuoter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setCanPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l2TokenIn","type":"address"},{"internalType":"address","name":"l1TokenIn","type":"address"}],"name":"setL1TokenIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l2ExchangeRateProvider","type":"address"}],"name":"setL2ExchangeRateProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"maxSyncAmount","type":"uint256"}],"name":"setMaxSyncAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"messenger","type":"address"}],"name":"setMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"minSyncAmount","type":"uint256"}],"name":"setMinSyncAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_srcEid","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint64","name":"_nonce","type":"uint64"}],"name":"setNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rateLimiter","type":"address"}],"name":"setRateLimiter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rebaseFee","type":"uint256"}],"name":"setRebaseFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"setReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_syncDepositFee","type":"uint256"}],"name":"setSyncDepositFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"syncKeeper","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setSyncKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wLST","type":"address"}],"name":"setWrappedLST","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"name":"sync","outputs":[{"internalType":"uint256","name":"unsyncedAmountIn","type":"uint256"},{"internalType":"uint256","name":"unsyncedAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"name":"sync","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"syncDepositFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"syncIndexPendingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"syncIndexes","outputs":[{"internalType":"uint256","name":"lastPendingSyncIndex","type":"uint256"},{"internalType":"uint256","name":"lastCompletedSyncIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"transferShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"transferSharesFrom","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

9c4d535b000000000000000000000000000000000000000000000000000000000000000001000b7dd690c72c7c839a760ef97505f037b722cbac3c96143a05c98d8f21c9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000400000000000000000000000005c6cff4b7c49805f8295ff73c204ac83f3bc4ae70000000000000000000000000000000000000000000000000000000000007595

Deployed Bytecode

0x000200000000000200120000000000020001000000010355000000600310027000000a400030019d00000a40033001970000000100200190000000310000c13d0000008002000039000a00000002001d000000400020043f000b00000003001d000000040030008c000000580000413d000000000201043b000000e00220027000000a4a0020009c0000005a0000213d00000a800020009c0000000b03000029000000740000213d00000a9b0020009c000000cc0000a13d00000a9c0020009c000001890000213d00000aa30020009c000005a90000a13d00000aa40020009c000008c10000613d00000aa50020009c00000aba0000613d00000aa60020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d28fd206a0000040f0000000c0100002928fd22d60000040f0000000001000019000028fe0001042e0000000002000416000000000002004b000000580000c13d00000000080300190000001f0230003900000a4102200197000000c002200039000000400020043f0000001f0430018f00000a4205300198000000c002500039000000430000613d000000c006000039000000000701034f000000007307043c0000000006360436000000000026004b0000003f0000c13d000000000004004b000000500000613d000000000151034f0000000303400210000000000402043300000000043401cf000000000434022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000141019f0000000000120435000000400080008c000000580000413d000000c00200043d00000a430020009c000000580000213d000000e00100043d00000a400010009c000000a10000a13d0000000001000019000028ff0001043000000a4b0020009c0000000b03000029000000850000213d00000a660020009c000001130000a13d00000a670020009c000001cf0000213d00000a6e0020009c000005b20000a13d00000a6f0020009c000008f10000613d00000a700020009c00000ac80000613d00000a710020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000ae001000041000000000101041a00000adf02000041000000000202041a000000800020043f000000a00010043f00000b3401000041000028fe0001042e00000a810020009c000001330000a13d00000a820020009c0000021a0000213d00000a890020009c000005bb0000a13d00000a8a0020009c000009110000613d00000a8b0020009c00000ad70000613d00000a8c0020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000b2001000041000008120000013d00000a4c0020009c0000014b0000a13d00000a4d0020009c000002590000213d00000a540020009c000005de0000a13d00000a550020009c000009240000613d00000a560020009c00000ae50000613d00000a570020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d28fd206a0000040f0000000c0100002928fd23d80000040f0000000001000019000028fe0001042e00000a4302200197000000800020043f000000a00010043f00000a4403000041000000000303041a00000a45003001980000158e0000c13d00000a460430019700000a460040009c000000c20000613d00000a46013001c700000a4402000041000000000012041b00000a4601000041000000400200043d000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000a480400004128fd28f30000040f0000000100200190000000580000613d000000a00100043d000000800200043d0000014000000443000001600020044300000020020000390000018000200443000001a00010044300000100002004430000000201000039000001200010044300000a4901000041000028fe0001042e00000aa90020009c000002730000a13d00000aaa0020009c0000056e0000a13d00000aab0020009c000008340000613d00000aac0020009c00000a370000613d00000aad0020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d0000012002000039000000400020043f000000800000043f000000a00000043f000000c00000043f000000e00000043f000001000000043f28fd1e380000040f000c00000001001d000000400100043d000b00000001001d28fd1dff0000040f0000000c06000029000000000106041a0000000b0700002900000000021704360000000103600039000000000303041a00000000003204350000000203600039000000000303041a000000400470003900000000003404350000000303600039000000000303041a0000006005700039000000000035043500000080037000390000000406600039000000000606041a00000a43066001970000000000630435000000400600043d000000000116043600000000020204330000000000210435000000000104043300000040026000390000000000120435000000000105043300000060026000390000000000120435000000000103043300000a43011001970000008002600039000000000012043500000a400060009c00000a4006008041000000400160021000000b49011001c7000028fe0001042e00000a740020009c000004860000a13d00000a750020009c0000057c0000a13d00000a760020009c0000084a0000613d00000a770020009c00000a950000613d00000a780020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000b0d01000041000000000201041a000000010420019000000001012002700000007f0310018f00000000010360190000001f0010008c00000000050000390000000105002039000000000552013f00000001005001900000070c0000c13d000000800010043f000000000004004b00000ba00000c13d00000b5f01200197000000a00010043f000000000003004b00000b800000013d00000a8f0020009c000004910000a13d00000a900020009c000005850000a13d00000a910020009c000008650000613d00000a920020009c00000aad0000613d00000a930020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d28fd1e5a0000040f000000000101041a28fd20040000040f00000b320000013d00000a5a0020009c000004a20000a13d00000a5b0020009c0000058e0000a13d00000a5c0020009c000008a60000613d00000a5d0020009c00000ab20000613d00000a5e0020009c000000580000c13d0000000b02000029000000e40020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002402100370000000000202043b000b00000002001d00000a430020009c000000580000213d0000006402100370000000000202043b000a00000002001d0000004402100370000000000202043b000900000002001d0000008401100370000000000101043b000800000001001d000000ff0010008c000000580000213d00000aed010000410000000000100443000000000100041400000a400010009c00000a4001008041000000c00110021000000aee011001c70000800b0200003928fd28f80000040f000000010020019000001da20000613d000000000101043b0000000a0010006c00000ce30000a13d000000400100043d00000afa02000041000000000021043500000004021000390000000a03000029000000000032043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff0001043000000a9d0020009c000005f60000a13d00000a9e0020009c000009650000613d00000a9f0020009c00000af40000613d00000aa00020009c000000580000c13d0000000b02000029000000440020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002401100370000000000201043b000000000002004b0000000001000039000000010100c039000b00000002001d000000000012004b000000580000c13d00000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b00000b570000c13d0000000c01000029000000000010043f00000b2901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a00000b5f022001970000000b03000029000000000232019f000000000021041b000000400100043d000000200210003900000000003204350000000c02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000010300003900000b440400004100000cab0000013d00000a680020009c000006300000a13d00000a690020009c0000096a0000613d00000a6a0020009c00000b160000613d00000a6b0020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a460020009c000000580000213d0000000c0200002900000023022000390000000b0020006c000000580000813d0000000c020000290000000402200039000000000221034f000000000202043b000900000002001d00000a460020009c000000580000213d000000090200002900000005032002100000000c020000290000002402200039000800000002001d000300000003001d00000000023200190000000b0020006c000000580000213d00000ae802000041000000000202041a00000a43032001970000000002000411000000000023004b00000b520000c13d000000090000006b00000d4a0000c13d00000020020000390000000a040000290000000002240436000000090300002900000000003204350000004002400039000000030b200029000000000003004b00000eab0000c13d0000000a0200002900000000012b004900000a400010009c00000a4001008041000000600110021000000a400020009c00000a40020080410000004002200210000000000121019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000121019f00000af2011001c70000800d02000039000000010300003900000b040400004100000cab0000013d00000a830020009c000006660000a13d00000a840020009c00000a1e0000613d00000a850020009c00000b1d0000613d00000a860020009c000000580000c13d0000000b02000029000000440020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002401100370000000000301043b00000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b00000b570000c13d000b00000003001d0000000c01000029000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b00000003011000390000000b03000029000000000031041b000000400100043d000000200210003900000000003204350000000c02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000010300003900000b3f0400004100000cab0000013d00000a4e0020009c000006840000a13d00000a4f0020009c00000a2b0000613d00000a500020009c00000b390000613d00000a510020009c000000580000c13d0000000b02000029000000640020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a400010009c000000580000213d28fd1ef90000040f00000024020000390000000102200367000000000202043b000000000021004b0000000001000039000000010100603900000b320000013d00000ab00020009c000005040000213d00000ab30020009c000005ad0000613d00000ab40020009c000000580000c13d0000000b02000029000000840020008c000000580000413d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002402100370000000000202043b00000a460020009c000000580000213d00000023032000390000000b0030006c000000580000813d0000000403200039000000000131034f000000000101043b000a00000001001d00000a460010009c000000580000213d0000002402200039000900000002001d0000000a012000290000000b0010006c000000580000213d000000000100041100000a4301100197000000000010043f00000b2901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000ff00100190000006630000613d0000000c01000029000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000402100039000000000202041a000b0a430020019c00000f4f0000613d000000000201041a000800000002001d000000000002004b000010dc0000613d0000000202100039000000000202041a000000080020006b000010dc0000413d0000000102100039000000000302041a000000000001041b000000000002041b000000400100043d0000002002100039000700000003001d00000000003204350000000802000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000020300003900000b2a040000410000000c0500002928fd28f30000040f0000000100200190000000580000613d000000400100043d00000b5b0010009c00000cbd0000813d0000006002100039000000400020043f000000200210003900000000000204350000000000010435000000400200043d00000ae20020009c00000cbd0000213d0000004003200039000000400030043f0000002003200039000000000003043500000000000204350000004001100039000000000021043500000ab601000041000000000201041a000000020020008c000012960000613d0000000202000039000000000021041b00000ab701000041000000000101041a000000ff00100190000010d90000c13d00000add0100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000c00000001001d000000400300043d00000080013000390000000702000029000000000021043500000060013000390000000802000029000000000021043500000040013000390000000b02000029000000000021043500000020013000390000000502000039000000000021043500000080010000390000000000130435000600000003001d00000b2c0030009c00000cbd0000213d0000000601000029000000a001100039000000400010043f0000000c0100002900000009020000290000000a0300002928fd1f0b0000040f000000400400043d00000ae20040009c00000cbd0000213d00000000030100190000004001400039000000400010043f00000044010000390000000101100367000000000101043b000000000114043600000000000104350000000c010000290000000602000029000000000500041128fd23e80000040f000c00000001001d00000adf01000041000000000201041a000000010020003a00000bb90000413d0000000102200039000a00000002001d000000000021041b0000000c010000290000000001010433000000000010043f00000b2d01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000a02000029000000000021041b000000000020043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000703000029000000000031041b00000ad501000041000000000201041a000000000032001a00000bb90000413d0000000702200029000000000021041b00000ad401000041000000000201041a000000070220006c00000bb90000413d000000000021041b00000b2e01000041000000400200043d000a00000002001d000000000012043500000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000201043b0000000a0100002900000a400010009c00000a40010080410000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abf011001c700000a430220019728fd28f80000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000a057000290000038f0000613d000000000801034f0000000a09000029000000008a08043c0000000009a90436000000000059004b0000038b0000c13d000000000006004b0000039c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000017290000613d0000001f01400039000000600210018f0000000a01200029000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f000000200030008c000000580000413d0000000a02000029000000000302043300000a400030009c000000580000213d0000000c020000290000000002020433000000a0041000390000000705000029000000000054043500000080041000390000000805000029000000000054043500000060041000390000000b0500002900000000005404350000004004100039000000000024043500000020021000390000000000320435000000a003000039000000000031043500000b2f0010009c00000cbd0000213d000000c003100039000b00000003001d000000400030043f000000e00410003900000b3003000041000c00000004001d0000000000340435000000e403100039000000200400003900000000004304350000010404100039000000000301043300000000003404350000012401100039000000000003004b000003da0000613d000000000400001900000000051400190000000006240019000000000606043300000000006504350000002004400039000000000034004b000003d30000413d000000000113001900000000000104350000001f0130003900000b600110019700000044021000390000000b030000290000000000230435000000830110003900000b60021001970000000001320019000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f00000b2201000041000000000101041a000900000001001d00000b2001000041000000000101041a00000acf02000041000000000020044300000a4301100197000a00000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000090100002900000a4301100197000000400400043d00000024024000390000004003000039000000000032043500000b31020000410000000000240435000000040240003900000000001204350000000b01000029000000000101043300000044024000390000000000120435000b00000004001d0000006402400039000000000001004b0000041c0000613d000000000300001900000000042300190000000c05300029000000000505043300000000005404350000002003300039000000000013004b000004150000413d0000001f0310003900000b600330019700000000012100190000000000010435000000640130003900000a400010009c00000a400100804100000060011002100000000b0200002900000a400020009c00000a40020080410000004002200210000000000121019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af2011001c7000080090200003900000008030000290000000a04000029000000000500001928fd28f30000040f0000000100200190000018210000613d0000000b0100002900000a460010009c00000cbd0000213d0000000b01000029000000400010043f00000b3201000041000000000101041a000c00000001001d00000ad601000041000000000101041a00000acf02000041000000000020044300000a4301100197000b00000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400300043d00000044013000390000000c020000290000000000210435000000240130003900000aba02000041000000000021043500000ad7010000410000000001130436000900000001001d000000000100041000000a4301100197000000040230003900000000001204350000006401300039000000000001043500000a400030009c000a00000003001d00000a400100004100000000010340190006004000100218000000000100041400000a400010009c00000a4001008041000000c00110021000000006011001af00000ad8011001c70000000b0200002928fd28f30000040f0000000100200190000018f80000613d0000000a0100002900000a460010009c00000cbd0000213d0000000a01000029000000400010043f00000b3201000041000000000201041a0000000c0220006c00000bb90000413d000000000021041b000000010100003900000ab602000041000000000012041b00000007010000290000000902000029000000000012043500000008010000290000000a020000290000000000120435000000060100002900000b33011001c7000028fe0001042e00000a7b0020009c000005210000213d00000a7e0020009c000006cb0000613d00000a7f0020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000b3e0100004100000ab60000013d00000a960020009c000005570000213d00000a990020009c000006d70000613d00000a9a0020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000ab701000041000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f00000afb01000041000028fe0001042e00000a610020009c000005600000213d00000a640020009c000006f40000613d00000a650020009c000000580000c13d0000000b02000029000000640020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b00000a400020009c000000580000213d0000002403100370000000000303043b000c00000003001d0000ffff0030008c000000580000213d0000004403100370000000000403043b00000a460040009c000000580000213d00000023034000390000000b0030006c000000580000813d000900040040003d0000000901100360000000000101043b000a00000001001d00000a460010009c000000580000213d0000002403400039000800000003001d0000000a03300029000700000003001d0000000b0030006c000000580000213d000000000020043f00000aff01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000c02000029000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a000000010320019000000001042002700000007f0440618f000c00000004001d0000001f0040008c00000000040000390000000104002039000000000442013f00000001004001900000070c0000c13d000000400400043d000b00000004001d0000000c050000290000000004540436000600000004001d000000000003004b000011500000613d000000000010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000a47011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d0000000c0000006b000011b80000c13d0000000001000019000011c30000013d00000ab10020009c000006ff0000613d00000ab20020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d00000ae802000041000000000202041a00000a43032001970000000002000411000000000023004b00000b520000c13d000000000001004b000008bd0000613d00000ac502000041000000000302041a00000afc03300197000000000113019f000000000012041b0000000001000019000028fe0001042e00000a7c0020009c000007120000613d00000a7d0020009c000000580000c13d0000000001000416000000000001004b000000580000c13d000000000100041100000a4301100197000000000010043f00000b3c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000ff00100190000005400000c13d00000ae801000041000000000101041a0000000002000411000000000121013f00000a4300100198000019200000c13d00000ab701000041000000000201041a000000ff00200190000010d90000c13d00000b5f0220019700000001022001bf000000000021041b000000400100043d0000000002000411000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b3d0400004100000cab0000013d00000a970020009c000007170000613d00000a980020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000b1c01000041000008120000013d00000a620020009c000007250000613d00000a630020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b28fd20a20000040f00000b320000013d00000aae0020009c000007340000613d00000aaf0020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b28fd207b0000040f00000b320000013d00000a790020009c000007430000613d00000a7a0020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000ae801000041000008120000013d00000a940020009c000007630000613d00000a950020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000b410100004100000ab60000013d00000a5f0020009c000007810000613d00000a600020009c000000580000c13d0000000b02000029000000440020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b0000002401100370000000000401043b000000000004004b0000000001000039000000010100c039000000000014004b000000580000c13d00000ad201000041000000000101041a000000000001004b000000000300001900000b830000c13d000000800030043f00000afb01000041000028fe0001042e00000aa70020009c000007cd0000613d00000aa80020009c000000580000c13d0000000001000416000000000001004b000000580000c13d28fd20540000040f00000b320000013d00000a720020009c000007d50000613d00000a730020009c000000580000c13d0000000001000416000000000001004b000000580000c13d00000ad601000041000008120000013d00000a8d0020009c000007da0000613d00000a8e0020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d00000ae802000041000000000202041a00000a43032001970000000002000411000000000023004b00000b520000c13d00000b2202000041000000000302041a00000afc03300197000000000313019f000000000032041b000000800010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000b43011001c70000800d02000039000000010300003900000b230400004100000cab0000013d00000a580020009c000007ef0000613d00000a590020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000ae802000041000000000202041a00000a43032001970000000002000411000000000023004b00000b520000c13d00000aeb0010009c000009200000213d00000aec02000041000000000012041b0000000001000019000028fe0001042e00000aa10020009c000008070000613d00000aa20020009c000000580000c13d0000000b02000029000000440020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a400020009c000000580000213d0000002401100370000000000301043b00000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b00000b570000c13d000b00000003001d0000000c01000029000000000010043f00000b4701000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000b03000029000000000031041b000000400100043d000000200210003900000000003204350000000c02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000010300003900000b480400004100000cab0000013d00000a6c0020009c0000080e0000613d00000a6d0020009c000000580000c13d0000000b02000029000000a40020008c000000580000413d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002402100370000000000202043b000a00000002001d0000004402100370000000000202043b00000a460020009c000000580000213d00000023032000390000000b0030006c000000580000813d0000000403200039000000000131034f000000000101043b000900000001001d00000a460010009c000000580000213d0000002402200039000800000002001d00000009012000290000000b0010006c000000580000213d000000000100041100000a4301100197000000000010043f00000b2901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000ff0010019000000f3d0000c13d000000400100043d00000b5e02000041000015900000013d00000a870020009c000008170000613d00000a880020009c000000580000c13d0000000b02000029000000240020008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000201043b000000000002004b0000000001000039000000010100c039000000000012004b000000580000c13d00000ad501000041000000000101041a000000000002004b00000000020000190000067e0000613d00000ad402000041000000000202041a000000000012001a00000bb90000413d0000000001120019000000800010043f00000afb01000041000028fe0001042e00000a520020009c000008250000613d00000a530020009c000000580000c13d0000000b02000029000000840020008c000000580000413d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002402100370000000000202043b000a00000002001d00000a430020009c000000580000213d0000004402100370000000000202043b000900000002001d0000006402100370000000000202043b00000a460020009c000000580000213d00000023032000390000000b0030006c000000580000813d0000000403200039000000000131034f000000000101043b000800000001001d00000a460010009c000000580000213d0000002402200039000700000002001d00000008012000290000000b0010006c000000580000213d00000ab601000041000000000201041a000000020020008c00000b4e0000613d0000000202000039000000000021041b00000ab701000041000000000101041a000000ff0010019000000c6e0000c13d0000000c0000006b000008bd0000613d00000acf0100004100000000001004430000000c010000290000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b0000117b0000c13d000000090000006b0000120f0000c13d000000400100043d00000ae602000041000015900000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d000000000010043f00000aef01000041000008200000013d000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b00000a400020009c000000580000213d0000002401100370000000000101043b000c00000001001d0000ffff0010008c000000580000213d000000000020043f00000aff01000041000000200010043f0000004002000039000000000100001928fd28c00000040f0000000c02000029000000000020043f000000200010043f0000000001000019000000400200003928fd28c00000040f000000800200003928fd1e7c0000040f00000bca0000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a400010009c000000580000213d28fd1ef90000040f00000b320000013d0000000001000416000000000001004b000000580000c13d00000b0901000041000000000201041a000000010320019000000001012002700000007f0110618f0000001f0010008c00000000040000390000000104002039000000000043004b00000b660000613d00000b5501000041000000000010043f0000002201000039000000040010043f00000ac801000041000028ff000104300000000001000416000000000001004b000000580000c13d00000ad30100004100000ab60000013d0000000001000416000000000001004b000000580000c13d0000000001000412001000000001001d000f00000000003d000080050100003900000044030000390000000004000415000000100440008a000000050440021000000add0200004128fd28d50000040f000008130000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d28fd206a0000040f0000000c0100002928fd239c0000040f0000000001000019000028fe0001042e000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b00000a430020009c000000580000213d0000002401100370000000000301043b000000000100041128fd262e0000040f000000010100003900000b320000013d0000000001000416000000000001004b000000580000c13d00000b1a01000041000000000101041a000000000001004b00000b5c0000c13d00000b1b01000041000000000101041a000000000001004b00000b5c0000c13d00000b1201000041000000000201041a000000010320019000000001012002700000007f0110618f0000001f0010008c00000000040000390000000104002039000000000442013f00000001004001900000070c0000c13d000000800010043f000000000003004b00000c720000613d00000b1202000041000000000020043f000000000001004b00000cb00000c13d0000002002000039000000a00100003900000cc40000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d00000ae802000041000000000202041a00000a43032001970000000002000411000000000023004b00000b520000c13d00000b2002000041000000000302041a00000afc03300197000000000313019f000000000032041b000000800010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000b43011001c70000800d02000039000000010300003900000b210400004100000cab0000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d00000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b00000b570000c13d00000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000101043b00000acf02000041000000000020044300000a4301100197000b00000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400300043d00000afe01000041000000000013043500000004013000390000000c02000029000000000021043500000a400030009c000c00000003001d00000a400100004100000000010340190000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ac8011001c70000000b0200002928fd28f30000040f000000010020019000000f210000613d0000000c0100002900000a460010009c00000cbd0000213d0000000c01000029000000400010043f0000000001000019000028fe0001042e0000000001000416000000000001004b000000580000c13d0000000101000039000000800010043f000000a00010043f00000b3401000041000028fe0001042e0000000001000416000000000001004b000000580000c13d00000b2201000041000008120000013d0000000001000416000000000001004b000000580000c13d00000ae801000041000000000201041a00000a43032001970000000005000411000000000053004b00000b780000c13d00000afc02200197000000000021041b000000000100041400000a400010009c00000a4001008041000000c00110021000000af2011001c70000800d02000039000000030300003900000b0804000041000000000600001900000cab0000013d000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b00000a430020009c000000580000213d0000002401100370000000000101043b000c00000001001d00000a430010009c000000580000213d000000000102001928fd1e6b0000040f0000000c02000029000000000020043f000000200010043f0000004002000039000000000100001928fd28c00000040f000000000101041a00000b320000013d0000000001000416000000000001004b000000580000c13d0000001201000039000000800010043f00000afb01000041000028fe0001042e0000000001000416000000000001004b000000580000c13d00000ac001000041000000000101041a00000a4301100197000000800010043f00000afb01000041000028fe0001042e000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000000000010043f00000ae101000041000000200010043f0000004002000039000000000100001928fd28c00000040f00000ab60000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d28fd206a0000040f0000000c0100002928fd20340000040f0000000001000019000028fe0001042e000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d28fd1ddc0000040f000b00000001001d28fd206a0000040f0000000c0100002928fd1e490000040f000000000301041a00000b5f023001970000000b0000006b000000010220c1bf000000000021041b0000000001000019000028fe0001042e000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000302043b00000a430030009c000000580000213d00000000020300190000002401100370000000000301043b000c00000003001d0000000001000411000b00000002001d28fd23150000040f0000000c0100002928fd20040000040f0000000003010019000a00000001001d00000000010004110000000b020000290000000c0400002928fd236d0000040f000000400100043d0000000a02000029000008a00000013d000000640030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b00000a430020009c000000580000213d00000000040200190000002402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000004401100370000000000501043b00000ad201000041000000000101041a000000000001004b00000000030000190000088f0000613d00000ad302000041000000000202041a00000ad403000041000000000303041a000000000023001a00000bb90000413d000000000223001900000ad503000041000000000303041a000000000023001a00000bb90000413d000000000223001a0000088b0000613d00000b6103200129000000000053004b000000580000413d00000000025200a900000000131200d9000000000001004b000000010330c039000a00000005001d00000000020004110000000001040019000900000004001d000b00000003001d28fd21c40000040f00000009010000290000000c020000290000000a0300002928fd23150000040f00000009010000290000000c020000290000000b030000290000000a0400002928fd236d0000040f000000400100043d0000000b02000029000000000021043500000a400010009c00000a4001008041000000400110021000000ab5011001c7000028fe0001042e000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002401100370000000000101043b000b00000001001d00000a430010009c000000580000213d00000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b00000b570000c13d0000000b0000006b00000c860000c13d00000ae501000041000000800010043f00000ace01000041000028ff00010430000000640030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000004401100370000000000101043b00000a460010009c000000580000213d00000004011000390000000b0200002928fd1db00000040f000a00000001001d000900000002001d000000400100043d000b00000001001d28fd1e0a0000040f0000000b0200002900000020012000390000000000010435000000000002043500000024010000390000000101100367000000000201043b000000400100043d000b00000001001d00000020011000390000000c0300002928fd1eb50000040f0000000b030000290000000002310049000000200120008a0000000000130435000000000103001928fd1e150000040f0000000001000412001200000001001d001100200000003d000080050100003900000044030000390000000004000415000000120440008a000009550000013d000000640030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a400020009c000000580000213d0000004401100370000000000101043b000b00000001001d00000a460010009c000000580000213d28fd206a0000040f0000000c0100002928fd1ebe0000040f00000024020000390000000102200367000000000202043b000000000020043f000000200010043f0000004002000039000000000100001928fd28c00000040f000000000201041a00000b05022001970000000b022001af000000000021041b0000000001000019000028fe0001042e000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000ae802000041000000000202041a00000a43032001970000000002000411000000000023004b00000b520000c13d00000b400010009c00000b9c0000413d00000b4201000041000000800010043f00000ace01000041000028ff00010430000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002401100370000000000101043b00000a460010009c000000580000213d00000004011000390000000b0200002928fd1db00000040f000a00000001001d000900000002001d000000400100043d000b00000001001d28fd1e0a0000040f0000000b020000290000002001200039000000000001043500000000000204350000000c0100002928fd1e380000040f000000000301041a0000000101100039000000000401041a000000400100043d000b00000001001d00000020011000390000000c0200002928fd20290000040f0000000b030000290000000002310049000000200120008a0000000000130435000000000103001928fd1e150000040f0000000001000412000e00000001001d000d00200000003d0000800501000039000000440300003900000000040004150000000e0440008a000000050440021000000add0200004128fd28d50000040f000c00000001001d0000000a02000029000000090300002928fd1f0b0000040f00000000030100190000000c010000290000000b0200002928fd20c70000040f0000000002010019000000400100043d000c00000001001d28fd1de70000040f00000bd30000013d0000000001000416000000000001004b000000580000c13d28fd26740000040f00000b320000013d000001440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002402100370000000000202043b000a00000002001d00000a430020009c000000580000213d0000004402100370000000000202043b00000a430020009c000000580000213d0000006402100370000000000202043b00000a430020009c000000580000213d0000008402100370000000000202043b00000a430020009c000000580000213d000000a402100370000000000202043b000900000002001d00000a430020009c000000580000213d000000c402100370000000000202043b000800000002001d00000a430020009c000000580000213d000000e402100370000000000202043b00000a430020009c000000580000213d0000010402100370000000000402043b00000a460040009c000000580000213d00000023024000390000000b0020006c000000580000813d0000000405400039000000000251034f000000000202043b00000a460020009c00000cbd0000213d0000001f0320003900000b60033001970000003f0330003900000b600330019700000adc0030009c00000cbd0000213d00000024044000390000008003300039000000400030043f000000800020043f00000000034200190000000b0030006c000000580000213d0000002003500039000000000531034f00000b60062001980000001f0720018f000000a004600039000009b80000613d000000a008000039000000000905034f000000009309043c0000000008380436000000000048004b000009b40000c13d000000000007004b000009c50000613d000000000365034f0000000305700210000000000604043300000000065601cf000000000656022f000000000303043b0000010005500089000000000353022f00000000035301cf000000000363019f0000000000340435000000a00220003900000000000204350000012402100370000000000402043b00000a460040009c000000580000213d00000023024000390000000b0020006c000000580000813d0000000405400039000000000251034f000000000202043b00000a460020009c00000cbd0000213d0000001f0320003900000b60033001970000003f0330003900000b6003300197000000400700043d0000000006370019000700000007001d000000000076004b0000000003000039000000010300403900000a460060009c00000cbd0000213d000000010030019000000cbd0000c13d0000002403400039000000400060043f00000007040000290000000004240436000600000004001d00000000033200190000000b0030006c000000580000213d0000002003500039000000000331034f00000b60042001980000001f0520018f0000000601400029000009f50000613d000000000603034f0000000607000029000000006806043c0000000007870436000000000017004b000009f10000c13d000000000005004b00000a020000613d000000000343034f0000000304500210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003104350000000601200029000000000001043500000a4401000041000000000101041a000b00000001001d00000a46011001980000157c0000613d000000010010008c0000158e0000c13d00000acf01000041000000000010044300000000010004100000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b0000158e0000c13d0000000b0100002900050a450010019b000015800000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d28fd1e270000040f000000000101041a000000ff0010019000000ae20000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d28fd1e5a0000040f000000000101041a00000b320000013d000000e40030008c000000580000413d0000008402100370000000000202043b000c00000002001d00000a460020009c000000580000213d0000000c0200002900000023022000390000000b0020006c000000580000813d0000000c02000029000900040020003d0000000902100360000000000202043b000a00000002001d00000a460020009c000000580000213d0000000c020000290000002403200039000800000003001d0000000a02300029000700000002001d0000000b0020006c000000580000213d000000a402100370000000000202043b00000a430020009c000000580000213d000000c402100370000000000202043b00000a460020009c000000580000213d00000023032000390000000b0030006c000000580000813d0000000403200039000000000131034f000000000101043b00000a460010009c000000580000213d000000000112001900000024011000390000000b0010006c000000580000213d00000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d0000000002000411000000000101043b00000a4301100197000000000021004b000011570000c13d00000004010000390000000101100367000000000101043b000b00000001001d00000a400010009c000000580000213d0000000b01000029000000000010043f00000b4701000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000600000001001d000000000001004b0000128d0000c13d000000400100043d00000b5a02000041000000000021043500000004021000390000000b03000029000001830000013d000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002401100370000000000301043b00000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b00000b570000c13d000000000003004b00000c4a0000c13d00000ae601000041000000800010043f00000ace01000041000028ff000104300000000001000416000000000001004b000000580000c13d00000aec0100004100000ab60000013d0000000001000416000000000001004b000000580000c13d00000ad201000041000000000101041a000000800010043f00000afb01000041000028fe0001042e0000000001000416000000000001004b000000580000c13d0000000b0100002928fd1ded0000040f000b00000001001d000c00000002001d000a00000003001d000000000200041128fd21c40000040f0000000b010000290000000c020000290000000a0300002900000ad40000013d000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000402100370000000000202043b00000a430020009c000000580000213d0000002401100370000000000301043b000000000100041128fd222c0000040f000000010100003900000b320000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a430010009c000000580000213d28fd22f80000040f000000000001004b0000000001000039000000010100c03900000b320000013d000000240030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b000c00000001001d00000a430010009c000000580000213d28fd206a0000040f0000000c0100002928fd23b60000040f0000000001000019000028fe0001042e0000000001000416000000000001004b000000580000c13d000000000100041100000a4301100197000000000010043f00000b3c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000ff0010019000000b0f0000c13d00000ae801000041000000000101041a0000000002000411000000000121013f00000a4300100198000019200000c13d000000400100043d00000ab702000041000000000302041a000000ff0030019000000ba60000c13d00000b4602000041000015900000013d0000000001000416000000000001004b000000580000c13d0000000001000410000000800010043f00000afb01000041000028fe0001042e000000440030008c000000580000413d0000000002000416000000000002004b000000580000c13d0000000401100370000000000101043b00000a400010009c000000580000213d28fd1ebe0000040f00000024020000390000000102200367000000000202043b000000000020043f000000200010043f0000004002000039000000000100001928fd28c00000040f000000000101041a00000a460110019728fd1ecf0000040f000000400200043d000000000012043500000a400020009c00000a4002008041000000400120021000000ab5011001c7000028fe0001042e000000840030008c000000580000413d0000000402100370000000000202043b000c00000002001d00000a430020009c000000580000213d0000002402100370000000000202043b000b00000002001d0000006401100370000000000101043b000000000001004b0000000002000039000000010200c039000000000021004b000000580000c13d00000ab601000041000000000201041a000000020020008c00000bdd0000c13d00000ae701000041000000800010043f00000ace01000041000028ff0001043000000ae901000041000000800010043f000000840020043f00000aea01000041000028ff0001043000000ae902000041000000800020043f000000840010043f00000aea01000041000028ff0001043000000b3601000041000000800010043f0000002001000039000000840010043f0000001501000039000000a40010043f00000b3701000041000000c40010043f00000b3801000041000028ff00010430000000800010043f000000000003004b00000b7d0000613d00000b0902000041000000000020043f000000000001004b00000ba40000613d00000b0b0200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000014004b00000b6f0000413d00000bc90000013d00000ae901000041000000800010043f000000840050043f00000aea01000041000028ff0001043000000b5f02200197000000a00020043f000000000001004b000000c001000039000000a00100603900000bca0000013d00000ad303000041000000000503041a00000ad403000041000000000303041a0000000003530019000000000004004b00000bb70000c13d000000000053004b00000bb90000413d00000ad504000041000000000404041a000000000034001a00000bb90000413d000000000334001a00000b950000613d00000b6104300129000000000024004b000000580000413d00000000022300a900000000131200d9000000000001004b000000010330c039000000800030043f00000afb01000041000028fe0001042e00000b4102000041000000000012041b0000000001000019000028fe0001042e00000b0d03000041000000000030043f000000020020008c00000bbf0000813d000000a00100003900000bca0000013d00000b5f03300197000000000032041b0000000002000411000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b450400004100000cab0000013d000000000053004b00000c780000813d00000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff0001043000000b0f0200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000014004b00000bc10000413d000000c001300039000000800210008a000000800100003928fd1e150000040f0000002001000039000000400200043d000c00000002001d0000000002120436000000800100003928fd1dca0000040f0000000c02000029000000000121004900000a400010009c00000a4001008041000000600110021000000a400020009c00000a40020080410000004002200210000000000121019f000028fe0001042e0000000202000039000000000021041b00000ab701000041000000000101041a000000ff0010019000000c6e0000c13d0000000b0000006b00000aa90000613d0000000c01000029000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000900000001001d0000000401100039000000000101041a00000a430010019800000f4f0000613d000000400100043d000a00000001001d0000000c0100002900000aba0010009c000010df0000c13d0000000b0200002900000ac001000041000000000301041a0000000a04000029000a00000004001d0000002401400039000000000021043500000ac101000041000000000014043500000004014000390000000c02000029000000000021043500000a400040009c00000a400100004100000000010440190000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000abd011001c700000a430230019728fd28f80000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000a0570002900000c240000613d000000000801034f0000000a09000029000000008a08043c0000000009a90436000000000059004b00000c200000c13d000000000006004b00000c310000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000011440000613d0000001f01400039000000600210018f0000000a01200029000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f000000200030008c000000580000413d0000000a02000029000000000302043300000044020000390000000102200367000000000202043b000a00000003001d000000000023004b000012720000813d00000acc02000041000015900000013d000b00000003001d0000000c01000029000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b00000002011000390000000b03000029000000000031041b000000400100043d000000200210003900000000003204350000000c02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000010300003900000b350400004100000cab0000013d00000acd01000041000000800010043f00000ace01000041000028ff0001043000000b5f02200197000000a00020043f000000000001004b0000002002000039000000000200603900000cb90000013d00000ad504000041000000000404041a000000000034001a00000bb90000413d000000000334001a00000c810000613d00000b6104300129000000000024004b000000580000413d00000000022300a900000000031200d9000000800030043f00000afb01000041000028fe0001042e0000000c01000029000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000401100039000000000201041a00000afc022001970000000b03000029000000000232019f000000000021041b000000400100043d000000200210003900000000003204350000000c02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000010300003900000afd0400004128fd28f30000040f0000000100200190000000580000613d0000000001000019000028fe0001042e00000b14030000410000000002000019000000000403041a000000a005200039000000000045043500000001033000390000002002200039000000000012004b00000cb20000413d0000003f0120003900000b600210019700000adc0020009c00000cc30000a13d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff000104300000008001200039000000400010043f00000b1603000041000000000403041a000000010540019000000001034002700000007f0330618f0000001f0030008c00000000060000390000000106002039000000000664013f00000001006001900000070c0000c13d0000000000310435000000a002200039000000000005004b00000e390000613d00000b1604000041000000000040043f000000000003004b000000000400001900000e3e0000613d00000b180500004100000000040000190000000006240019000000000705041a000000000076043500000001055000390000002004400039000000000034004b00000cdb0000413d00000e3e0000013d0000000c01000029000000000010043f00000aef01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a0000000103200039000000000031041b000000400100043d000000c0031000390000000a040000290000000000430435000000a003100039000000000023043500000080021000390000000903000029000000000032043500000060021000390000000b03000029000000000032043500000040021000390000000c030000290000000000320435000000c002000039000000000221043600000af003000041000000000032043500000af10010009c00000cbd0000213d000000e003100039000000400030043f00000a400020009c00000a40020080410000004002200210000000000101043300000a400010009c00000a40010080410000006001100210000000000121019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af2011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000a00000001001d28fd26740000040f00000af302000041000000400300043d00000000002304350000000202300039000000000012043500000022013000390000000a0200002900000000002104350000000101000367000000c402100370000000000202043b000a00000002001d000000a401100370000000000101043b000700000001001d00000a400030009c00000a40030080410000004001300210000000000200041400000a400020009c00000a4002008041000000c002200210000000000121019f00000af4011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000400200043d0000000a0300002900000af50030009c0000117e0000a13d00000af901000041000000000012043500000004012000390000000a03000029000000000031043500000a400020009c00000a4002008041000000400120021000000ac8011001c7000028ff000104300000000c02000029000500440020003d0000000007000019000000080600002900000d5e0000013d000000030140021000000b610110027f00000b610210016700000001010003670000000b03100360000000000303043b000000000223016f0000000103400210000000000232019f0000000806000029000000070700002900000000002a041b0000000107700039000000090070006c000011400000813d000700000007001d00000005027002100000000009620019000000000291034f000000000202043b00000000030000310000000c0430006a000000830440008a00000b030540019700000b0306200197000000000756013f000000000056004b000000000500001900000b0305004041000000000042004b000000000400001900000b030400804100000b030070009c000000000504c019000000000005004b000000580000c13d00000008022000290000004004200039000000000441034f000000000404043b00000000052300490000001f0550008a00000b030650019700000b0307400197000000000867013f000000000067004b000000000600001900000b0306004041000000000054004b000000000500001900000b030500804100000b030080009c000000000605c019000000000006004b000000580000c13d0000000004240019000000000541034f000000000705043b00000a460070009c000000580000213d000000020070008c000000580000413d00000000037300490000002005400039000000000035004b000000000400001900000b030400204100000b0303300197000b00000005001d00000b0305500197000000000635013f000000000035004b000000000300001900000b030300404100000b030060009c000000000304c019000000000003004b000000580000c13d0000000b03100360000000000303043b00000b010330019700000b020030009c0000112b0000c13d000000000121034f000000000101043b00000a400010009c000000580000213d000000000010043f00000aff01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c70000801002000039000a00000007001d000600000009001d28fd28f80000040f00000006030000290000000100200190000000580000613d0000000102000367000000000332034f000000000303043b0000000c040000290000000004400079000000830440008a00000b030530019700000b0306400197000000000765013f000000000065004b000000000500001900000b0305004041000000000043004b000000000400001900000b030400804100000b030070009c000000000504c019000000000101043b000000000005004b000000580000c13d0000000503300029000000000232034f000000000202043b0000ffff0020008c000000580000213d000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000a040000290000000100200190000000580000613d000000000a01043b00000000010a041a000000010010019000000001031002700000007f0330618f0000001f0030008c00000000020000390000000102002039000000000121013f00000001001001900000070c0000c13d000000200030008c00060000000a001d00000e050000413d000400000003001d0000000000a0043f000000000100041400000a400010009c00000a4001008041000000c00110021000000a47011001c7000080100200003928fd28f80000040f0000000a040000290000000100200190000000580000613d0000001f024000390000000502200270000000200040008c0000000002004019000000000301043b00000004010000290000001f01100039000000050110027000000000011300190000000002230019000000000012004b000000060a00002900000e050000813d000000000002041b0000000102200039000000000012004b00000e010000413d0000001f0040008c00000d4f0000a13d0000000000a0043f000000000100041400000a400010009c00000a4001008041000000c00110021000000a47011001c7000080100200003928fd28f80000040f0000000a080000290000000100200190000000580000613d000000000301034f00000b60048001980000000101000367000000000203043b000000000300001900000e320000613d000000080600002900000007070000290000000b09000029000000060a0000290000000005930019000000000551034f000000000505043b000000000052041b00000001022000390000002003300039000000000043004b00000e1c0000413d000000000084004b00000e2f0000813d0000000304800210000000f80440018f00000b610440027f00000b61044001670000000003930019000000000331034f000000000303043b000000000343016f000000000032041b000000010280021000000001022001bf00000d5a0000013d000000080600002900000007070000290000000b09000029000000060a000029000000000084004b00000e260000413d00000e2f0000013d00000b5f044001970000000000420435000000000003004b00000020040000390000000004006039000000000312004900000000034300190000001f0330003900000b60033001970000000004130019000000000034004b00000000030000390000000103004039000c00000004001d00000a460040009c00000cbd0000213d000000010030019000000cbd0000c13d0000000c03000029000000400030043f00000b390030009c00000cbd0000213d0000000c040000290000002003400039000800000003001d000000400030043f0000000000040435000000400500043d0000002003500039000000e004000039000000000043043500000b3a030000410000000000350435000000e004500039000000800300043d0000000000340435000b00000005001d0000010004500039000000000003004b00000e690000613d00000000050000190000000006450019000000a007500039000000000707043300000000007604350000002005500039000000000035004b00000e620000413d000000000543001900000000000504350000001f0330003900000b600330019700000000034300190000000b0500002900000000045300490000004005500039000000000045043500000000060104330000000005630436000000000006004b00000e7e0000613d000000000100001900000000035100190000000004120019000000000404043300000000004304350000002001100039000000000061004b00000e770000413d000a00000005001d000900000006001d0000000001560019000000000001043500000b3b010000410000000000100443000000000100041400000a400010009c00000a4001008041000000c00110021000000aee011001c70000800b0200003928fd28f80000040f000000010020019000001da20000613d000000000101043b0000000b040000290000008002400039000000000300041000000000003204350000006002400039000000000012043500000009010000290000001f0110003900000b60011001970000000a011000290000000002410049000000c0034000390000000000230435000000a00240003900000000000204350000000c0200002900000000020204330000000001210436000000000002004b00000ea90000613d00000000030000190000000805000029000000005405043400000000014104360000000103300039000000000023004b00000ea40000413d0000000b0200002900000bd40000013d0000000b040000290000000c0340006a000000830330008a0007004300400092000000000603001900000b0307300197000000000a000019000000080400002900000ebd0000013d0000001f03c0003900000b600330019700000000048c00190000000000040435000000000b8300190000002004500039000000010aa000390000000900a0006c000002070000813d0000000a03b0006a000000400330008a0000000002320436000000000341034f000000000c03043b00000b0303c00197000000000873013f000000000073004b000000000300001900000b030300204100000000006c004b000000000d00001900000b030d00404100000b030080009c00000000030dc019000000000003004b000000580000613d0000000c0cc000290000002403c00039000000000831034f000000000808043b00000a400080009c000000580000213d00000000088b04360000002003300039000000000d31034f000000000d0d043b0000ffff00d0008c000000580000213d00000000050400190000000000d804350000000708c000690000002003300039000000000331034f000000000d03043b00000b030380019700000b030ed00197000000000f3e013f00000000003e004b000000000300001900000b030300404100000000008d004b000000000800001900000b030800804100000b0300f0009c000000000308c019000000000003004b000000580000c13d0000000003cd0019000000240d3000390000000008d1034f000000000c08043b00000a4600c0009c000000580000213d00000044033000390000000b08c00069000000000083004b000000000e00001900000b030e00204100000b030880019700000b0303300197000000000f83013f000000000083004b000000000300001900000b030300404100000b0300f0009c00000000030ec019000000000003004b000000580000c13d0000004003b00039000000600400003900000000004304350000006003b000390000000000c304350000002003d00039000000000331034f00000b600fc001980000008008b00039000000000df8001900000f130000613d000000000e03034f000000000b08001900000000e40e043c000000000b4b04360000000000db004b00000f0f0000c13d0000001f0bc0019000000eb40000613d0000000003f3034f0000000304b00210000000000b0d0433000000000b4b01cf000000000b4b022f000000000303043b0000010004400089000000000343022f00000000034301cf0000000003b3019f00000000003d043500000eb40000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00000f290000c13d00000a4006600197000000000004004b00000f3b0000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001304350000006001600210000011760000013d0000000c01000029000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000402100039000000000202041a00070a430020019c00000f520000c13d000000400100043d00000b5d02000041000015900000013d000000000201041a000b00000002001d000000000002004b000010dc0000613d0000000202100039000000000202041a0000000b0020006b000010dc0000413d0000000b030000290000000a0330006c000010dc0000413d0000000102100039000000000402041a0000000a054000b9000000000004004b00000f650000613d00000000064500d90000000a0060006b00000bb90000c13d000000000031041b0006000b00500102000000060140006c00000bb90000413d000000000012041b000000400100043d0000002002100039000000060300002900000000003204350000000a02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000020300003900000b2a040000410000000c0500002928fd28f30000040f0000000100200190000000580000613d000000400100043d00000b2b0010009c00000cbd0000213d0000006002100039000000400020043f000000200210003900000000000204350000000000010435000000400200043d00000ae20020009c00000cbd0000213d0000004003200039000000400030043f0000002003200039000000000003043500000000000204350000004001100039000000000021043500000ab601000041000000000201041a000000020020008c000012960000613d0000000202000039000000000021041b00000ab701000041000000000101041a000000ff00100190000010d90000c13d00000add0100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000c00000001001d000000400300043d00000080013000390000000602000029000000000021043500000060013000390000000a02000029000000000021043500000040013000390000000702000029000000000021043500000020013000390000000502000039000000000021043500000080010000390000000000130435000500000003001d00000b2c0030009c00000cbd0000213d0000000501000029000000a001100039000000400010043f0000000c010000290000000802000029000000090300002928fd1f0b0000040f000000400400043d00000ae20040009c00000cbd0000213d00000000030100190000004001400039000000400010043f00000064010000390000000101100367000000000101043b000000000114043600000000000104350000000c010000290000000502000029000000000500041128fd23e80000040f000c00000001001d00000adf01000041000000000201041a000000010020003a00000bb90000413d0000000102200039000900000002001d000000000021041b0000000c010000290000000001010433000000000010043f00000b2d01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000902000029000000000021041b000000000020043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000603000029000000000031041b00000ad501000041000000000201041a000000000032001a00000bb90000413d0000000602200029000000000021041b00000ad401000041000000000201041a000000060220006c00000bb90000413d000000000021041b00000b2e01000041000000400200043d000900000002001d000000000012043500000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000201043b000000090100002900000a400010009c00000a40010080410000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abf011001c700000a430220019728fd28f80000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000905700029000010360000613d000000000801034f0000000909000029000000008a08043c0000000009a90436000000000059004b000010320000c13d000000000006004b000010430000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000017860000613d0000001f01400039000000600210018f0000000901200029000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f000000200030008c000000580000413d0000000902000029000000000302043300000a400030009c000000580000213d0000000c020000290000000002020433000000a0041000390000000605000029000000000054043500000080041000390000000a0500002900000000005404350000006004100039000000070500002900000000005404350000004004100039000000000024043500000020021000390000000000320435000000a003000039000000000031043500000b2f0010009c00000cbd0000213d000000c003100039000900000003001d000000400030043f000000e00410003900000b3003000041000c00000004001d0000000000340435000000e403100039000000200400003900000000004304350000010404100039000000000301043300000000003404350000012401100039000000000003004b000010810000613d000000000400001900000000051400190000000006240019000000000606043300000000006504350000002004400039000000000034004b0000107a0000413d000000000113001900000000000104350000001f0130003900000b6001100197000000440210003900000009030000290000000000230435000000830110003900000b60021001970000000001320019000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f00000b2201000041000000000101041a000800000001001d00000b2001000041000000000101041a00000acf02000041000000000020044300000a4301100197000700000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000080100002900000a4301100197000000400400043d00000024024000390000004003000039000000000032043500000b31020000410000000000240435000000040240003900000000001204350000000901000029000000000101043300000044024000390000000000120435000900000004001d0000006402400039000000000001004b000010c30000613d000000000300001900000000042300190000000c05300029000000000505043300000000005404350000002003300039000000000013004b000010bc0000413d0000001f0310003900000b600330019700000000012100190000000000010435000000640130003900000a400010009c00000a40010080410000006001100210000000090200002900000a400020009c00000a40020080410000004002200210000000000121019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f0000000a0000006b000018380000c13d00000007020000290000183d0000013d000000400100043d00000acd02000041000015900000013d000000400100043d00000b5c02000041000015900000013d00000abb01000041000000000201041a0000000a0400002900000024014000390000000b03000029000000000031043500000abc010000410000000001140436000b00000001001d00000004014000390000000c03000029000000000031043500000a400040009c00000a400100004100000000010440190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abd011001c700000a430220019728fd28f80000040f000000600310027000000a4003300197000000400030008c000000400400003900000000040340190000001f0640018f00000060074001900000000a05700029000011060000613d000000000801034f0000000a09000029000000008a08043c0000000009a90436000000000059004b000011020000c13d000000000006004b000011130000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f000000000065043500000001002001900000115d0000613d0000001f01400039000000e00210018f0000000a01200029000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f000000400030008c000000580000413d0000000a0200002900000000030204330000000b020000290000000002020433000b00000003001d000000000032004b000012990000a13d00000abe02000041000015900000013d000000400300043d000c00000003001d00000b0001000041000000000013043500000004013000390000002002000039000000000021043500000024033000390000000b01000029000000000207001928fd1eda0000040f0000000c02000029000000000121004900000a400010009c00000a400100804100000a400020009c00000a400200804100000060011002100000004002200210000000000121019f000028ff00010430000b000000000035000000400200043d000a00000002001d000001fe0000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000114b0000c13d000011680000013d00000b5f01200197000000060200002900000000001204350000000c0000006b00000020010000390000000001006039000011c30000013d000000400100043d00000b4a03000041000000000031043500000004031000390000000000230435000001840000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011640000c13d000000000005004b000011750000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000000a400020009c00000a40020080410000004002200210000000000112019f000028ff00010430000000400100043d00000ad102000041000015900000013d000000000101043b00000060032000390000000a0400002900000000004304350000004003200039000000070400002900000000004304350000002003200039000000080400002900000000004304350000000000120435000000000000043f00000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af6011001c7000000010200003928fd28f80000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0540018f0000002004400190000011a30000613d000000000601034f0000000007000019000000006806043c0000000007870436000000000047004b0000119f0000c13d000000000005004b000011b00000613d000000000641034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350000000100200190000012660000613d000000000100043d00000a43011001980000129b0000c13d000000400100043d00000af802000041000015900000013d000000000201043b000000000100001900000006050000290000000c060000290000000003510019000000000402041a000000000043043500000001022000390000002001100039000000000061004b000011bc0000413d0000003f0210003900000b60022001970000000b03200029000000000023004b0000000002000039000000010200403900000a460030009c00000cbd0000213d000000010020019000000cbd0000c13d000000000a030019000000400030043f0000000b020000290000000002020433000000000002004b000012000000c13d0000000a020000290000001f0220003900000b60022001970000003f0220003900000b600220019700000000022a001900000a460020009c00000cbd0000213d000000400020043f0000000a0200002900000000022a04360000000704000029000000000040007c000000580000213d0000000a0400002900000b60034001980000001f0440018f0000000001320019000000090500002900000020055000390000000105500367000011ef0000613d000000000605034f0000000007020019000000006806043c0000000007870436000000000017004b000011eb0000c13d000000000004004b000011fc0000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003104350000000a012000290000000000010435000000400200043d000012e80000013d0000000a0000006b000012a30000613d0000000a03000029000000010030008c000012a60000c13d00000b0001000041000c0000000a001d00000000001a04350000000401a00039000000200200003900000000002104350000002403a0003900000001020000390000000801000029000011350000013d00000ad301000041000000000101041a00000ad402000041000000000202041a000000000012001a00000bb90000413d000000000112001900000ad502000041000000000202041a000000000012001a00000bb90000413d000000000112001a000b00000000001d000012290000613d00000ad202000041000000000202041a000000000002004b000012240000613d00000b6103200129000000090030006c000000580000413d00000009022000b900000000121200d9000000000001004b000000010220c039000b00000002001d00000ad601000041000000000101041a00000acf02000041000000000020044300000a4301100197000600000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400300043d00000064013000390000000b02000029000000000021043500000ad7010000410000000000130435000000240130003900000000020004100000000000210435000000040130003900000000002104350000004401300039000000000001043500000a400030009c000500000003001d00000a400100004100000000010340190004004000100218000000000100041400000a400010009c00000a4001008041000000c00110021000000004011001af00000ad8011001c7000000060200002928fd28f30000040f0000000100200190000014fb0000613d000000050100002900000a460010009c00000cbd0000213d0000000501000029000000400010043f0000000001000411000000000001004b000015670000c13d00000ae50100004100000005020000290000000000120435000000040100002900000abf011001c7000028ff000104300000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000126d0000c13d000011680000013d000000200310003900000000002304350000000b02000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000020300003900000ac2040000410000000c0500002928fd28f30000040f0000000100200190000000580000613d00000000010004160000000c0200002900000aba0020009c000013140000c13d0000000b0010006b0000131b0000613d0000132b0000013d00000001010003670000002402100370000000000202043b000000060020006b000012ed0000c13d00000ab602000041000000000302041a000000020030008c0000132e0000c13d000000400100043d00000ae702000041000015900000013d000a00000001001d00000bfe0000013d0000000c0010006c000012fd0000c13d0000000c010000290000000b02000029000000090300002928fd262e0000040f0000000001000019000028fe0001042e00000000020a00190000000b0a000029000012e80000013d000000090300002900000020043000390000000103000367000000000543034f000000000505043b00000b010550019700000b020050009c0000130a0000c13d0000002005a000390000000006000019000000060900002900000000075600190000000008690019000000000808043300000000008704350000002006600039000000000026004b000012b10000413d0000000204400039000000000443034f000000000352001900000000000304350000000002a200190000000a03000029000000020330008a00000b60053001980000001f0630018f00000020072000390000000003570019000012c90000613d000000000804034f000000008908043c0000000007970436000000000037004b000012c50000c13d000000000006004b000012d60000613d000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f00000000004304350000000a022000290000001e0320003900000000000304350000000002a20049000000020320008a00000000003a04350000003d0220003900000b60012001970000000003a10019000000000013004b0000000001000039000000010100403900000a460030009c00000cbd0000213d000000010010019000000cbd0000c13d0000000002030019000000400030043f0000002001000039000c00000002001d000000000212043600000000010a001900000bd20000013d0000000401100370000000000101043b00000a400010009c000000580000213d000000400300043d0000002404300039000000000024043500000b4b0200004100000000002304350000000402300039000000000012043500000a400030009c00000a4003008041000000400130021000000abd011001c7000028ff00010430000000400200043d00000024032000390000000c04000029000000000043043500000af70300004100000000003204350000000403200039000000000013043500000a400020009c00000a4002008041000000400120021000000abd011001c7000028ff0001043000000b0001000041000c0000000a001d00000000001a04350000000401a00039000000200200003900000000002104350000002403a0003900000008010000290000000a02000029000011350000013d000000000001004b0000132b0000c13d000000000200041100000000030004100000000c010000290000000b0400002928fd27500000040f0000000901000029000000000101041a0000000b0010002a00000bb90000413d0000000b011000290000000902000029000000000012041b0000000302200039000000000202041a000000000002004b000015080000613d000000000021004b000015080000a13d000000400100043d00000acb02000041000015900000013d000000400100043d00000ac302000041000015900000013d0000000203000039000000000032041b0000000402100370000000000202043b000b00000002001d00000a400020009c000000580000213d0000004401100370000000000101043b000500000001001d00000a460010009c000000580000213d0000000b01000029000000000010043f00000b4c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000602000029000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a00000a460110019700000a460010009c00000bb90000613d0000000101100039000000050010006b000016670000c13d0000000b01000029000000000010043f00000b4c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000602000029000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a00000a460320019700000a460030009c00000bb90000613d00000b05022001970000000103300039000000000223019f000000000021041b0000000a01000029000000400010008c000000580000413d000000090100002900000020021000390000000101000367000000000321034f000000000303043b000000000003004b0000000004000039000000010400c039000000000043004b000000580000c13d0000002002200039000000000321034f000000000303043b0000000a0430006b00000bb90000413d00000b4e0340009a00000b4f0030009c000000580000413d0000002003200039000000000231034f000000000202043b000000ff0020008c000000580000213d0000006003300039000000000531034f000000000505043b000b00000005001d00000a430050009c000000580000213d0000002003300039000000000531034f000000000505043b00000a460050009c000000580000213d0000000805500029000000080440002900000b03064001970000005f0750003900000b0308700197000000000968013f000000000068004b000000000600001900000b0306004041000000000047004b000000000700001900000b030700804100000b030090009c000000000607c019000000000006004b000000580000c13d0000004006500039000000000661034f000000000606043b00000a460060009c00000cbd0000213d00000005076002100000003f0870003900000b5008800197000000400900043d0000000008890019000900000009001d000000000098004b0000000009000039000000010900403900000a460080009c00000cbd0000213d000000010090019000000cbd0000c13d000000400080043f00000009080000290000000008680436000600000008001d00000060055000390000000007570019000000000047004b000000580000213d000000000006004b000013d70000613d0000000604000029000000000651034f000000000606043b00000000046404360000002005500039000000000075004b000013d10000413d000000ff0220018f000000010420008a000000020040008c000019050000813d000000400330008a000000000431034f000000000404043b00000b3e05000041000000000605041a000000000006004b000013e90000613d000000000004004b000013e90000613d00000b610640012900000ad307000041000000000707041a000000000076004b000000580000413d000000000045041b00030020003000920000000301100360000000000301043b00000ad201000041000000000101041a000000000001004b000014040000613d00000ad304000041000000000404041a00000ad405000041000000000505041a000000000045001a00000bb90000413d000000000445001900000ad505000041000000000505041a000000000045001a00000bb90000413d000000000445001a000500000000001d000014050000613d00000b6105100129000000000035004b000000580000413d00000000031300a900000000034300d9000500000003001d0000000c03000029000400840030003d000000020020008c000019760000c13d0000000002000410000c0a430020019c00001bbd0000613d000000050010002a00000bb90000413d000000050110002900000ad202000041000000000012041b0000000c01000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a000200000002001d000000050020002a00000bb90000413d0000000c01000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d00000002030000290000000502300029000000000101043b000000000021041b00000ad301000041000000000201041a00000003030000290000000103300367000000000303043b000000000032001a00000bb90000413d0000000002320019000000000021041b00000ad201000041000000000101041a000000000001004b000300000000001d000014520000613d00000ad403000041000000000303041a000000000023001a00000bb90000413d000000000223001900000ad503000041000000000303041a000000000023001a00000bb90000413d000000000223001a000014500000613d00000b6103200129000000050030006c000000580000413d00000005022000b900030000001200e100000ac501000041000000000101041a00020a430010019c000016610000613d0000000c01000029000000000010043f00000ac601000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000202000029000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000303000029000000000031041b00000ac501000041000000000201041a000000400400043d000200000004001d00000ac70100004100000000001404350000000401400039000000000031043500000a400040009c00000a400100004100000000010440190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000ac8011001c700000a430220019728fd28f30000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f0000002007400190000000020b0000290000000205700029000014970000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000014930000c13d000000000006004b000014a40000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000010020019000001a020000613d0000001f01400039000000600110018f0000000002b10019000000000012004b00000000010000390000000101004039000c00000002001d00000a460020009c00000cbd0000213d000000010010019000000cbd0000c13d0000000c01000029000000400010043f000000200030008c000000580000413d00000ac501000041000000000201041a00000000010b04330000000c040000290000002403400039000000000013043500000ac90100004100000000001404350000000b0100002900000a43011001970000000403400039000000000013043500000a400040009c00000a400100004100000000010440190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abd011001c700000a430220019728fd28f30000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000c05700029000014dc0000613d000000000801034f0000000c09000029000000008a08043c0000000009a90436000000000059004b000014d80000c13d000000000006004b000014e90000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000010020019000001a0e0000613d0000001f01400039000000600110018f0000000c0110002900000a460010009c00000cbd0000213d000000400010043f000000200030008c000000580000413d0000000c010000290000000001010433000000000001004b0000000002000039000000010200c039000000000021004b000000580000c13d000019aa0000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000015030000c13d00000f2d0000013d00000009010000290000000101100039000000000201041a0000000a0020002a00000bb90000413d0000000a02200029000000000021041b00000ac001000041000000000201041a000000400300043d000c00000003001d00000ac401000041000000000013043500000a400030009c00000a400100004100000000010340190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abf011001c700000a430220019728fd28f30000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000c0b0000290000000c05700029000015310000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000152d0000c13d000000000006004b0000153e0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f000000000065043500000001002001900000155b0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000a460010009c00000cbd0000213d000000010020019000000cbd0000c13d000000400010043f000000200030008c000000580000413d00000000020b043300000064010000390000000101100367000000000101043b000000000001004b000016480000c13d00000000010004110000000a0300002928fd27f20000040f000000400100043d000000010200003900000ab603000041000000000023041b000008630000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000015620000c13d000011680000013d00000a4301100197000600000001001d000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a0005000b00100074000015960000813d000000400100043d00000ae402000041000015900000013d0000000b0100002900000a4500100198000500000000001d0000158e0000c13d0000000b0200002900000b050120019700000001011001bf00000b060220019700000b07022001c7000000050000006b000000000201c01900000a4401000041000000000021041b00000a4500200198000016510000c13d000000400100043d00000b2502000041000015900000013d000000400100043d00000b2802000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff0001043000000ad201000041000000000101041a000000000001004b000400000000001d000015ad0000613d00000ad302000041000000000202041a00000ad403000041000000000303041a000000000023001a00000bb90000413d000000000223001900000ad503000041000000000303041a000000000023001a00000bb90000413d000000000223001a000015ab0000613d00000b61032001290000000b0030006c000000580000413d0000000b022000b900040000001200e10000000b0110006c00000bb90000413d00000ad202000041000000000012041b0000000601000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000502000029000000000021041b00000ad201000041000000000101041a000000000001004b0000000002000019000015d80000613d00000ad302000041000000000202041a00000ad403000041000000000303041a000000000023001a00000bb90000413d000000000223001900000ad503000041000000000303041a000000000023001a00000bb90000413d000000000223001a000015d60000613d00000b61032001290000000b0030006c000000580000413d0000000b022000b900000000021200d9000000400100043d00000040031000390000000b040000290000000000430435000000200310003900000000002304350000000402000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ada011001c70000800d02000039000000020300003900000adb04000041000000000500041128fd28f30000040f0000000100200190000000580000613d000000400300043d00000060013000390000000c02000029000000000021043500000040013000390000000902000029000000000021043500000020013000390000000302000039000000000021043500000060010000390000000000130435000500000003001d00000adc0030009c00000cbd0000213d00000005010000290000008001100039000000400010043f00000add0100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000400000001001d0000000702000029000000080300002928fd1f0b0000040f000300000001001d00000ad501000041000000000101041a000000000001004b000017920000c13d00000ad301000041000000000201041a000000090220006c00000bb90000413d000000000021041b000000400400043d00000ae20040009c00000cbd0000213d0000004001400039000000400010043f0000000001000416000000000114043600000000000104350000000a0100002900000a430510019700000004010000290000000502000029000000030300002928fd23e80000040f0000000005010433000000400100043d0000000902000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000040300003900000ae30400004100000000060004110000000c0700002928fd28f30000040f0000000100200190000000580000613d000000010100003900000ab602000041000000000012041b0000000001000019000028fe0001042e00000000010004100000000a0300002928fd27f20000040f000000000100041000000a43011001980000165d0000c13d000000400100043d00000aca02000041000016630000013d000000010200003900000ab601000041000000000021041b00000ab701000041000000000201041a00000b5f02200197000000000021041b0000000a0000006b0000166a0000c13d000000400100043d00000b2702000041000016630000013d00000ac502000041000000000202041a000c0a430020019c000016850000c13d000000400100043d00000b5802000041000000000021043500000004021000390000000000020435000001840000013d000000400100043d00000b4d02000041000015900000013d00000ae801000041000000000201041a00000afc032001970000000a06000029000000000363019f000000000031041b000000000100041400000a430520019700000a400010009c00000a4001008041000000c00110021000000af2011001c70000800d02000039000000030300003900000b080400004128fd28f30000040f0000000100200190000000580000613d00000a4401000041000000000101041a00000a45001001980000158b0000613d0000000c0000006b000017350000c13d000000400100043d00000b2602000041000015900000013d000000000010043f00000ac601000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000c02000029000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b0000000a03000029000000000031041b00000ac501000041000000000201041a000000400400043d000c00000004001d00000ac70100004100000000001404350000000401400039000000000031043500000a400040009c00000a400100004100000000010440190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000ac8011001c700000a430220019728fd28f30000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000c0b0000290000000c05700029000016c50000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000016c10000c13d000000000006004b000016d20000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f000000000065043500000001002001900000177a0000613d0000001f01400039000000600110018f0000000002b10019000000000012004b00000000010000390000000101004039000b00000002001d00000a460020009c00000cbd0000213d000000010010019000000cbd0000c13d0000000b01000029000000400010043f000000200030008c000000580000413d00000ac501000041000000000201041a00000000010b04330000000b040000290000002403400039000000000013043500000ac9010000410000000000140435000000000100041100000a43011001970000000403400039000000000013043500000a400040009c00000a400100004100000000010440190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abd011001c700000a430220019728fd28f30000040f000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000b057000290000170a0000613d000000000801034f0000000b09000029000000008a08043c0000000009a90436000000000059004b000017060000c13d000000000006004b000017170000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000017cb0000613d0000001f01400039000000600110018f0000000b0110002900000a460010009c00000cbd0000213d000000400010043f000000200030008c000000580000413d0000000b020000290000000002020433000000000002004b0000000003000039000000010300c039000000000032004b000015570000613d000000580000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000017300000c13d000011680000013d00000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000101043b00000acf02000041000000000020044300000a4301100197000b00000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400200043d00000afe010000410000000001120436000400000001001d00000004012000390000000c03000029000000000031043500000a400020009c000c00000002001d00000a40010000410000000001024019000a004000100218000000000100041400000a400010009c00000a4001008041000000c0011002100000000a011001af00000ac8011001c70000000b0200002928fd28f30000040f0000000100200190000017d70000613d0000000c0100002900000a460010009c00000cbd0000213d0000000c01000029000000400010043f00000a4401000041000000000101041a00000a4500100198000017f70000c13d00000b25010000410000000c0200002900000000001204350000000a0100002900000abf011001c7000028ff000104300000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000017810000c13d000011680000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000178d0000c13d000011680000013d00000ae001000041000000000101041a000b00000001001d00000b610010009c00000bb90000613d00000adf01000041000000000101041a000600000001001d000800090000002d00000006020000290000000b0020006b000017e40000813d0000000b010000290000000101100039000b00000001001d000000000010043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a0007000800200073000017f30000413d0000000b01000029000000000010043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000001041b00000ae001000041000000000101041a000000010110003a00000bb90000613d00000ae002000041000000000012041b000000010200008a0000000b0020006b000800070000002d0000179b0000c13d00000bb90000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000017d20000c13d000011680000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000017df0000c13d00000f2d0000013d0000000802000029000000090120006b00000bb90000413d00000ad502000041000000000302041a000000000113004b00000bb90000413d000000000012041b000000080000006b000016200000613d00000ad301000041000000000201041a000000080220006c00000bb90000413d0000161f0000013d000000080220006a000000000021041b00000ad5010000410000161c0000013d000000800100043d00000a460010009c00000cbd0000213d00000b0902000041000000000302041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f00000001003001900000070c0000c13d000000200020008c000018170000413d00000b0903000041000000000030043f0000001f03100039000000050330027000000b0a0330009a000000200010008c00000b0b030040410000001f02200039000000050220027000000b0a0220009a000000000023004b000018170000813d000000000003041b0000000103300039000000000023004b000018130000413d0000001f0010008c00000001021002100000182e0000a13d00000b0903000041000000000030043f00000b6005100198000018a90000c13d000000200400003900000b0b03000041000018b50000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000018290000c13d00000f2d0000013d000000000001004b0000000003000019000018320000613d000000a00300043d000000030110021000000b610110027f00000b6101100167000000000113016f000000000121019f000018c00000013d00000af2011001c700008009020000390000000a030000290000000704000029000000000500001928fd28f30000040f00000001002001900000189c0000613d000000090100002900000a460010009c00000cbd0000213d0000000901000029000000400010043f00000b3201000041000000000101041a000c00000001001d0000000b020000290000000a0020006c000018540000613d0000000a0000006b000018510000613d000000010100008a0000000a011000fa0000000c0010006c000000580000413d0000000c020000290000000a012000b9000c000b0010010200000ad601000041000000000101041a00000acf02000041000000000020044300000a4301100197000b00000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400300043d00000044013000390000000c020000290000000000210435000000240130003900000aba02000041000000000021043500000ad7010000410000000001130436000800000001001d000000000100041000000a4301100197000000040230003900000000001204350000006401300039000000000001043500000a400030009c000900000003001d00000a400100004100000000010340190007004000100218000000000100041400000a400010009c00000a4001008041000000c00110021000000007011001af00000ad8011001c70000000b0200002928fd28f30000040f0000000100200190000019f50000613d000000090100002900000a460010009c00000cbd0000213d0000000901000029000000400010043f00000b3201000041000000000201041a0000000c0220006c00000bb90000413d000000000021041b000000010100003900000ab602000041000000000012041b0000000601000029000000080200002900000000001204350000000a0100002900000009020000290000000000120435000000070100002900000b33011001c7000028fe0001042e00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000018a40000c13d00000f2d0000013d00000b0b030000410000002004000039000000010650008a000000050660027000000b0c0660009a00000080074000390000000007070433000000000073041b00000020044000390000000103300039000000000063004b000018ae0000c13d000000000015004b000018bf0000813d0000000301100210000000f80110018f00000b610110027f00000b610110016700000080044000390000000004040433000000000114016f000000000013041b00000001012001bf00000b0902000041000000000012041b0000000701000029000000000101043300000a460010009c00000cbd0000213d00000b0d02000041000000000302041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f00000001003001900000070c0000c13d000000200020008c000018e30000413d00000b0d03000041000000000030043f0000001f03100039000000050330027000000b0e0330009a000000200010008c00000b0f030040410000001f02200039000000050220027000000b0e0220009a000000000023004b000018e30000813d000000000003041b0000000103300039000000000023004b000018df0000413d0000001f0010008c0000000102100210000018ed0000a13d00000b0d03000041000000000030043f00000b6005100198000019230000c13d000000200400003900000b0f030000410000192f0000013d000000000001004b0000000003000019000018f20000613d00000006030000290000000003030433000000030110021000000b610110027f00000b6101100167000000000113016f000000000121019f0000193a0000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000019000000c13d00000f2d0000013d000000040020008c000019200000c13d0000000c02000029000b00a40020003d0000000b02100360000000000202043b00000b3e03000041000000000403041a000000000004004b000019160000613d000000000002004b000019160000613d00000b610420012900000ad305000041000000000505041a000000000054004b000000580000413d000000000023041b00000b4103000041000000000303041a000000000003004b00001a1a0000c13d0000000b04000029000000200440008a000000000441034f000000000404043b00001a210000013d000000400100043d00000b5902000041000015900000013d00000b0f030000410000002004000039000000010650008a000000050660027000000b100660009a00000007074000290000000007070433000000000073041b00000020044000390000000103300039000000000063004b000019280000c13d000000000015004b000019390000813d0000000301100210000000f80110018f00000b610110027f00000b610110016700000007044000290000000004040433000000000114016f000000000013041b00000001012001bf00000b0d02000041000000000012041b00000a4401000041000000000101041a00000a4500100198000017740000613d0000000c0100002900000ae20010009c00000cbd0000213d0000000c020000290000004001200039000000400010043f0000000101000039000000000012043500000b110100004100000004020000290000000000120435000000800100043d00000a460010009c00000cbd0000213d00000b1202000041000000000302041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f00000001003001900000070c0000c13d000000200020008c0000196b0000413d00000b1203000041000000000030043f0000001f03100039000000050330027000000b130330009a000000200010008c00000b14030040410000001f02200039000000050220027000000b130220009a000000000023004b0000196b0000813d000000000003041b0000000103300039000000000023004b000019670000413d0000001f0010008c0000000102100210000000030310021000001aa10000a13d00000b1204000041000000000040043f00000b600610019800001aaa0000c13d000000200500003900000b140400004100001ab60000013d0000000b02000029000c0a430020019c00001bbd0000613d000000050010002a00000bb90000413d000000050110002900000ad202000041000000000012041b0000000c01000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a000300000002001d000000050020002a00000bb90000413d0000000c01000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d00000003030000290000000502300029000000000101043b000000000021041b00000ad301000041000000000201041a00000004030000290000000103300367000000000303043b000000000032001a00000bb90000413d0000000002320019000000000021041b00000ad601000041000000000101041a00000acf02000041000000000020044300000a4301100197000300000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400300043d00000044013000390000000502000029000000000021043500000ad7010000410000000001130436000200000001001d000000000100041000000a430110019700000024023000390000000000120435000000040230003900000000001204350000006401300039000000000001043500000a400030009c000c00000003001d00000a400100004100000000010340190001004000100218000000000100041400000a400010009c00000a4001008041000000c00110021000000001011001af00000ad8011001c7000000030200002928fd28f30000040f000000010020019000001aec0000613d0000000c0100002900000a460010009c00000cbd0000213d0000000c02000029000000400020043f0000000501000029000000000012043500000001010003670000000402100360000000000202043b000000020300002900000000002304350000006401100370000000000501043b000000000100041400000a400010009c00000a4001008041000000c00110021000000001011001af0000000b0200002900000a430620019700000ab9011001c70000800d02000039000000030300003900000b540400004100001b1c0000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000019fd0000c13d00000f2d0000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00001a090000c13d000011680000013d0000001f0530018f00000a4206300198000000400200043d0000000004620019000011680000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00001a150000c13d000011680000013d00000b61053001290000000c040000290000008404400039000000000441034f000000000404043b000000000054004b000000580000213d00000000033400a900000b510030009c00001af90000413d00000ad304000041000000000404041a00000ad405000041000000000505041a000000000045001a00000bb90000413d000000000445001900000ad505000041000000000505041a000000000045001a00000bb90000413d00050b51003001320000000003450019000000050330006c00001af90000a13d00000ad201000041000000000101041a000000000001004b00001a3a0000613d00000b6102100129000000050020006c000000580000413d00000b1c02000041000000000202041a00040a430020019c00001bbd0000613d00000005021000b9000c0000003200e10000000c0010002a00000bb90000413d0000000c0110002900000ad202000041000000000012041b0000000401000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000201041a000300000002001d0000000c0020002a00000bb90000413d0000000401000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d00000003030000290000000c02300029000000000101043b000000000021041b00000ad601000041000000000101041a00000acf02000041000000000020044300000a4301100197000200000001001d0000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400300043d00000044013000390000000c02000029000000000021043500000ad7010000410000000000130435000000000100041000000a430110019700000024023000390000000000120435000000040230003900000000001204350000006401300039000000000001043500000a400030009c000400000003001d00000a400100004100000000010340190003004000100218000000000100041400000a400010009c00000a4001008041000000c00110021000000003011001af00000ad8011001c7000000020200002928fd28f30000040f000000010020019000001b5d0000613d000000040100002900000a460010009c00000cbd0000213d0000000401000029000000400010043f00000001010003670000000b02100360000000000202043b00001b000000013d000000000001004b000000000100001900001aa50000613d000000a00100043d00000b610330027f00000b6103300167000000000131016f000000000121019f00001ac00000013d00000b14040000410000002005000039000000010760008a000000050770027000000b150770009a00000080085000390000000008080433000000000084041b00000020055000390000000104400039000000000074004b00001aaf0000c13d000000000016004b00001abf0000813d000000f80130018f00000b610110027f00000b610110016700000080035000390000000003030433000000000113016f000000000014041b00000001012001bf00000b1202000041000000000012041b0000000c01000029000000000101043300000a460010009c00000cbd0000213d00000b1602000041000000000302041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f00000001003001900000070c0000c13d000000200020008c00001ae30000413d00000b1603000041000000000030043f0000001f03100039000000050330027000000b170330009a000000200010008c00000b18030040410000001f02200039000000050220027000000b170220009a000000000023004b00001ae30000813d000000000003041b0000000103300039000000000023004b00001adf0000413d0000001f0010008c00001b6a0000a13d00000b1602000041000000000020043f00000b600410019800001b760000c13d000000200300003900000b180200004100001b820000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00001af40000c13d00000f2d0000013d000000400300043d00000a400030009c000400000003001d00000a40030080410003004000300218000c00000000001d000500000000001d00000b1c03000041000000000303041a000000040600002900000000002604350000000b02000029000000200220008a000000000221034f000000000202043b00000060046000390000000c050000290000000000540435000000400460003900000005050000290000000000540435000000200460003900000000002404350000006401100370000000000501043b000000000100041400000a400010009c00000a4001008041000000c00110021000000003011001af00000a430630019700000b52011001c70000800d02000039000000030300003900000b530400004128fd28f30000040f0000000100200190000000580000613d00000009010000290000000001010433000500000001001d000000000001004b00001c910000613d00000ae001000041000000000101041a000400000001001d00000adf01000041000000000101041a000300000001001d000c00000000001d000b00000000001d00001b320000013d0000000c020000290000000102200039000c00000002001d000000050020006c00001bc00000813d000000090100002900000000010104330000000c0010006b00001bfe0000813d0000000c01000029000000050110021000000006011000290000000001010433000000000010043f00000b2d01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000000010043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000201043b000000000102041a000000000001004b00001b2d0000613d000000000002041b0000000b0010002a00000bb90000413d000b000b0010002d00001b2d0000013d00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00001b650000c13d00000f2d0000013d000000000001004b000000000200001900001b6f0000613d00000004020000290000000002020433000000030310021000000b610330027f00000b6103300167000000000232016f0000000101100210000000000112019f00001b8e0000013d00000b18020000410000002003000039000000010540008a000000050550027000000b190550009a0000000c063000290000000006060433000000000062041b00000020033000390000000102200039000000000052004b00001b7b0000c13d000000000014004b00001b8c0000813d0000000304100210000000f80440018f00000b610440027f00000b61044001670000000c033000290000000003030433000000000343016f000000000032041b000000010110021000000001011001bf00000b1602000041000000000012041b00000b1a01000041000000000001041b00000b1b01000041000000000001041b00000001010003670000004402100370000000000202043b00000a430220019800001bbd0000613d00000b1c03000041000000000403041a00000afc04400197000000000224019f000000000023041b0000006401100370000000000101043b00000a430110019800001bbd0000613d00000ac002000041000000000302041a00000afc03300197000000000313019f000000000032041b000000400200043d000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b1d0400004128fd28f30000040f0000000100200190000000580000613d00000084010000390000000101100367000000000101043b00000a430110019800001c040000c13d000000400100043d00000ae502000041000015900000013d000000010200008a000000040020006b00000bb90000613d0000000502000029000000040020002a00000bb90000413d00000005020000290000000402200029000000030020006c0000000302008029000c00000002001d00001bcf0000013d000000010200008a000000040020006b00000bb90000613d0000000c01000029000900040000002d000000040010006b00001c840000813d00000009010000290000000101100039000400000001001d000000000010043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000000001004b00001c810000c13d0000000c02000029000000040020006b00001bcc0000c13d0000000c01000029000000000010043f00000ae101000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000000580000613d000000000101043b000000000101041a000000000001004b00001bcc0000c13d0000000c0100002900000ae002000041000000000012041b00001bcc0000013d00000b5501000041000000000010043f0000003201000039000000040010043f00000ac801000041000028ff0001043000000ad602000041000000000302041a00000afc03300197000000000313019f000000000032041b000000400200043d000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b1e0400004128fd28f30000040f0000000100200190000000580000613d00000abb01000041000000000201041a00000afc02200197000000e4030000390000000103300367000000000303043b00000a4303300197000000000232019f000000000021041b000000400100043d000000000031043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b1f0400004128fd28f30000040f0000000100200190000000580000613d00000a4401000041000000000101041a00000a45001001980000158b0000613d000000090100002900000a430110019700000b2002000041000000000302041a00000afc03300197000000000313019f000000000032041b000000400200043d000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b210400004128fd28f30000040f0000000100200190000000580000613d00000a4401000041000000000101041a00000a45001001980000158b0000613d000000080100002900000a430110019700000b2202000041000000000302041a00000afc03300197000000000313019f000000000032041b000000400200043d000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b230400004128fd28f30000040f0000000100200190000000580000613d000000050000006b00000cae0000c13d00000a4401000041000000000201041a00000b2402200197000000000021041b000000400100043d0000000103000039000000000031043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d0200003900000a480400004100000cab0000013d00000ae0010000410000000902000029000000000021041b0000000b0000006b00001c910000613d00000ad301000041000000000201041a0000000b0020002a00000bb90000413d0000000b02200029000000000021041b00000ad501000041000000000201041a0000000b0220006c00000bb90000413d000000000021041b00000001010003670000000802100360000000000302043b000000000003004b0000000002000039000000010200c039000000000023004b000000580000c13d00000008020000290000002004200039000000000241034f000000000202043b000000000003004b000016430000613d0000000405100370000000000505043b00000a400050009c000000580000213d0000004406100370000000000606043b000000010030008c000000580000c13d00000b560060009c000000580000813d000000210700008a0000000a0070006b00000bb90000213d0000000a030000290000002003300039000000000a23004b00000bb90000413d0000000a07a0006b000000580000413d00000a460070009c00000cbd0000213d0000001f0370003900000b60033001970000003f0330003900000b6003300197000000400900043d0000000008390019000000000098004b000000000b000039000000010b00403900000a460080009c00000cbd0000213d0000000100b0019000000cbd0000c13d000000400080043f0000000008790436000000070b0000290000000000b0007c000000580000213d000000080aa00029000000000ba1034f00000b600c7001980000001f0d70018f000000000ac8001900001cd20000613d000000000e0b034f000000000f08001900000000e30e043c000000000f3f04360000000000af004b00001cce0000c13d00000000000d004b00001cdf0000613d0000000003cb034f000000030bd00210000000000c0a0433000000000cbc01cf000000000cbc022f000000000303043b000001000bb000890000000003b3022f0000000003b301cf0000000003c3019f00000000003a043500000000037800190000000000030435000000400a00043d0000002007a0003900000000030004100000000000370435000000400ba000390000000009090433000000000009004b00001cf10000613d000000000c0000190000000003bc0019000000000d8c0019000000000d0d04330000000000d30435000000200cc0003900000000009c004b00001cea0000413d0000000003b900190000000000030435000000200390003900000000003a04350000005f0390003900000b60033001970000000009a30019000000000039004b00000000080000390000000108004039000c00000009001d00000a460090009c00000cbd0000213d000000010080019000000cbd0000c13d0000000c08000029000000400080043f000000c0036002100000002006800039000b00000006001d0000000000360435000000e003500210000000280580003900000000003504350000004003400039000000000331034f000000000303043b0000002c0480003900000000003404350000004c0580003900000000040a0433000000000004004b00001d1a0000613d000000000600001900000000035600190000000008760019000000000808043300000000008304350000002006600039000000000046004b00001d130000413d000000000354001900000000000304350000002c034000390000000c0500002900000000003504350000006b0340003900000b60033001970000000004530019000000000034004b0000000005000039000000010500403900000a460040009c00000cbd0000213d000000010050019000000cbd0000c13d000000400040043f0000000a0220006b00000bb90000413d00000b620020009c00000bb90000213d00000020032000390000000a0030006c000000580000213d0000000802200029000000000121034f000000000101043b000a00000001001d00000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d000000000101043b00000acf02000041000000000020044300000a43011001970000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f000000010020019000001da20000613d000000000101043b000000000001004b000000580000613d000000400400043d00000b570100004100000000001404350000000a0100002900000a43011001970000000402400039000000000012043500000064010000390000000101100367000000000101043b00000064024000390000008003000039000000000032043500000024024000390000000000120435000000440140003900000000000104350000000c01000029000000000201043300000084014000390000000000210435000a00000004001d000000a401400039000c00000002001d000000000002004b00001d760000613d000000000200001900000000031200190000000b042000290000000004040433000000000043043500000020022000390000000c0020006c00001d6f0000413d0000000c01100029000000000001043500000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f000000010020019000001da20000613d0000000c020000290000001f0220003900000b6002200197000000a40220003900000a400020009c00000a400200804100000060022002100000000a0300002900000a400030009c00000a40030080410000004003300210000000000232019f000000000301043b000000000100041400000a400010009c00000a4001008041000000c001100210000000000121019f00000a430230019728fd28f30000040f000000010020019000001da30000613d0000000a0100002900000a460010009c00000cbd0000213d0000000a01000029000000400010043f000016430000013d000000000001042f00000060061002700000001f0460018f00000a4205600198000000400200043d000000000352001900000f2d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00001dab0000c13d00000f2d0000013d0000001f03100039000000000023004b000000000400001900000b030400404100000b030520019700000b0303300197000000000653013f000000000053004b000000000300001900000b030300204100000b030060009c000000000304c019000000000003004b00001dc80000613d0000000103100367000000000303043b00000a460030009c00001dc80000213d00000020011000390000000004310019000000000024004b00001dc80000213d0000000002030019000000000001042d0000000001000019000028ff0001043000000000430104340000000001320436000000000003004b00001dd60000613d000000000200001900000000051200190000000006240019000000000606043300000000006504350000002002200039000000000032004b00001dcf0000413d000000000213001900000000000204350000001f0230003900000b60022001970000000001210019000000000001042d00000024010000390000000101100367000000000101043b000000000001004b0000000002000039000000010200c039000000000021004b00001de50000c13d000000000001042d0000000001000019000028ff0001043000000000320204340000000002210436000000000303043300000000003204350000004001100039000000000001042d00000b630010009c00001dfd0000213d000000630010008c00001dfd0000a13d00000001030003670000000401300370000000000101043b00000a430010009c00001dfd0000213d0000002402300370000000000202043b00000a430020009c00001dfd0000213d0000004403300370000000000303043b000000000001042d0000000001000019000028ff0001043000000b640010009c00001e040000813d000000a001100039000000400010043f000000000001042d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff0001043000000b650010009c00001e0f0000813d0000004001100039000000400010043f000000000001042d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff000104300000001f0220003900000b60022001970000000001120019000000000021004b0000000002000039000000010200403900000a460010009c00001e210000213d000000010020019000001e210000c13d000000400010043f000000000001042d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff0001043000000a4301100197000000000010043f00000b2901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001e360000613d000000000101043b000000000001042d0000000001000019000028ff0001043000000a4301100197000000000010043f00000ab801000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001e470000613d000000000101043b000000000001042d0000000001000019000028ff0001043000000a4301100197000000000010043f00000b3c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001e580000613d000000000101043b000000000001042d0000000001000019000028ff0001043000000a4301100197000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001e690000613d000000000101043b000000000001042d0000000001000019000028ff0001043000000a4301100197000000000010043f00000ac601000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001e7a0000613d000000000101043b000000000001042d0000000001000019000028ff000104300002000000000002000000000301041a000000010430019000000001063002700000007f0660618f0000001f0060008c00000000050000390000000105002039000000000054004b00001ead0000c13d0000000005620436000000000004004b00001ea40000613d000200000006001d000100000005001d000000000010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000a47011001c7000080100200003928fd28f80000040f000000010020019000001eb30000613d0000000206000029000000000006004b00001eab0000613d000000000201043b000000000100001900000001050000290000000003150019000000000402041a000000000043043500000001022000390000002001100039000000000061004b00001e9b0000413d0000000001150019000000000001042d00000b5f013001970000000000150435000000000006004b000000200100003900000000010060390000000001150019000000000001042d0000000101000029000000000001042d00000b5501000041000000000010043f0000002201000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff0001043000000a43033001970000004004100039000000000034043500000020031000390000000000230435000000030200003900000000002104350000006001100039000000000001042d00000a4001100197000000000010043f00000b4c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001ecd0000613d000000000101043b000000000001042d0000000001000019000028ff0001043000000a460110019700000a460010009c00001ed40000613d0000000101100039000000000001042d00000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff00010430000000000323043600000b60062001980000001f0720018f0000000005630019000000010110036700001ee60000613d000000000801034f0000000009030019000000008a08043c0000000009a90436000000000059004b00001ee20000c13d000000000007004b00001ef30000613d000000000161034f0000000306700210000000000705043300000000076701cf000000000767022f000000000101043b0000010006600089000000000161022f00000000016101cf000000000171019f0000000000150435000000000123001900000000000104350000001f0120003900000b60011001970000000001130019000000000001042d00000a4001100197000000000010043f00000b4701000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001f090000613d000000000101043b000000000101041a000000000001042d0000000001000019000028ff000104300005000000000002000500000003001d000400000002001d00000a4001100197000000000010043f00000aff01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001fd90000613d000000000101043b000000000000043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f000000010020019000001fd90000613d000000000501043b000000000205041a000000010320019000000001062002700000007f0660618f0000001f0060008c00000000040000390000000104002039000000000043004b00001fe10000c13d000000400100043d0000000008610436000000000003004b00001f510000613d000300000006001d000100000001001d000200000008001d000000000050043f000000000100041400000a400010009c00000a4001008041000000c00110021000000a47011001c7000080100200003928fd28f80000040f000000010020019000001fd90000613d0000000306000029000000000006004b00001f580000613d000000000201043b0000000005000019000000050a00002900000002080000290000000003850019000000000402041a000000000043043500000001022000390000002005500039000000000065004b00001f490000413d00001f5b0000013d00000b5f022001970000000000280435000000000006004b00000020050000390000000005006039000000050a00002900001f5c0000013d0000000005000019000000050a000029000000020800002900000001010000290000003f0250003900000b6002200197000000000b12001900000000002b004b0000000002000039000000010200403900000a4600b0009c00001fdb0000213d000000010020019000001fdb0000c13d0000004000b0043f0000000002010433000000000002004b00001fad0000613d00000000000a004b00001fd80000613d0000000100a0008c00001fe70000613d00000001030003670000000404300360000000000404043b00000b010440019700000b020040009c00001ff00000c13d0000002005b00039000000000400001900000000065400190000000007480019000000000707043300000000007604350000002004400039000000000024004b00001f760000413d00000004040000290000000204400039000000000443034f000000000352001900000000000304350000000002b200190000000203a0008a00000b60053001980000001f0630018f0000002007200039000000000357001900001f8e0000613d000000000804034f000000008908043c0000000007970436000000000037004b00001f8a0000c13d000000000006004b00001f9b0000613d000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f00000000004304350000000002a200190000001e0320003900000000000304350000000002b20049000000020320008a00000000003b04350000003d0220003900000b60022001970000000001b20019000000000021004b0000000002000039000000010200403900000a460010009c00001fdb0000213d000000010020019000001fdb0000c13d000000400010043f00001fd70000013d00000a4600a0009c00001fdb0000213d0000001f02a0003900000b60022001970000003f0220003900000b600220019700000000022b001900000a460020009c00001fdb0000213d000000400020043f0000000002ab04360000000404a00029000000000040007c00001fd90000213d000000050900002900000b60039001980000001f0490018f00000004010000290000000105100367000000000132001900001fc80000613d000000000605034f0000000007020019000000006806043c0000000007870436000000000017004b00001fc40000c13d000000000004004b00001fd50000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003104350000000001920019000000000001043500000000010b0019000000000001042d0000000001000019000028ff0001043000000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff0001043000000b5501000041000000000010043f0000002201000039000000040010043f00000ac801000041000028ff0001043000000b000100004100000000001b04350000000401b00039000000200200003900000000002104350000002403b000390000000102000039000000040100002900001ff80000013d00000b000100004100000000001b04350000000401b00039000000200200003900000000002104350000002403b00039000000040100002900000000020a001900050000000b001d28fd1eda0000040f0000000502000029000000000121004900000a400010009c00000a400100804100000a400020009c00000a400200804100000060011002100000004002200210000000000121019f000028ff0001043000000ad202000041000000000202041a000000000002004b0000201f0000613d00000ad303000041000000000303041a00000ad404000041000000000404041a000000000034001a000020210000413d000000000334001900000ad504000041000000000404041a0000000003340019000000000043004b00000000040000390000000104004039000000010040008c000020210000613d000000000003004b0000201c0000613d00000b6104300129000000000014004b000020270000413d00000000011300a900000000012100d9000000000001042d0000000001000019000000000001042d00000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff00010430000000600510003900000000004504350000004004100039000000000034043500000a430220019700000020031000390000000000230435000000050200003900000000002104350000008001100039000000000001042d00000a4306100198000020480000613d00000ae801000041000000000201041a00000afc03200197000000000363019f000000000031041b000000000100041400000a430520019700000a400010009c00000a4001008041000000c00110021000000af2011001c70000800d02000039000000030300003900000b080400004128fd28f30000040f0000000100200190000020520000613d000000000001042d000000400100043d00000b270200004100000000002104350000000402100039000000000002043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff000104300000000001000019000028ff0001043000000ad301000041000000000101041a00000ad402000041000000000202041a000000000012001a000020640000413d000000000112001900000ad502000041000000000202041a0000000001120019000000000021004b00000000020000390000000102004039000000010020008c000020640000613d000000000001042d00000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff0001043000000ae801000041000000000101041a00000a43021001970000000001000411000000000012004b000020710000c13d000000000001042d000000400200043d00000ae90300004100000000003204350000000403200039000000000013043500000a400020009c00000a4002008041000000400120021000000ac8011001c7000028ff0001043000000ad302000041000000000202041a00000ad403000041000000000303041a000000000023001a0000209a0000413d000000000223001900000ad503000041000000000303041a0000000002230019000000000032004b00000000030000390000000103004039000000010030008c0000209a0000613d000000000002004b000020980000613d00000ad203000041000000000303041a000000000003004b000020930000613d00000b6104300129000000000014004b000020a00000413d00000000011300a900000000212100d9000000000002004b000000010110c039000000000001042d0000000001000019000000000001042d00000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff0001043000000ad302000041000000000202041a00000ad403000041000000000303041a000000000023001a000020bf0000413d000000000223001900000ad503000041000000000303041a0000000002230019000000000032004b00000000030000390000000103004039000000010030008c000020bf0000613d000000000002004b000020bd0000613d00000ad203000041000000000303041a000000000003004b000020ba0000613d00000b6104300129000000000014004b000020c50000413d00000000011300a900000000012100d9000000000001042d0000000001000019000000000001042d00000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff000104300004000000000002000300000003001d000400000002001d000000400200043d00000b650020009c000021930000813d0000004003200039000000400030043f00000020032000390000000000030435000000000002043500000a4001100197000200000001001d000000000010043f00000b4701000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000021990000613d000000400300043d000000000101043b000000000101041a000000000001004b0000219b0000613d00000b2c0030009c000021930000213d000000a002300039000000400020043f00000060023000390000000304000029000000000042043500000040043000390000000405000029000000000054043500000020053000390000000000150435000000020100002900000000001304350000008001300039000000000001043500000b6606000041000000400900043d0000000006690436000100000006001d000000040690003900000040070000390000000000760435000000000303043300000a40033001970000004406900039000000000036043500000000030504330000006405900039000000000035043500000000030404330000008404900039000000a0050000390000000000540435000000e404900039000000003503043400000000005404350000010404900039000000000005004b000021150000613d000000000600001900000000074600190000000008630019000000000808043300000000008704350000002006600039000000000056004b0000210e0000413d0000000003000410000000000645001900000000000604350000001f0550003900000b60055001970000000002020433000000a406900039000000c0075000390000000000760435000000000445001900000000280204340000000007840436000000000008004b0000212b0000613d000000000400001900000000057400190000000006420019000000000606043300000000006504350000002004400039000000000084004b000021240000413d00000000027800190000000000020435000000000101043300000a430230019700000024039000390000000000230435000000c402900039000000000001004b0000000001000039000000010100c039000000000012043500000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c70000800502000039000400000009001d000300000007001d000200000008001d28fd28f80000040f0000000100200190000021a50000613d00000002020000290000001f0220003900000b600220019700000004040000290000000303400069000000000223001900000a400020009c00000a4002008041000000600220021000000a400040009c00000a400300004100000000030440190000004003300210000000000232019f000000000301043b000000000100041400000a400010009c00000a4001008041000000c001100210000000000121019f00000a430230019728fd28f80000040f000000600310027000000a4003300197000000400030008c000000400400003900000000040340190000001f0640018f0000006007400190000000040b00002900000000057b00190000216d0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000021690000c13d000000000006004b0000217a0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000021a60000613d0000001f01400039000000e00210018f0000000001b20019000000000021004b0000000002000039000000010200403900000a460010009c000021930000213d0000000100200190000021930000c13d000000400010043f000000400030008c000021990000413d00000ae20010009c000021930000213d0000004002100039000000400020043f00000000020b04330000000002210436000000010300002900000000030304330000000000320435000000000001042d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff0001043000000b5a01000041000000000013043500000004013000390000000202000029000000000021043500000a400030009c00000a4003008041000000400130021000000ac8011001c7000028ff00010430000000000001042f0000001f0530018f00000a4206300198000000400200043d0000000004620019000021b10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000021ad0000c13d000000000005004b000021be0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000000a400020009c00000a40020080410000004002200210000000000112019f000028ff000104300003000000000002000200000003001d000300000002001d00000a4301100197000100000001001d000000000010043f00000ac601000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000001002001900000220e0000613d000000000101043b000000030200002900000a4302200197000300000002001d000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000001002001900000220e0000613d000000000101043b000000000101041a00000b610010009c0000220d0000613d0000000204000029000000000341004b000022100000413d0000000102000029000000000002004b0000221f0000613d000200000003001d000000030000006b000022220000613d000000000020043f00000ac601000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000001002001900000220e0000613d000000000101043b0000000302000029000000000020043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000001002001900000220e0000613d000000000101043b0000000202000029000000000021041b000000000001042d0000000001000019000028ff00010430000000400200043d000000440320003900000000004304350000002403200039000000000013043500000b6701000041000000000012043500000004012000390000000303000029000000000031043500000a400020009c00000a4002008041000000400120021000000b68011001c7000028ff00010430000000400100043d00000aca02000041000022240000013d000000400100043d00000b580200004100000000002104350000000402100039000000000002043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff000104300005000000000002000300000003001d00050a430010019c000022bb0000613d00000a4303200198000022be0000613d00000ad301000041000000000101041a00000ad402000041000000000202041a000000000012001a000022d00000413d000000000112001900000ad502000041000000000202041a0000000005120019000000000025004b00000000010000390000000101004039000000010010008c000022d00000613d000000000005004b000022b80000613d00000ad201000041000000000101041a000000000001004b0000224a0000613d00000b6102100129000000030020006c000022b60000413d00000003011000b9000000000015004b000022b80000213d000100000001001d000200000005001d000000050030006b000022c80000613d0000000001000410000000000013004b000022c80000613d0000000501000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c70000801002000039000400000003001d28fd28f80000040f00000001002001900000000202000029000022b60000613d0002000100200101000000000101043b000000000101041a000000020110006c000100000001001d000022b80000413d0000000501000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000004030000290000000100200190000022b60000613d000000000101043b0000000102000029000000000021041b000000000030043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000022b60000613d000000000101043b000000000201041a0000000203000029000000000032001a000022d00000413d0000000002320019000000000021041b000000400100043d0000000302000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000030300003900000b69040000410000000505000029000000040600002928fd28f30000040f00000004060000290000000100200190000022b60000613d000000400100043d0000000202000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000030300003900000b6a04000041000000050500002928fd28f30000040f0000000100200190000022b60000613d000000000001042d0000000001000019000028ff00010430000000400100043d00000ae402000041000022ca0000013d000000400100043d00000b6c02000041000022c00000013d000000400100043d00000b6b0200004100000000002104350000000402100039000000000002043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff00010430000000400100043d00000b5902000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff0001043000000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff00010430000000400200043d00000a4301100198000022ef0000613d00000ac003000041000000000403041a00000afc04400197000000000414019f000000000043041b000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b1d0400004128fd28f30000040f0000000100200190000022f60000613d000000000001042d00000ae501000041000000000012043500000a400020009c00000a4002008041000000400120021000000abf011001c7000028ff000104300000000001000019000028ff000104300001000000000002000100000001001d00000a4301100197000000000010043f00000b3c01000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000023130000613d000000000101043b000000000101041a000000ff011001900000230c0000613d000000000001042d00000ae801000041000000000101041a000000010110014f00000a430010019800000000010000390000000101006039000000000001042d0000000001000019000028ff00010430000400000000000200000a4304100198000023590000613d00000a4302200198000023590000613d000400000003001d000000000024004b0000235c0000613d0000000001000410000000000012004b0000235c0000613d000200000002001d000300000004001d000000000040043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000023570000613d000000000101043b000000000101041a00010004001000740000235f0000413d0000000301000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000023570000613d000000000101043b0000000102000029000000000021041b0000000201000029000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000023570000613d000000000101043b000000000201041a0000000403000029000000000032001a000023670000413d0000000002320019000000000021041b000000000001042d0000000001000019000028ff00010430000000400100043d00000ae502000041000023610000013d000000400100043d00000b5902000041000023610000013d000000400100043d00000ae402000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff0001043000000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff000104300003000000000002000100000004001d000000400400043d000000000034043500000a400040009c00000a40040080410000004003400210000000000400041400000a400040009c00000a4004008041000000c004400210000000000334019f00000a47043001c700000a430510019700000a43062001970000800d020000390000000303000039000000000104001900000b6904000041000300000005001d000200000006001d28fd28f30000040f00000001002001900000239a0000613d000000400100043d0000000102000029000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000030300003900000b6a040000410000000305000029000000020600002928fd28f30000040f00000001002001900000239a0000613d000000000001042d0000000001000019000028ff0001043000000a430110019700000abb02000041000000000302041a00000afc03300197000000000313019f000000000032041b000000400200043d000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b1f0400004128fd28f30000040f0000000100200190000023b40000613d000000000001042d0000000001000019000028ff00010430000000400200043d00000a4301100198000023cf0000613d00000ad603000041000000000403041a00000afc04400197000000000414019f000000000043041b000000000012043500000a400020009c00000a40020080410000004001200210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000010300003900000b1e0400004128fd28f30000040f0000000100200190000023d60000613d000000000001042d00000ae501000041000000000012043500000a400020009c00000a4002008041000000400120021000000abf011001c7000028ff000104300000000001000019000028ff0001043000000a4301100198000023e00000613d00000b1c02000041000000000302041a00000afc03300197000000000113019f000000000012041b000000000001042d000000400100043d00000ae502000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff000104300009000000000002000800000005001d000600000003001d000700000002001d000900000001001d000000400100043d00000b5b0010009c000025b00000813d0000006002100039000000400020043f000000200210003900000000000204350000000000010435000000400200043d00000ae20020009c000025b00000213d0000004003200039000000400030043f0000002003200039000000000003043500000000000204350000004001100039000000000021043500000000320404340000000001000416000500000002001d000000000021004b000025b90000c13d000400000003001d0000000001030433000000000001004b000024d20000613d000200000001001d00000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c7000080050200003928fd28f80000040f0000000100200190000025b80000613d000000000201043b000000400300043d000300000003001d00000b6e01000041000000000013043500000a400030009c00000a400100004100000000010340190000004001100210000000000300041400000a400030009c00000a4003008041000000c003300210000000000113019f00000abf011001c700000a4302200197000100000002001d28fd28f80000040f000000030b000029000000600310027000000a4003300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000024390000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000024350000c13d000000000006004b000024460000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000025eb0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000a460010009c000025b00000213d0000000100200190000025b00000c13d000000400010043f000000200030008c000025b60000413d00000000020b043300000b6f0020009c000025b60000813d000000000002004b000026090000613d000000640310003900000002040000290000000000430435000000440310003900000001040000290000000000430435000000200510003900000b70030000410000000000350435000000000300041100000a4303300197000000240410003900000000003404350000006403000039000000000031043500000b2c0010009c000025b00000213d000000a003100039000000400030043f00000a400050009c00000a40050080410000004003500210000000000101043300000a400010009c00000a40010080410000006001100210000000000131019f000000000300041400000a400030009c00000a4003008041000000c003300210000000000131019f000300000002001d28fd28f30000040f000000600310027000000a4003300198000024a70000613d0000001f0430003900000a41044001970000003f0440003900000b7104400197000000400b00043d00000000044b00190000000000b4004b0000000005000039000000010500403900000a460040009c0000000309000029000025b00000213d0000000100500190000025b00000c13d000000400040043f0000001f0430018f000000000a3b043600000a420530019800000000035a0019000024990000613d000000000601034f00000000070a0019000000006806043c0000000007870436000000000037004b000024950000c13d000000000004004b000024aa0000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000024aa0000013d000000600b000039000000800a000039000000030900002900000000010b043300000001002001900000260b0000613d000000000001004b000024c60000c13d00020000000b001d00010000000a001d00000acf0100004100000000001004430000000400900443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f0000000100200190000025b80000613d000000000101043b000000000001004b0000000201000029000026230000613d0000000001010433000000000001004b0000000309000029000000010a000029000024d20000613d00000b630010009c000025b60000213d000000200010008c000025b60000413d00000000010a0433000000000001004b0000000002000039000000010200c039000000000021004b000025b60000c13d000000000001004b000026150000613d000000090100002900000a4001100197000900000001001d000000000010043f00000b4701000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f0000000100200190000025b60000613d000000400300043d000000000101043b000000000401041a000000000004004b000025c30000613d00000b2c0030009c000025b00000213d00000004010000290000000001010433000000a002300039000000400020043f000000000001004b0000000002000039000000010200c03900000080013000390000000000210435000000600230003900000006050000290000000000520435000000400530003900000007060000290000000000650435000000200630003900000000004604350000000904000029000000000043043500000b7604000041000000400900043d0000000004490436000600000004001d000000040490003900000040070000390000000000740435000000000303043300000a40033001970000004404900039000000000034043500000000030604330000006404900039000000000034043500000000030504330000008404900039000000a0050000390000000000540435000000e406900039000000005403043400000000004604350000010403900039000000000004004b0000251b0000613d000000000600001900000000073600190000000008650019000000000808043300000000008704350000002006600039000000000046004b000025140000413d000000000534001900000000000504350000001f0440003900000b60044001970000000002020433000000a405900039000000c0064000390000000000650435000000000334001900000000270204340000000006730436000000000007004b000025300000613d000000000300001900000000046300190000000005320019000000000505043300000000005404350000002003300039000000000073004b000025290000413d000000000267001900000000000204350000000001010433000000080200002900000a430220019700000024039000390000000000230435000000c402900039000000000001004b0000000001000039000000010100c039000000000012043500000add010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400000a400010009c00000a4001008041000000c00110021000000ade011001c70000800502000039000900000009001d000800000006001d000700000007001d28fd28f80000040f0000000100200190000025b80000613d00000007020000290000001f0220003900000b600220019700000009040000290000000803400069000000000223001900000a400020009c00000a4002008041000000600220021000000a400040009c00000a400300004100000000030440190000004003300210000000000232019f000000000301043b000000000100041400000a400010009c00000a4001008041000000c001100210000000000121019f00000a43043001970000000503000029000000000003004b000025690000613d00000af2011001c7000080090200003900000000050000190000256a0000013d000000000204001928fd28f30000040f000000600310027000000a4003300197000000800030008c000000800400003900000000040340190000001f0640018f000000e007400190000000090b00002900000000057b00190000257b0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000025770000c13d000000000006004b000025880000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000025cd0000613d0000001f01400039000001e00210018f0000000001b20019000000000021004b0000000002000039000000010200403900000a460010009c000025b00000213d0000000100200190000025b00000c13d000000400010043f000000800030008c000025b60000413d00000b2b0010009c000025b00000213d0000006002100039000000400020043f00000000020b043300000000022104360000000603000029000000000303043300000a460030009c000025b60000213d0000000000320435000000400200043d00000ae20020009c000025b00000213d0000004003200039000000400030043f0000004003b00039000000000303043300000000033204360000006004b000390000000004040433000000000043043500000040031000390000000000230435000000000001042d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff00010430000000000001042f000000400200043d00000b6d0300004100000000003204350000000403200039000000000013043500000a400020009c00000a4002008041000000400120021000000ac8011001c7000028ff0001043000000b5a01000041000000000013043500000004013000390000000902000029000000000021043500000a400030009c00000a4003008041000000400130021000000ac8011001c7000028ff000104300000001f0530018f00000a4206300198000000400200043d0000000004620019000025d80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000025d40000c13d000000000005004b000025e50000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000000a400020009c00000a40020080410000004002200210000000000121019f000028ff000104300000001f0530018f00000a4206300198000000400200043d0000000004620019000025f60000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000025f20000c13d000000000005004b000026030000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000000a400020009c00000a40020080410000004002200210000000000112019f000028ff0001043000000b75020000410000260f0000013d000000000001004b0000261b0000c13d000000400100043d00000b7202000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff00010430000000400100043d00000b7302000041000000000021043500000004021000390000000000920435000026290000013d00000a4000a0009c00000a400a0080410000004002a0021000000a400010009c00000a40010080410000006001100210000000000121019f000028ff00010430000000400100043d00000b7402000041000000000021043500000004021000390000000303000029000000000032043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff00010430000300000000000200000a4301100198000026670000613d000200000003001d00030a430020019c0000266a0000613d000100000001001d000000000010043f00000ac601000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000001002001900000000303000029000026650000613d000000000101043b000000000030043f000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000003060000290000000100200190000026650000613d000000000101043b0000000202000029000000000021041b000000400100043d000000000021043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000a47011001c70000800d02000039000000030300003900000b7704000041000000010500002928fd28f30000040f0000000100200190000026650000613d000000000001042d0000000001000019000028ff00010430000000400100043d00000aca020000410000266c0000013d000000400100043d00000b580200004100000000002104350000000402100039000000000002043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff00010430000200000000000200000b1201000041000000000401041a000000010540019000000001024002700000007f0220618f0000001f0020008c00000000010000390000000101002039000000000015004b000027490000c13d000000400300043d0000000001230436000000000005004b000026910000613d00000b1204000041000000000040043f000000000002004b000026970000613d00000b140500004100000000040000190000000006140019000000000705041a000000000076043500000001055000390000002004400039000000000024004b000026890000413d000026980000013d00000b5f044001970000000000410435000000000002004b00000020040000390000000004006039000026980000013d00000000040000190000003f02400039000000200900008a000000000492016f0000000002340019000000000042004b0000000004000039000000010400403900000a460020009c000027410000213d0000000100400190000027410000c13d000000400020043f0000000003030433000000000003004b000026bc0000613d00000a400010009c00000a4001008041000000400110021000000a400030009c00000a40030080410000006002300210000000000112019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af2011001c7000080100200003928fd28f80000040f0000000100200190000027470000613d000000400200043d000000000801043b000000200900008a000026c00000013d00000b1a01000041000000000801041a000000000008004b00000b780800604100000b1601000041000000000401041a000000010540019000000001034002700000007f0330618f0000001f0030008c00000000010000390000000101002039000000000114013f0000000100100190000027490000c13d0000000001320436000000000005004b000026dc0000613d00000b1604000041000000000040043f000000000003004b000026e20000613d00000b180500004100000000040000190000000006140019000000000705041a000000000076043500000001055000390000002004400039000000000034004b000026d40000413d000026e30000013d00000b5f044001970000000000410435000000000003004b00000020040000390000000004006039000026e30000013d00000000040000190000003f03400039000000000393016f0000000004230019000000000034004b0000000003000039000000010300403900000a460040009c000027410000213d0000000100300190000027410000c13d000000400040043f0000000002020433000000000002004b000027070000613d000200000008001d00000a400010009c00000a4001008041000000400110021000000a400020009c00000a40020080410000006002200210000000000112019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af2011001c7000080100200003928fd28f80000040f0000000100200190000027470000613d000000400400043d000000000101043b00000002080000290000270b0000013d00000b1b01000041000000000101041a000000000001004b00000b7801006041000200000004001d0000006002400039000000000012043500000040014000390000000000810435000000200240003900000b7901000041000100000002001d000000000012043500000b3b010000410000000000100443000000000100041400000a400010009c00000a4001008041000000c00110021000000aee011001c70000800b0200003928fd28f80000040f00000001002001900000274f0000613d000000000101043b0000000204000029000000a0024000390000000003000410000000000032043500000080024000390000000000120435000000a001000039000000000014043500000b2f0040009c000027410000213d000000c001400039000000400010043f000000010100002900000a400010009c00000a40010080410000004001100210000000000204043300000a400020009c00000a40020080410000006002200210000000000112019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af2011001c7000080100200003928fd28f80000040f0000000100200190000027470000613d000000000101043b000000000001042d00000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff000104300000000001000019000028ff0001043000000b5501000041000000000010043f0000002201000039000000040010043f00000ac801000041000028ff00010430000000000001042f0003000000000002000000400500043d0000006406500039000000000046043500000a430330019700000044045000390000000000340435000000200350003900000b7004000041000000000043043500000a4302200197000000240450003900000000002404350000006402000039000000000025043500000b640050009c000027cb0000813d000000a002500039000000400020043f00000a400030009c00000a40030080410000004002300210000000000305043300000a400030009c00000a40030080410000006003300210000000000223019f000000000300041400000a400030009c00000a4003008041000000c003300210000000000332019f00000a43021001970000000001030019000300000002001d28fd28f30000040f000000600310027000000a40033001980000279e0000613d0000001f0430003900000a41044001970000003f0440003900000b7104400197000000400a00043d00000000044a00190000000000a4004b0000000005000039000000010500403900000a460040009c000027cb0000213d0000000100500190000027cb0000c13d000000400040043f0000001f0430018f00000000093a043600000a42053001980000000003590019000027900000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000037004b0000278c0000c13d000000000004004b000027a00000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000027a00000013d000000600a000039000000800900003900000000010a04330000000100200190000027d10000613d000000000001004b000027bc0000c13d00020000000a001d000100000009001d00000acf01000041000000000010044300000003010000290000000400100443000000000100041400000a400010009c00000a4001008041000000c00110021000000ad0011001c7000080020200003928fd28f80000040f0000000100200190000027e60000613d000000000101043b000000000001004b0000000201000029000027e70000613d0000000001010433000000000001004b0000000109000029000027c80000613d00000b630010009c000027c90000213d0000001f0010008c000027c90000a13d0000000001090433000000000001004b0000000002000039000000010200c039000000000021004b000027c90000c13d000000000001004b000027db0000613d000000000001042d0000000001000019000028ff0001043000000b5501000041000000000010043f0000004101000039000000040010043f00000ac801000041000028ff00010430000000000001004b000027de0000c13d000000400100043d00000b7202000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff00010430000000400100043d00000b7302000041000027e90000013d00000a400090009c00000a4009008041000000400290021000000a400010009c00000a40010080410000006001100210000000000121019f000028ff00010430000000000001042f000000400100043d00000b7402000041000000000021043500000004021000390000000303000029000000000032043500000a400010009c00000a4001008041000000400110021000000ac8011001c7000028ff000104300006000000000002000600000003001d000400000001001d00000b3e01000041000000000301041a000000000023004b000028020000813d000000000003004b000028000000613d00000b610320012900000ad304000041000000000404041a000000000043004b000028af0000413d00000b3e03000041000000000023041b00000ad202000041000000000202041a000000000002004b00000006040000290000281f0000613d00000ad303000041000000000303041a00000ad404000041000000000404041a000000000034001a000028b90000413d000000000334001900000ad504000041000000000404041a0000000003340019000000000043004b00000000040000390000000104004039000000010040008c000028b90000613d000000000003004b0000281e0000613d00000b6104200129000000060040006c000028af0000413d00000006042000b900000000043400d90000281f0000013d000000000400001900000aec03000041000000000303041a000000000003004b0000285f0000613d00000b6101300129000000000014004b000028af0000213d00000b1c01000041000000000101041a00000a4305100198000028b10000613d00000000014300a900000b510310012a000000000023001a000028b90000413d000000000123001900000ad202000041000000000012041b000200000005001d000000000050043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c70000801002000039000500000004001d000300000003001d28fd28f80000040f0000000100200190000028af0000613d000000000101043b000000000101041a000100000001001d000000030010002a0000000201000029000028b90000413d000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000005040000290000000100200190000028af0000613d00000003030000290000000102300029000000000101043b000000000021041b00000b3201000041000000000201041a000000000032001a000028b90000413d0000000002320019000000000021041b000000000434004b000028b90000413d000000040100002900000a4303100198000028b10000613d00000ad201000041000000000201041a000000000042001a000028b90000413d0000000002420019000000000021041b000400000003001d000000000030043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c70000801002000039000500000004001d28fd28f80000040f00000005030000290000000100200190000028af0000613d000000000101043b000000000101041a000300000001001d000000000031001a0000000401000029000028b90000413d000000000010043f00000ad901000041000000200010043f000000000100041400000a400010009c00000a4001008041000000c00110021000000ab9011001c7000080100200003928fd28f80000040f00000005040000290000000100200190000028af0000613d0000000302400029000000000101043b000000000021041b00000b3201000041000000000201041a000000000042001a0000000405000029000028b90000413d0000000002420019000000000021041b00000ad401000041000000000201041a000000060020002a000028b90000413d00000006030000290000000002320019000000000021041b000000400100043d00000020021000390000000000320435000000000041043500000a400010009c00000a40010080410000004001100210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000ab9011001c70000800d02000039000000020300003900000b7a0400004128fd28f30000040f0000000100200190000028af0000613d000000000001042d0000000001000019000028ff00010430000000400100043d00000ae502000041000000000021043500000a400010009c00000a4001008041000000400110021000000abf011001c7000028ff0001043000000b5501000041000000000010043f0000001101000039000000040010043f00000ac801000041000028ff00010430000000000001042f00000a400010009c00000a4001008041000000400110021000000a400020009c00000a40020080410000006002200210000000000112019f000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000af2011001c7000080100200003928fd28f80000040f0000000100200190000028d30000613d000000000101043b000000000001042d0000000001000019000028ff0001043000000000050100190000000000200443000000050030008c000028e30000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b000028db0000413d00000a400030009c00000a40030080410000006001300210000000000200041400000a400020009c00000a4002008041000000c002200210000000000112019f00000b7b011001c7000000000205001928fd28f80000040f0000000100200190000028f20000613d000000000101043b000000000001042d000000000001042f000028f6002104210000000102000039000000000001042d0000000002000019000000000001042d000028fb002104230000000102000039000000000001042d0000000002000019000000000001042d000028fd00000432000028fe0001042e000028ff0001043000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000fffffffffffffffffffffffffffffffffffffffff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff0200000000000000000000000000000000000020000000000000000000000000c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d200000002000000000000000000000000000000c0000001000000000000000000000000000000000000000000000000000000000000000000000000007ecebdff00000000000000000000000000000000000000000000000000000000bb0b6a5200000000000000000000000000000000000000000000000000000000dd62ed3d00000000000000000000000000000000000000000000000000000000f2fde38a00000000000000000000000000000000000000000000000000000000f5eb42db00000000000000000000000000000000000000000000000000000000f5eb42dc00000000000000000000000000000000000000000000000000000000fe41e52400000000000000000000000000000000000000000000000000000000ff7bd03d00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000f37e8d3800000000000000000000000000000000000000000000000000000000ebfd66e700000000000000000000000000000000000000000000000000000000ebfd66e800000000000000000000000000000000000000000000000000000000f018d7c000000000000000000000000000000000000000000000000000000000f0f4426000000000000000000000000000000000000000000000000000000000dd62ed3e00000000000000000000000000000000000000000000000000000000e4e4856000000000000000000000000000000000000000000000000000000000ca5eb5e000000000000000000000000000000000000000000000000000000000d038c4a800000000000000000000000000000000000000000000000000000000d038c4a900000000000000000000000000000000000000000000000000000000d5002f2e00000000000000000000000000000000000000000000000000000000d505accf00000000000000000000000000000000000000000000000000000000ca5eb5e100000000000000000000000000000000000000000000000000000000cae791ed00000000000000000000000000000000000000000000000000000000bf5eb2bc00000000000000000000000000000000000000000000000000000000bf5eb2bd00000000000000000000000000000000000000000000000000000000c6e6f59200000000000000000000000000000000000000000000000000000000bb0b6a5300000000000000000000000000000000000000000000000000000000bc70b3540000000000000000000000000000000000000000000000000000000098aca92100000000000000000000000000000000000000000000000000000000b3b4084400000000000000000000000000000000000000000000000000000000b5f3a12700000000000000000000000000000000000000000000000000000000b5f3a12800000000000000000000000000000000000000000000000000000000b92d0eff00000000000000000000000000000000000000000000000000000000b98bd07000000000000000000000000000000000000000000000000000000000b3b4084500000000000000000000000000000000000000000000000000000000b5d2074b00000000000000000000000000000000000000000000000000000000a8edcb8b00000000000000000000000000000000000000000000000000000000a8edcb8c00000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000ab88ecb20000000000000000000000000000000000000000000000000000000098aca92200000000000000000000000000000000000000000000000000000000a38097680000000000000000000000000000000000000000000000000000000084b0196d000000000000000000000000000000000000000000000000000000008fcb4e5a000000000000000000000000000000000000000000000000000000008fcb4e5b000000000000000000000000000000000000000000000000000000009388bd520000000000000000000000000000000000000000000000000000000095d89b410000000000000000000000000000000000000000000000000000000084b0196e000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000817b1cd100000000000000000000000000000000000000000000000000000000817b1cd2000000000000000000000000000000000000000000000000000000008456cb59000000000000000000000000000000000000000000000000000000007ecebe00000000000000000000000000000000000000000000000000000000007edddbb2000000000000000000000000000000000000000000000000000000005535d46000000000000000000000000000000000000000000000000000000000715018a5000000000000000000000000000000000000000000000000000000007bb4ec30000000000000000000000000000000000000000000000000000000007d00a54e000000000000000000000000000000000000000000000000000000007d00a54f000000000000000000000000000000000000000000000000000000007d25a05e000000000000000000000000000000000000000000000000000000007e071776000000000000000000000000000000000000000000000000000000007bb4ec31000000000000000000000000000000000000000000000000000000007be98ea30000000000000000000000000000000000000000000000000000000073334d5a0000000000000000000000000000000000000000000000000000000073334d5b0000000000000000000000000000000000000000000000000000000075b24ebe00000000000000000000000000000000000000000000000000000000779c9ad800000000000000000000000000000000000000000000000000000000715018a600000000000000000000000000000000000000000000000000000000718da7ee0000000000000000000000000000000000000000000000000000000066285966000000000000000000000000000000000000000000000000000000006d780458000000000000000000000000000000000000000000000000000000006d780459000000000000000000000000000000000000000000000000000000006daf72840000000000000000000000000000000000000000000000000000000070a0823100000000000000000000000000000000000000000000000000000000662859670000000000000000000000000000000000000000000000000000000067700b99000000000000000000000000000000000000000000000000000000005e280f10000000000000000000000000000000000000000000000000000000005e280f110000000000000000000000000000000000000000000000000000000061d027b3000000000000000000000000000000000000000000000000000000005535d461000000000000000000000000000000000000000000000000000000005c975abb0000000000000000000000000000000000000000000000000000000017442b6f00000000000000000000000000000000000000000000000000000000313ce566000000000000000000000000000000000000000000000000000000003644e514000000000000000000000000000000000000000000000000000000003644e515000000000000000000000000000000000000000000000000000000003f4ba83a00000000000000000000000000000000000000000000000000000000489641cc00000000000000000000000000000000000000000000000000000000313ce567000000000000000000000000000000000000000000000000000000003400288b000000000000000000000000000000000000000000000000000000001c5aaf8a000000000000000000000000000000000000000000000000000000001c5aaf8b0000000000000000000000000000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000293e2fb50000000000000000000000000000000000000000000000000000000017442b700000000000000000000000000000000000000000000000000000000018160ddd00000000000000000000000000000000000000000000000000000000095ea7b200000000000000000000000000000000000000000000000000000000121c55ec00000000000000000000000000000000000000000000000000000000121c55ed0000000000000000000000000000000000000000000000000000000013137d650000000000000000000000000000000000000000000000000000000013ff7e9f00000000000000000000000000000000000000000000000000000000095ea7b3000000000000000000000000000000000000000000000000000000000a28a4770000000000000000000000000000000000000000000000000000000006fdde020000000000000000000000000000000000000000000000000000000006fdde0300000000000000000000000000000000000000000000000000000000076a09f70000000000000000000000000000000000000000000000000000000001e1d1140000000000000000000000000000000000000000000000000000000003e7467500000000000000000000000000000000000000200000000000000000000000009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300c064a301e926254981c9bd3b3225923d097271573deb3cc61ae7f6a144f10a030200000000000000000000000000000000000040000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeec064a301e926254981c9bd3b3225923d097271573deb3cc61ae7f6a144f10a02ca706bcf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000006a43f8d1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000c064a301e926254981c9bd3b3225923d097271573deb3cc61ae7f6a144f10a00312ddf7d0000000000000000000000000000000000000000000000000000000090890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15cae33fc2000000000000000000000000000000000000000000000000000000004105f5e700000000000000000000000000000000000000000000000000000000dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910e52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace01ea598cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000e602df05000000000000000000000000000000000000000000000000000000000bc48bc300000000000000000000000000000000000000000000000000000000e52970aa00000000000000000000000000000000000000000000000000000000d93c06650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000008000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8302000002000000000000000000000000000000240000000000000000000000001e4ec46b00000000000000000000000000000000000000000000000000000000ddf967707f52bbdea6c202114c491d81e6de0cb9ded430e88a276a6f8d3e3800dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09100dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09102dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09103c064a301e926254981c9bd3b3225923d097271573deb3cc61ae7f6a144f10a017c134b5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000ddf967707f52bbdea6c202114c491d81e6de0cb9ded430e88a276a6f8d3e380102000000000000000000000000000000000000600000000000000000000000008b2a1e1ad5e0578c3dd82494156e985dade827a87c573b5c1c7716a32162ad64000000000000000000000000000000000000000000000000ffffffffffffff7f310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09108dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09109dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910a000000000000000000000000000000000000000000000000ffffffffffffffbf6c3a45613039e0a1117bd6ce110ab3c920271709c010983d921a2cd268e2ea472c5211c600000000000000000000000000000000000000000000000000000000d92e233d000000000000000000000000000000000000000000000000000000001f2a2005000000000000000000000000000000000000000000000000000000003ee5aeb5000000000000000000000000000000000000000000000000000000009016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300118cdaa70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000008000000000000000000000000000000000000000000000000000000000000000000000000000030d40dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb09106796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913202000002000000000000000000000000000000040000000000000000000000005ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9000000000000000000000000000000000000000000000000ffffffffffffff1f0200000000000000000000000000000000000000000000000000000000000000190100000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000420000000000000000000000007fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a000000000000000000000000000000000000000800000000000000000000000004b800e4600000000000000000000000000000000000000000000000000000000f645eedf00000000000000000000000000000000000000000000000000000000d78bce0c0000000000000000000000000000000000000000000000000000000062791302000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000800000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000ef31c3aa06f1248be5c6b6e1e2d20eadd1a9b8ba067380b4a303ef49f9a489acca5eb5e1000000000000000000000000000000000000000000000000000000008d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00009a6d49cd00000000000000000000000000000000000000000000000000000000ffff00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000be4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000100000000000000018be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03d51f7571d6dac09653a26865efe6a95470726282129c05857c4e903b89b715502ae08a8e29253f69ac5d979a101956ab8f8d9d7ded63fa7a83b16fc47648eab0d51f7571d6dac09653a26865efe6a95470726282129c05857c4e903b89b7154f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace04b95d7fc1a65b21b185b3a8b4edbc0da68853b3882a5e5b59f64ac6b3144b5d5646a2803e59a4de4e7a4c574b1243f25977ac4c77d5a1a4a609b5394cebb4a2aab95d7fc1a65b21b185b3a8b4edbc0da68853b3882a5e5b59f64ac6b3144b5d553100000000000000000000000000000000000000000000000000000000000000a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102bd52a2c1e0d1918f12309266e475cfdc2c0357fb85ecea6d0612460264762a8342ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57dbd52a2c1e0d1918f12309266e475cfdc2c0357fb85ecea6d0612460264762a82a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d103a0631cb7ea071eebce38448a571977956eb8708003e244f56723dbf02228948b5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b75a0631cb7ea071eebce38448a571977956eb8708003e244f56723dbf02228948aa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d101dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb091074a0f73c7c1971268d36d35f4aa566bc6bf4d11a95048a36db084492132ab6f743881bcae1b79d28312da310a8d211e93a9d6ea5a30e04f43bca54b0768e5b3e756586991759b0dd92948599d3a023e9ba12504fa867fbc532ba4e1d2502a6f262d365d82646798ae645c4baa2dc2ee228626f61d8b5395bf298ba125a3c6b100af53bfd91676a5f7c3d8a2bcd6a9df83b50bde13a00670e3db6a6cefa04823bc487698e326934c06370ca3c28e3bca79fe27d578048e9d42af7fa98f2e481e00b68fd1a788a85f8f18de7976d851969ff9ff2216de81169c17a6f4ac94c23defffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffd7e6bcf800000000000000000000000000000000000000000000000000000000b5863604000000000000000000000000000000000000000000000000000000001e4fbdf700000000000000000000000000000000000000000000000000000000f92ee8a900000000000000000000000000000000000000000000000000000000c064a301e926254981c9bd3b3225923d097271573deb3cc61ae7f6a144f10a04f10fc780c78f994a214c79a2ae8d8b7bfe7cc3f0f935a8f05a29525e71d7f127000000000000000000000000000000000000000000000000ffffffffffffff9f000000000000000000000000000000000000000000000000ffffffffffffff5fdd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910b416ecebf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff3f3a69197e0000000000000000000000000000000000000000000000000000000084bc3eb000000000000000000000000000000000000000000000000000000000dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb091040000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000080000000000000000094ba8d5f7922370aad18b707619f668a8fd07cbdf364eeaa6a048e737c9f2a8208c379a0000000000000000000000000000000000000000000000000000000004549503731323a20556e696e697469616c697a656400000000000000000000000000000000000000000000000000000000000064000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf0f000000000000000000000000000000000000000000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670bdd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910d62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910196a88a019b24fd6b65f34b2d2145e4c74f774e5ef02b2b85180a51fae1918a580000000000000000000000000000000000000000000000000000000000030d41dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910558d620b3000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000020000000800000000000000000d9933b26b990ffbd85af14fd2796031d934c55d6148174e62f05a912a837f9ed5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa8dfc202b0000000000000000000000000000000000000000000000000000000072ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f900238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b00000000000000000000000000000000000000a000000000000000000000000091ac5e4f00000000000000000000000000000000000000000000000000000000c26bebcc00000000000000000000000000000000000000000000000000000000dd932cf12f0dd29482349e8f041f211cd1a01e556f17b4835472bd462fb0910c756688fe00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000004080000000000000000000000000000000000000000000000000000000000000a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000f42400200000000000000000000000000000000000080000000000000000000000000d36e76ee550c32ed4f6b9d679dd357f6eece52b7634554661fcd8d02eebfb6646849bd31a1772b1b6992f1f328cce6888b435faff25d13805baee12a8a944bbe4e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000007cb590120000000000000000000000000000000000000000000000000000000094280d62000000000000000000000000000000000000000000000000000000003d693ada00000000000000000000000000000000000000000000000000000000f6ff4fb700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffa05bf93781000000000000000000000000000000000000000000000000000000007e5f9349000000000000000000000000000000000000000000000000000000005c427cd900000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffff60000000000000000000000000000000000000000000000000ffffffffffffffc0ddc28c5800000000000000000000000000000000000000000000000000000000fb8f41b2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcbec442f050000000000000000000000000000000000000000000000000000000096c6fd1e000000000000000000000000000000000000000000000000000000009f70412000000000000000000000000000000000000000000000000000000000e4fe1d9400000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000023b872dd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffe01425ea42000000000000000000000000000000000000000000000000000000005274afe7000000000000000000000000000000000000000000000000000000009996b315000000000000000000000000000000000000000000000000000000005373352a000000000000000000000000000000000000000000000000000000002637a450000000000000000000000000000000000000000000000000000000008c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f0200000200000000000000000000000000000000000000000000000000000000d3fd81a241ed1a61a6b8479304e83088dbed5066b2f866e7f9318f57203c7397

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000005c6cff4b7c49805f8295ff73c204ac83f3bc4ae70000000000000000000000000000000000000000000000000000000000007595

-----Decoded View---------------
Arg [0] : _endpoint (address): 0x5c6cfF4b7C49805F8295Ff73C204ac83f3bC4AE7
Arg [1] : _srcEid (uint32): 30101

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c6cff4b7c49805f8295ff73c204ac83f3bc4ae7
Arg [1] : 0000000000000000000000000000000000000000000000000000000000007595


Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.