ETH Price: $3,988.11 (+2.99%)

Contract

0x66D79B8f60ec93Bfce0b56F5Ac14A2714E509a99
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

TokenTracker

MAP Protocol (MAPO) (@$0.0121)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer213416712024-12-06 6:30:1127 hrs ago1733466611IN
MAP Protocol: MAPO Token
0 ETH0.0006428613.77047854
Transfer213358722024-12-05 11:03:1146 hrs ago1733396591IN
MAP Protocol: MAPO Token
0 ETH0.0011783522.88773423
Transfer213290542024-12-04 12:11:592 days ago1733314319IN
MAP Protocol: MAPO Token
0 ETH0.0006873223.24237431
Transfer213286152024-12-04 10:43:352 days ago1733309015IN
MAP Protocol: MAPO Token
0 ETH0.0010865321.10931763
Approve213203372024-12-03 6:58:234 days ago1733209103IN
MAP Protocol: MAPO Token
0 ETH0.0010909523.53023294
Transfer213203172024-12-03 6:54:234 days ago1733208863IN
MAP Protocol: MAPO Token
0 ETH0.0009370918.20593329
Approve213202182024-12-03 6:34:354 days ago1733207675IN
MAP Protocol: MAPO Token
0 ETH0.0009718120.95515821
Approve213200492024-12-03 6:00:354 days ago1733205635IN
MAP Protocol: MAPO Token
0 ETH0.0008033117.31724639
Approve213086162024-12-01 15:39:595 days ago1733067599IN
MAP Protocol: MAPO Token
0 ETH0.0011085523.90992319
Approve213072692024-12-01 11:09:475 days ago1733051387IN
MAP Protocol: MAPO Token
0 ETH0.000225319.24642171
Approve213055982024-12-01 5:34:116 days ago1733031251IN
MAP Protocol: MAPO Token
0 ETH0.00037618.06184284
Approve213032182024-11-30 21:36:356 days ago1733002595IN
MAP Protocol: MAPO Token
0 ETH0.0003989516.37196102
Transfer213030912024-11-30 21:11:116 days ago1733001071IN
MAP Protocol: MAPO Token
0 ETH0.0006334713.56584945
Approve213005152024-11-30 12:32:596 days ago1732969979IN
MAP Protocol: MAPO Token
0 ETH0.0004685210.11848768
Transfer212979232024-11-30 3:50:597 days ago1732938659IN
MAP Protocol: MAPO Token
0 ETH0.0005899611.45922856
Approve212978642024-11-30 3:39:117 days ago1732937951IN
MAP Protocol: MAPO Token
0 ETH0.000408088.79727138
Approve212947162024-11-29 17:04:117 days ago1732899851IN
MAP Protocol: MAPO Token
0 ETH0.0008625318.60360009
Approve212914572024-11-29 6:06:478 days ago1732860407IN
MAP Protocol: MAPO Token
0 ETH0.000394178.5018169
Transfer212902602024-11-29 2:05:358 days ago1732845935IN
MAP Protocol: MAPO Token
0 ETH0.000550810.70111932
Transfer212899422024-11-29 1:01:598 days ago1732842119IN
MAP Protocol: MAPO Token
0 ETH0.000349197.47801208
Transfer212897962024-11-29 0:32:478 days ago1732840367IN
MAP Protocol: MAPO Token
0 ETH0.000220797.46014733
Transfer212894582024-11-28 23:24:358 days ago1732836275IN
MAP Protocol: MAPO Token
0 ETH0.000392348.40436244
Transfer212893892024-11-28 23:10:478 days ago1732835447IN
MAP Protocol: MAPO Token
0 ETH0.00042929.1914714
Approve212861452024-11-28 12:17:118 days ago1732796231IN
MAP Protocol: MAPO Token
0 ETH0.000402368.67617332
Approve212708822024-11-26 8:59:1111 days ago1732611551IN
MAP Protocol: MAPO Token
0 ETH0.0005828712.49403109
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
213442872024-12-06 15:15:3518 hrs ago1733498135
MAP Protocol: MAPO Token
0.00000144 ETH
213442872024-12-06 15:15:3518 hrs ago1733498135
MAP Protocol: MAPO Token
0.00000144 ETH
213373562024-12-05 16:01:5941 hrs ago1733414519
MAP Protocol: MAPO Token
0.00000144 ETH
213373562024-12-05 16:01:5941 hrs ago1733414519
MAP Protocol: MAPO Token
0.00000144 ETH
213371692024-12-05 15:23:5942 hrs ago1733412239
MAP Protocol: MAPO Token
0.00000144 ETH
213371692024-12-05 15:23:5942 hrs ago1733412239
MAP Protocol: MAPO Token
0.00000144 ETH
213371592024-12-05 15:21:5942 hrs ago1733412119
MAP Protocol: MAPO Token
0.00000144 ETH
213371592024-12-05 15:21:5942 hrs ago1733412119
MAP Protocol: MAPO Token
0.00000144 ETH
213370592024-12-05 15:01:5942 hrs ago1733410919
MAP Protocol: MAPO Token
0.00000144 ETH
213370592024-12-05 15:01:5942 hrs ago1733410919
MAP Protocol: MAPO Token
0.00000144 ETH
213364532024-12-05 12:59:5944 hrs ago1733403599
MAP Protocol: MAPO Token
0.00000144 ETH
213364532024-12-05 12:59:5944 hrs ago1733403599
MAP Protocol: MAPO Token
0.00000144 ETH
213349452024-12-05 7:56:592 days ago1733385419
MAP Protocol: MAPO Token
0.00000144 ETH
213349452024-12-05 7:56:592 days ago1733385419
MAP Protocol: MAPO Token
0.00000144 ETH
213349412024-12-05 7:56:112 days ago1733385371
MAP Protocol: MAPO Token
0.00000144 ETH
213349412024-12-05 7:56:112 days ago1733385371
MAP Protocol: MAPO Token
0.00000144 ETH
213349222024-12-05 7:52:232 days ago1733385143
MAP Protocol: MAPO Token
0.00000144 ETH
213349222024-12-05 7:52:232 days ago1733385143
MAP Protocol: MAPO Token
0.00000144 ETH
213348772024-12-05 7:43:232 days ago1733384603
MAP Protocol: MAPO Token
0.00000144 ETH
213348772024-12-05 7:43:232 days ago1733384603
MAP Protocol: MAPO Token
0.00000144 ETH
213337212024-12-05 3:50:352 days ago1733370635
MAP Protocol: MAPO Token
0.00000144 ETH
213337212024-12-05 3:50:352 days ago1733370635
MAP Protocol: MAPO Token
0.00000144 ETH
213333122024-12-05 2:28:112 days ago1733365691
MAP Protocol: MAPO Token
0.00000144 ETH
213333122024-12-05 2:28:112 days ago1733365691
MAP Protocol: MAPO Token
0.00000144 ETH
213332522024-12-05 2:15:592 days ago1733364959
MAP Protocol: MAPO Token
0.00000144 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MORC20PermitToken

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion, MIT license
File 1 of 35 : MORC20PermitToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

import "../morc20/MORC20Token.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

contract MORC20PermitToken is MORC20Token, ERC20Permit {
    constructor(
        string memory _name,
        string memory _symbol,
        address _mosAddress,
        uint256 _initialSupply,
        address _owner
    ) MORC20Token(_name, _symbol, _mosAddress) ERC20Permit(_name) {
        _transferOwnership(_owner);
        _mint(_owner, _initialSupply);
    }
}

File 2 of 35 : IMapoExecutor.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.0;

interface IMapoExecutor {
    function mapoExecute(
        uint256 _fromChain,
        uint256 _toChain,
        bytes calldata _fromAddress,
        bytes32 _orderId,
        bytes calldata _message
    ) external returns (bytes memory newMessage);
}

File 3 of 35 : IMOSV3.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IMOSV3 {
    enum ChainType {
        NULL,
        EVM,
        NEAR
    }

    enum MessageType {
        CALLDATA,
        MESSAGE
    }

    // @notice This is the configuration you need across the chain.
    // @param relay - When it is true, the relay chain is required to perform a special execution to continue across the chain.
    // @param msgType - Different execution patterns of messages across chains.
    // @param target - The contract address of the target chain.
    // @param payload - Cross-chain data.
    // @param gasLimit - The gasLimit allowed to be consumed by an operation performed on the target chain.
    // @param value - Collateral value cross-chain, currently not supported, default is 0.
    struct MessageData {
        bool relay;
        MessageType msgType;
        bytes target;
        bytes payload;
        uint256 gasLimit;
        uint256 value;
    }

    // @notice Gets the fee to cross to the target chain.
    // @param toChain - Target chain chainID.
    // @param feeToken - Token address that supports payment fee,if it's native, it's address(0).
    // @param gasLimit - The gasLimit allowed to be consumed by an operation performed on the target chain.
    function getMessageFee(
        uint256 toChain,
        address feeToken,
        uint256 gasLimit
    ) external view returns (uint256, address);

    function getOrderStatus(
        uint256 _chainId,
        uint256 _blockNum,
        bytes32 _orderId
    ) external view returns (bool exists, bool verifiable, uint256 nodeType);

    // @notice Initiate cross-chain transactions. Generate cross-chain logs.
    // @param toChain - Target chain chainID.
    // @param messageData - Structure MessageData encoding.
    // @param feeToken - In what Token would you like to pay the fee.
    function transferOut(
        uint256 toChain,
        bytes memory messageData,
        address feeToken
    ) external payable returns (bytes32);

    // @notice Add remote address permission.
    // @param fromChain - The chain id of the source chain.
    // @param fromAddress - The call address of the source chain.
    // @param tag - Permission,false: revoke permission.
    function addRemoteCaller(uint256 fromChain, bytes memory fromAddress, bool tag) external;

    // @notice Query whether the contract has execution permission.
    // @param targetAddress - The target address.
    // @param fromChain - The chain id of the source chain.
    // @param fromAddress - The call address of the source chain.
    function getExecutePermission(
        address targetAddress,
        uint256 fromChain,
        bytes memory fromAddress
    ) external view returns (bool);

    event mapMessageOut(
        uint256 indexed fromChain,
        uint256 indexed toChain,
        bytes32 orderId,
        bytes fromAddrss,
        bytes callData
    );

    event mapMessageIn(
        uint256 indexed fromChain,
        uint256 indexed toChain,
        bytes32 orderId,
        bytes fromAddrss,
        bytes callData,
        bool result,
        bytes reason
    );
}

File 4 of 35 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

File 5 of 35 : IERC5267.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.0;

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 6 of 35 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.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 Pausable is Context {
    /**
     * @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);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _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) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

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

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

File 7 of 35 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.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}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * 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 ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        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 override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` 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 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * 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 `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `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.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(address from, address to, uint256 amount) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` 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.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

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

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}

File 8 of 35 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../utils/Context.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

File 9 of 35 : ERC20Capped.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";

/**
 * @dev Extension of {ERC20} that adds a cap to the supply of tokens.
 */
abstract contract ERC20Capped is ERC20 {
    uint256 private immutable _cap;

    /**
     * @dev Sets the value of the `cap`. This value is immutable, it can only be
     * set once during construction.
     */
    constructor(uint256 cap_) {
        require(cap_ > 0, "ERC20Capped: cap is 0");
        _cap = cap_;
    }

    /**
     * @dev Returns the cap on the token's total supply.
     */
    function cap() public view virtual returns (uint256) {
        return _cap;
    }

    /**
     * @dev See {ERC20-_mint}.
     */
    function _mint(address account, uint256 amount) internal virtual override {
        require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded");
        super._mint(account, amount);
    }
}

File 10 of 35 : ERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/ERC20Permit.sol)

pragma solidity ^0.8.0;

import "./IERC20Permit.sol";
import "../ERC20.sol";
import "../../../utils/cryptography/ECDSA.sol";
import "../../../utils/cryptography/EIP712.sol";
import "../../../utils/Counters.sol";

/**
 * @dev Implementation 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.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping(address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private constant _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    /**
     * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
     * However, to ensure consistency with the upgradeable transpiler, we will continue
     * to reserve a slot.
     * @custom:oz-renamed-from _PERMIT_TYPEHASH
     */
    // solhint-disable-next-line var-name-mixedcase
    bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

    /**
     * @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 ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @inheritdoc IERC20Permit
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired 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);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

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

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}

File 11 of 35 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
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 12 of 35 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 13 of 35 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

File 14 of 35 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

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

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

File 15 of 35 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 16 of 35 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 17 of 35 : Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 18 of 35 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @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,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode 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 {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]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        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);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode 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 {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        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]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        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.
     *
     * _Available since v4.2._
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
        // 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);
        }

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

        return (signer, RecoverError.NoError);
    }

    /**
     * @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) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32")
            mstore(0x1c, hash)
            message := keccak256(0x00, 0x3c)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, "\x19\x01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            data := keccak256(ptr, 0x42)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Data with intended validator, created from a
     * `validator` and `data` according to the version 0 of EIP-191.
     *
     * See {recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x00", validator, data));
    }
}

File 19 of 35 : EIP712.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.8;

import "./ECDSA.sol";
import "../ShortStrings.sol";
import "../../interfaces/IERC5267.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic 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 their contracts 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.
 *
 * _Available since v3.4._
 *
 * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
 */
abstract contract EIP712 is IERC5267 {
    using ShortStrings for *;

    bytes32 private constant _TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _cachedDomainSeparator;
    uint256 private immutable _cachedChainId;
    address private immutable _cachedThis;

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

    ShortString private immutable _name;
    ShortString private immutable _version;
    string private _nameFallback;
    string private _versionFallback;

    /**
     * @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].
     */
    constructor(string memory name, string memory version) {
        _name = name.toShortStringWithFallback(_nameFallback);
        _version = version.toShortStringWithFallback(_versionFallback);
        _hashedName = keccak256(bytes(name));
        _hashedVersion = keccak256(bytes(version));

        _cachedChainId = block.chainid;
        _cachedDomainSeparator = _buildDomainSeparator();
        _cachedThis = address(this);
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
            return _cachedDomainSeparator;
        } else {
            return _buildDomainSeparator();
        }
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev See {EIP-5267}.
     *
     * _Available since v4.9._
     */
    function eip712Domain()
        public
        view
        virtual
        override
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f", // 01111
            _name.toStringWithFallback(_nameFallback),
            _version.toStringWithFallback(_versionFallback),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }
}

File 20 of 35 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 21 of 35 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 22 of 35 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @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 up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (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; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                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.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 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.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            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 (rounding == Rounding.Up && 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 down.
     *
     * 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * 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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * 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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 23 of 35 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @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 24 of 35 : ShortStrings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)

pragma solidity ^0.8.8;

import "./StorageSlot.sol";

// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |
// | length  | 0x                                                              BB |
type ShortString is bytes32;

/**
 * @dev This library provides functions to convert short memory strings
 * into a `ShortString` type that can be used as an immutable variable.
 *
 * Strings of arbitrary length can be optimized using this library if
 * they are short enough (up to 31 bytes) by packing them with their
 * length (1 byte) in a single EVM word (32 bytes). Additionally, a
 * fallback mechanism can be used for every other case.
 *
 * Usage example:
 *
 * ```solidity
 * contract Named {
 *     using ShortStrings for *;
 *
 *     ShortString private immutable _name;
 *     string private _nameFallback;
 *
 *     constructor(string memory contractName) {
 *         _name = contractName.toShortStringWithFallback(_nameFallback);
 *     }
 *
 *     function name() external view returns (string memory) {
 *         return _name.toStringWithFallback(_nameFallback);
 *     }
 * }
 * ```
 */
library ShortStrings {
    // Used as an identifier for strings longer than 31 bytes.
    bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;

    error StringTooLong(string str);
    error InvalidShortString();

    /**
     * @dev Encode a string of at most 31 chars into a `ShortString`.
     *
     * This will trigger a `StringTooLong` error is the input string is too long.
     */
    function toShortString(string memory str) internal pure returns (ShortString) {
        bytes memory bstr = bytes(str);
        if (bstr.length > 31) {
            revert StringTooLong(str);
        }
        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
    }

    /**
     * @dev Decode a `ShortString` back to a "normal" string.
     */
    function toString(ShortString sstr) internal pure returns (string memory) {
        uint256 len = byteLength(sstr);
        // using `new string(len)` would work locally but is not memory safe.
        string memory str = new string(32);
        /// @solidity memory-safe-assembly
        assembly {
            mstore(str, len)
            mstore(add(str, 0x20), sstr)
        }
        return str;
    }

    /**
     * @dev Return the length of a `ShortString`.
     */
    function byteLength(ShortString sstr) internal pure returns (uint256) {
        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
        if (result > 31) {
            revert InvalidShortString();
        }
        return result;
    }

    /**
     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.
     */
    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
        if (bytes(value).length < 32) {
            return toShortString(value);
        } else {
            StorageSlot.getStringSlot(store).value = value;
            return ShortString.wrap(_FALLBACK_SENTINEL);
        }
    }

    /**
     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     */
    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return toString(value);
        } else {
            return store;
        }
    }

    /**
     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     *
     * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
     */
    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return byteLength(value);
        } else {
            return bytes(store).length;
        }
    }
}

File 25 of 35 : StorageSlot.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

File 26 of 35 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

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

    /**
     * @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), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(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) {
        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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        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 keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 27 of 35 : MapoExecutor.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@mapprotocol/mos/contracts/interface/IMOSV3.sol";
import "@mapprotocol/mos/contracts/interface/IMapoExecutor.sol";
import "../lib/Helper.sol";

abstract contract MapoExecutor is Ownable, IMapoExecutor {
    uint256 public constant MESSAGE_TYPE_MESSAGE = 0;
    uint256 public constant MESSAGE_TYPE_CALL_DATA = 1;

    uint256 public constant gasLimitMin = 21000;
    uint256 public constant gasLimitMax = 10000000;

    IMOSV3 public mos;
    address public feeToken;
    mapping(uint256 => bytes) public trustedList;

    event SetTrustedAddress(uint256 indexed toChainId, bytes toAddress);
    event SetFeeToken(address indexed feeToken);
    event SetMosAddress(address indexed mos);

    constructor(address _mosAddress) {
        require(_mosAddress != address(0), "MapoExecutor: invalid mos address");
        mos = IMOSV3(_mosAddress);
    }

    function mapoExecute(
        uint256 _fromChain,
        uint256 _toChain,
        bytes calldata _fromAddress,
        bytes32 _orderId,
        bytes calldata _message
    ) external virtual override returns (bytes memory newMessage) {
        require(_msgSender() == address(mos), "MapoExecutor: invalid mos caller");

        bytes memory tempFromAddress = trustedList[_fromChain];

        require(
            _fromAddress.length == tempFromAddress.length &&
                tempFromAddress.length > 0 &&
                keccak256(_fromAddress) == keccak256(tempFromAddress),
            "MapoExecutor: invalid source chain address"
        );

        newMessage = _execute(_fromChain, _toChain, _fromAddress, _orderId, _message);
    }

    function _execute(
        uint256 _fromChain,
        uint256 _toChain,
        bytes memory _fromAddress,
        bytes32 _orderId,
        bytes memory _message
    ) internal virtual returns (bytes memory);

    function _mosTransferOut(
        uint256 _toChain,
        uint256 _toType,
        bytes memory _payload,
        uint256 _gasLimit
    ) internal virtual returns (bytes32) {
        bytes memory toAddress = trustedList[_toChain];
        require(toAddress.length > 0, "MapoExecutor: invalid remote trust address");

        bytes memory messageDataBytes;
        if (_toType == MESSAGE_TYPE_MESSAGE) {
            messageDataBytes = abi.encode(false, IMOSV3.MessageType.MESSAGE, toAddress, _payload, _gasLimit, 0);
        } else if (_toType == MESSAGE_TYPE_CALL_DATA) {
            messageDataBytes = abi.encode(false, IMOSV3.MessageType.CALLDATA, toAddress, _payload, _gasLimit, 0);
        } else {
            require(false, "MapoExecutor: invalid message type");
        }

        (address token, uint256 fee) = _getMessageFee(_toChain, _gasLimit);
        require(fee > 0, "MapoExecutor: invalid fee value");
        if (token == address(0)) {
            require(msg.value >= fee, "MapoExecutor: invalid fee");
        } else {
            SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), fee);
            SafeERC20.safeApprove(IERC20(token), address(mos), fee);
        }

        return mos.transferOut{value: msg.value}(_toChain, messageDataBytes, token);
    }

    function _getMessageFee(uint256 _toChain, uint256 _gasLimit) internal view returns (address token, uint256 amount) {
        (uint256 fee, ) = mos.getMessageFee(_toChain, feeToken, _gasLimit);

        return (feeToken, fee);
    }

    function getTrustedAddress(uint256 _remoteChainId) external view returns (bytes memory) {
        return trustedList[_remoteChainId];
    }

    function setTrustedAddress(
        uint256[] calldata _remoteChainIds,
        bytes[] calldata _remoteAddresses
    ) external onlyOwner {
        require(_remoteChainIds.length == _remoteAddresses.length, "MapoExecutor: address or chainId not match");
        for (uint256 i = 0; i < _remoteChainIds.length; i++) {
            trustedList[_remoteChainIds[i]] = _remoteAddresses[i];
            emit SetTrustedAddress(_remoteChainIds[i], _remoteAddresses[i]);
        }
    }

    function setFeeToken(address _feeToken) external onlyOwner {
        require(_feeToken != address(0), "MapoExecutor: invalid fee token");
        feeToken = _feeToken;
        emit SetFeeToken(_feeToken);
    }

    function setMosAddress(address _mos) external onlyOwner {
        require(_mos != address(0), "MapoExecutor: invalid mos address");
        mos = IMOSV3(_mos);
        emit SetMosAddress(_mos);
    }

    function rescueFunds(address _token, uint256 _amount) external onlyOwner {
        Helper._transfer(_token, msg.sender, _amount);
    }
}

File 28 of 35 : MORC20Capped.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../morc20/MORC20Token.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol";

contract MORC20Capped is MORC20Token, ERC20Capped {
    constructor(
        string memory _name,
        string memory _symbol,
        uint256 _cappded,
        address _mosAddress
    ) MORC20Token(_name, _symbol, _mosAddress) ERC20Capped(_cappded) {}

    function _mint(address account, uint amount) internal virtual override(ERC20, ERC20Capped) {
        ERC20Capped._mint(account, amount);
    }
}

File 29 of 35 : MORC20Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../morc20/MORC20Token.sol";
import "@openzeppelin/contracts/security/Pausable.sol";

contract MORC20Pausable is MORC20Token, Pausable {
    constructor(
        string memory _name,
        string memory _symbol,
        address _mosAddress
    ) MORC20Token(_name, _symbol, _mosAddress) {}

    function interTransfer(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit
    ) external payable virtual override whenNotPaused {
        return _interTransfer(_fromAddress, _toChainId, _toAddress, _fromAmount, _gasLimit);
    }

    function interTransferAndCall(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit,
        bytes memory _refundAddress,
        bytes memory _messageData
    ) external payable virtual override whenNotPaused {
        _interTransferAndCall(
            _fromAddress,
            _toChainId,
            _toAddress,
            _fromAmount,
            _gasLimit,
            _refundAddress,
            _messageData
        );
    }

    function pauseSendTokens(bool pause) external onlyOwner {
        pause ? _pause() : _unpause();
    }
}

File 30 of 35 : IMORC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Interface of the IMORC20 core standard
 */
interface IMORC20 is IERC165 {
    event InterTransfer(
        bytes32 indexed orderId,
        address indexed fromAddress,
        uint256 indexed toChainId,
        bytes toAddress,
        uint256 fromAmount
    );

    event InterTransferAndCall(
        bytes32 indexed orderId,
        address indexed fromAddress,
        uint256 indexed toChainId,
        bytes toAddress,
        uint256 fromAmount,
        bytes payLoad
    );

    event InterReceive(
        bytes32 indexed orderId,
        uint256 indexed fromChain,
        bytes fromAddress,
        address toAddress,
        uint256 amount
    );

    event InterReceiveAndExecute(
        bytes32 indexed orderId,
        uint256 indexed fromchain,
        bytes srcAddress,
        address toAddress,
        bool result,
        bytes reason
    );

    /**
     * estimate interchain transfer fee
     */
    function estimateFee(uint256 toChain, uint256 gasLimit) external view returns (address feeToken, uint256 fee);

    /**
     * returns the circulating supply on current chain
     */
    function currentChainSupply() external view returns (uint);

    /**
     *  returns the address of the ERC20 token
     */
    function token() external view returns (address);

    function interTransfer(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit
    ) external payable;

    function interTransferAndCall(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit,
        bytes memory _refundAddress,
        bytes memory _messageData
    ) external payable;
}

File 31 of 35 : IMORC20Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IMORC20Receiver {
    function onMORC20Received(
        uint256 _fromChainId,
        bytes memory _fromAddress,
        uint256 _amount,
        bytes32 _orderId,
        bytes calldata _message
    ) external returns (bool);
}

File 32 of 35 : ExcessivelySafeCall.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;

library ExcessivelySafeCall {
    uint256 constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := call(
                _gas, // gas
                _target, // recipient
                0, // ether value
                add(_calldata, 0x20), // inloc
                mload(_calldata), // inlen
                0, // outloc
                0 // outlen
            )
            // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
            // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
            // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeStaticCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal view returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := staticcall(
                _gas, // gas
                _target, // recipient
                add(_calldata, 0x20), // inloc
                mload(_calldata), // inlen
                0, // outloc
                0 // outlen
            )
            // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
            // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
            // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /**
     * @notice Swaps function selectors in encoded contract calls
     * @dev Allows reuse of encoded calldata for functions with identical
     * argument types but different names. It simply swaps out the first 4 bytes
     * for the new selector. This function modifies memory in place, and should
     * only be used with caution.
     * @param _newSelector The new 4-byte selector
     * @param _buf The encoded contract args
     */
    function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {
        require(_buf.length >= 4);
        uint256 _mask = LOW_28_MASK;
        assembly {
            // load the first word of
            let _word := mload(add(_buf, 0x20))
            // mask out the top 4 bytes
            // /x
            _word := and(_word, _mask)
            _word := or(_newSelector, _word)
            mstore(add(_buf, 0x20), _word)
        }
    }
}

File 33 of 35 : Helper.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

library Helper {
    using SafeERC20 for IERC20;
    address internal constant ZERO_ADDRESS = address(0);

    address internal constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    function _isNative(address token) internal pure returns (bool) {
        return (token == ZERO_ADDRESS || token == NATIVE_ADDRESS);
    }

    function _getBalance(address _token, address _account) internal view returns (uint256) {
        if (_isNative(_token)) {
            return _account.balance;
        } else {
            return IERC20(_token).balanceOf(_account);
        }
    }

    function _transfer(address _token, address _to, uint256 _amount) internal {
        if (_isNative(_token)) {
            Address.sendValue(payable(_to), _amount);
        } else {
            IERC20(_token).safeTransfer(_to, _amount);
        }
    }

    function _safeWithdraw(address _wToken, uint _value) internal returns (bool) {
        (bool success, bytes memory data) = _wToken.call(abi.encodeWithSelector(0x2e1a7d4d, _value));
        return (success && (data.length == 0 || abi.decode(data, (bool))));
    }

    function _fromBytes(bytes memory bys) internal pure returns (address addr) {
        assembly {
            addr := mload(add(bys, 20))
        }
    }

    function _toBytes(address self) internal pure returns (bytes memory b) {
        b = abi.encodePacked(self);
    }
}

File 34 of 35 : MORC20Core.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "../interfaces/IMORC20.sol";
import "../interfaces/IMORC20Receiver.sol";
import "../executor/MapoExecutor.sol";
import "../lib/ExcessivelySafeCall.sol";
import "../lib/Helper.sol";

abstract contract MORC20Core is MapoExecutor, ERC165, IMORC20 {
    using ExcessivelySafeCall for address;
    using SafeERC20 for IERC20;
    using Address for address;

    bytes32 public constant INTERCHAIN_TRANSFER = keccak256("InterTransfer(bytes32,bytes)");
    bytes32 public constant INTERCHAIN_TRANSFER_AND_CALL = keccak256("InterTransferAndCall(bytes32,bytes)");
    bytes public constant NOT_CONTRACT_ADDRESS = "0x4e4f545f434f4e54524143545f41444452455353";

    mapping(bytes32 => bool) public orderList;

    constructor(address _mosAddress) MapoExecutor(_mosAddress) {}

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IMORC20).interfaceId || super.supportsInterface(interfaceId);
    }

    function estimateFee(
        uint256 _toChain,
        uint256 _gasLimit
    ) external view virtual override returns (address feeToken, uint256 fee) {
        return _getMessageFee(_toChain, _gasLimit);
    }

    function interTransfer(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit
    ) external payable virtual override {
        _interTransfer(_fromAddress, _toChainId, _toAddress, _fromAmount, _gasLimit);
    }

    function interTransferAndCall(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit,
        bytes memory _refundAddress,
        bytes memory _messageData
    ) external payable virtual override {
        _interTransferAndCall(
            _fromAddress,
            _toChainId,
            _toAddress,
            _fromAmount,
            _gasLimit,
            _refundAddress,
            _messageData
        );
    }

    function _interTransfer(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit
    ) internal virtual {
        (uint256 amount, uint256 decimals) = _destroyTokenFrom(_fromAddress, _toChainId, _toAddress, _fromAmount);

        require(amount > 0, "MORC20Core: amount too small");

        bytes memory fromAddress = Helper._toBytes(_fromAddress);
        bytes memory prePayload = abi.encode(fromAddress, _toAddress, amount, decimals);
        bytes memory payload = abi.encode(INTERCHAIN_TRANSFER, prePayload);

        bytes32 orderId = _mosTransferOut(_toChainId, MESSAGE_TYPE_MESSAGE, payload, _gasLimit);

        emit InterTransfer(orderId, _fromAddress, _toChainId, _toAddress, _fromAmount);
    }

    function _interTransferAndCall(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount,
        uint256 _gasLimit,
        bytes memory _refundAddress,
        bytes memory _messageData
    ) internal virtual {
        (uint256 amount, uint256 decimals) = _destroyTokenFrom(_fromAddress, _toChainId, _toAddress, _fromAmount); // amount returned should not have dust
        require(amount > 0, "MORC20Core: amount too small");

        bytes memory fromAddress = Helper._toBytes(_fromAddress);
        bytes memory prePayload = abi.encode(fromAddress, _toAddress, amount, decimals, _refundAddress, _messageData);
        bytes memory payload = abi.encode(INTERCHAIN_TRANSFER_AND_CALL, prePayload);

        bytes32 orderId = _mosTransferOut(_toChainId, MESSAGE_TYPE_MESSAGE, payload, _gasLimit);

        emit InterTransferAndCall(orderId, _fromAddress, _toChainId, _toAddress, _fromAmount, prePayload);
    }

    function _interReceive(uint256 _fromChain, bytes32 _orderId, bytes memory _payload) internal virtual {
        (bytes memory fromBytes, bytes memory receiverBytes, uint256 amount, uint256 decimals) = abi.decode(
            _payload,
            (bytes, bytes, uint256, uint256)
        );
        address receiverAddress = Helper._fromBytes(receiverBytes);
        _createTokenTo(receiverAddress, _fromChain, amount, decimals);

        emit InterReceive(_orderId, _fromChain, fromBytes, receiverAddress, amount);
    }

    function callOnMORC20Received(
        uint256 _fromChainId,
        bytes memory _fromAddress,
        uint256 _amount,
        address _receiverAddress,
        bytes32 _orderId,
        bytes calldata _message
    ) public virtual {
        require(_msgSender() == address(this), "MORC20Core: caller must be MORC20Core");

        // send
        uint256 amount = _transferFrom(address(this), _receiverAddress, _amount);
        emit InterReceive(_orderId, _fromChainId, _fromAddress, _receiverAddress, amount);

        // call
        // todo: check the gas for call
        bool success = IMORC20Receiver(_receiverAddress).onMORC20Received{gas: gasleft()}(
            _fromChainId,
            _fromAddress,
            _amount,
            _orderId,
            _message
        );
        require(success, "MORC20Core: callOnMORC20Received fail");
    }

    function _interReceiveAndExecute(uint256 _fromChain, bytes32 _orderId, bytes memory _payload) internal virtual {
        (
            bytes memory srcAddress,
            bytes memory receiverBytes,
            uint256 amount,
            uint256 decimals,
            bytes memory refundBytes,
            bytes memory messageData
        ) = abi.decode(_payload, (bytes, bytes, uint256, uint256, bytes, bytes));

        address receiverAddress = Helper._fromBytes(receiverBytes);
        (uint256 amount_, ) = _createTokenTo(address(this), _fromChain, amount, decimals);

        if (!receiverAddress.isContract()) {
            _transferFrom(address(this), Helper._fromBytes(refundBytes), amount_);
            emit InterReceive(_orderId, _fromChain, srcAddress, Helper._fromBytes(refundBytes), amount_);
            emit InterReceiveAndExecute(_orderId, _fromChain, srcAddress, receiverAddress, false, NOT_CONTRACT_ADDRESS);
            return;
        }

        bytes memory callOnMORC20ReceivedSelector = abi.encodeWithSelector(
            this.callOnMORC20Received.selector,
            _fromChain,
            srcAddress,
            amount_,
            receiverAddress,
            _orderId,
            messageData
        );

        (bool success, bytes memory reason) = address(this).excessivelySafeCall(
            gasleft(),
            150,
            callOnMORC20ReceivedSelector
        );

        if (success) {
            emit InterReceiveAndExecute(_orderId, _fromChain, srcAddress, receiverAddress, true, bytes(""));
        } else {
            _transferFrom(address(this), Helper._fromBytes(refundBytes), amount_);
            emit InterReceive(_orderId, _fromChain, srcAddress, Helper._fromBytes(refundBytes), amount_);
            emit InterReceiveAndExecute(_orderId, _fromChain, srcAddress, receiverAddress, false, reason);
        }
    }

    function _execute(
        uint256 _fromChain,
        uint256,
        bytes memory,
        bytes32 _orderId,
        bytes memory _message
    ) internal virtual override returns (bytes memory) {
        require(!orderList[_orderId], "MORC20Core: invalid orderId");

        (bytes32 interType, bytes memory payload) = abi.decode(_message, (bytes32, bytes));

        orderList[_orderId] = true;

        if (interType == INTERCHAIN_TRANSFER) {
            _interReceive(_fromChain, _orderId, payload);
        } else if (interType == INTERCHAIN_TRANSFER_AND_CALL) {
            _interReceiveAndExecute(_fromChain, _orderId, payload);
        } else {
            revert("MORC20Core: unknown message type");
        }

        return payload;
    }

    // burn or lock omnichain token
    function _destroyTokenFrom(
        address _fromAddress,
        uint256 _toChainId,
        bytes memory _toAddress,
        uint256 _fromAmount
    ) internal virtual returns (uint256 amount, uint256 decimals);

    // mint or unlock omnichain token
    function _createTokenTo(
        address _receiverAddress,
        uint256 _fromChainId,
        uint256 _amount,
        uint256 _decimals
    ) internal virtual returns (uint256 amount, uint256 decimals);

    function _transferFrom(address _from, address _to, uint256 _amount) internal virtual returns (uint256);

    function currentChainSupply() public view virtual override returns (uint);

    function token() public view virtual override returns (address);
}

File 35 of 35 : MORC20Token.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./MORC20Core.sol";

contract MORC20Token is MORC20Core, ERC20 {
    uint256 public tokenDecimals;

    constructor(
        string memory _name,
        string memory _symbol,
        address _mosAddress
    ) ERC20(_name, _symbol) MORC20Core(_mosAddress) {
        tokenDecimals = uint256(decimals());
    }

    function currentChainSupply() public view virtual override returns (uint) {
        return totalSupply();
    }

    function token() public view virtual override returns (address) {
        return address(this);
    }

    function _destroyTokenFrom(
        address _fromAddress,
        uint256,
        bytes memory,
        uint256 _fromAmount
    ) internal virtual override returns (uint256 amount, uint256 decimals) {
        address spender = _msgSender();
        if (_fromAddress != spender) {
            _spendAllowance(_fromAddress, spender, _fromAmount);
        }
        _burn(_fromAddress, _fromAmount);

        return (_fromAmount, tokenDecimals);
    }

    function _createTokenTo(
        address _receiverAddress,
        uint256,
        uint256 _fromAmount,
        uint256 _fromDecimals
    ) internal virtual override returns (uint256 amount, uint256 decimals) {
        if (tokenDecimals == _fromDecimals) {
            amount = _fromAmount;
        } else {
            amount = (_fromAmount * 10 ** tokenDecimals) / 10 ** _fromDecimals;
        }

        _mint(_receiverAddress, amount);

        return (amount, tokenDecimals);
    }

    function _transferFrom(address _from, address _to, uint256 _amount) internal virtual override returns (uint256) {
        address spender = _msgSender();
        // if transfer from this contract, no need to check allowance
        if (_from != address(this) && _from != spender) {
            _spendAllowance(_from, spender, _amount);
        }
        _transfer(_from, _to, _amount);
        return _amount;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "london",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_mosAddress","type":"address"},{"internalType":"uint256","name":"_initialSupply","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","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":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"fromChain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"fromAddress","type":"bytes"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InterReceive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"fromchain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"InterReceiveAndExecute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"}],"name":"InterTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"payLoad","type":"bytes"}],"name":"InterTransferAndCall","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":true,"internalType":"address","name":"feeToken","type":"address"}],"name":"SetFeeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mos","type":"address"}],"name":"SetMosAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"}],"name":"SetTrustedAddress","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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INTERCHAIN_TRANSFER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INTERCHAIN_TRANSFER_AND_CALL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_TYPE_CALL_DATA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_TYPE_MESSAGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NOT_CONTRACT_ADDRESS","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"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":"amount","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":"uint256","name":"_fromChainId","type":"uint256"},{"internalType":"bytes","name":"_fromAddress","type":"bytes"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_receiverAddress","type":"address"},{"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"callOnMORC20Received","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentChainSupply","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":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"_toChain","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"estimateFee","outputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasLimitMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasLimitMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_remoteChainId","type":"uint256"}],"name":"getTrustedAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromAddress","type":"address"},{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_fromAmount","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"interTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromAddress","type":"address"},{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_fromAmount","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_refundAddress","type":"bytes"},{"internalType":"bytes","name":"_messageData","type":"bytes"}],"name":"interTransferAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromChain","type":"uint256"},{"internalType":"uint256","name":"_toChain","type":"uint256"},{"internalType":"bytes","name":"_fromAddress","type":"bytes"},{"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"mapoExecute","outputs":[{"internalType":"bytes","name":"newMessage","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mos","outputs":[{"internalType":"contract IMOSV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"orderList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeToken","type":"address"}],"name":"setFeeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mos","type":"address"}],"name":"setMosAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_remoteChainIds","type":"uint256[]"},{"internalType":"bytes[]","name":"_remoteAddresses","type":"bytes[]"}],"name":"setTrustedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimals","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":"amount","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":"amount","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":"uint256","name":"","type":"uint256"}],"name":"trustedList","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]

6101606040523480156200001257600080fd5b50604051620047473803806200474783398101604081905262000035916200048a565b8480604051806040016040528060018152602001603160f81b81525087878782828280620000726200006c6200020660201b60201c565b6200020a565b6001600160a01b038116620000d85760405162461bcd60e51b815260206004820152602160248201527f4d61706f4578656375746f723a20696e76616c6964206d6f73206164647265736044820152607360f81b60648201526084015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055506008620001078382620005b1565b506009620001168282620005b1565b5062000123915050601290565b60ff16600a55506200013b9150839050600b6200025a565b610120526200014c81600c6200025a565b61014052815160208084019190912060e052815190820120610100524660a052620001da60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05250620001ef816200020a565b620001fb818362000293565b5050505050620006f9565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020835110156200027a57620002728362000358565b90506200028d565b81620002878482620005b1565b5060ff90505b92915050565b6001600160a01b038216620002eb5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620000cf565b8060076000828254620002ff91906200067d565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600080829050601f8151111562000386578260405163305a27a960e01b8152600401620000cf91906200069f565b80516200039382620006d4565b179392505050565b505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620003d3578181015183820152602001620003b9565b50506000910152565b600082601f830112620003ee57600080fd5b81516001600160401b03808211156200040b576200040b620003a0565b604051601f8301601f19908116603f01168101908282118183101715620004365762000436620003a0565b816040528381528660208588010111156200045057600080fd5b62000463846020830160208901620003b6565b9695505050505050565b80516001600160a01b03811681146200048557600080fd5b919050565b600080600080600060a08688031215620004a357600080fd5b85516001600160401b0380821115620004bb57600080fd5b620004c989838a01620003dc565b96506020880151915080821115620004e057600080fd5b50620004ef88828901620003dc565b94505062000500604087016200046d565b92506060860151915062000517608087016200046d565b90509295509295909350565b600181811c908216806200053857607f821691505b6020821081036200055957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039b57600081815260208120601f850160051c81016020861015620005885750805b601f850160051c820191505b81811015620005a95782815560010162000594565b505050505050565b81516001600160401b03811115620005cd57620005cd620003a0565b620005e581620005de845462000523565b846200055f565b602080601f8311600181146200061d5760008415620006045750858301515b600019600386901b1c1916600185901b178555620005a9565b600085815260208120601f198616915b828110156200064e578886015182559484019460019091019084016200062d565b50858210156200066d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200028d57634e487b7160e01b600052601160045260246000fd5b6020815260008251806020840152620006c0816040850160208701620003b6565b601f01601f19169190910160400192915050565b80516020808301519190811015620005595760001960209190910360031b1b16919050565b60805160a05160c05160e051610100516101205161014051613ff3620007546000396000610d2701526000610cfc015260006119da015260006119b20152600061190d01526000611937015260006119610152613ff36000f3fe60806040526004361061025b5760003560e01c8063715018a611610144578063a457c2d7116100b6578063dd62ed3e1161007a578063dd62ed3e14610732578063ea093f3814610752578063f2fde38b14610765578063f32d49f714610785578063f4bf6a711461079b578063fc0c546a146107bb57600080fd5b8063a457c2d71461069b578063a9059cbb146106bb578063c697caec146106db578063d1dedf58146106fb578063d505accf1461071257600080fd5b806387d095b91161010857806387d095b9146105ec5780638da5cb5b146105ff578063950d4fcc1461061d57806395d89b4114610632578063994e919a14610647578063a2784c7a1461066757600080fd5b8063715018a61461055a57806378e3214f1461056f5780637c0ec54a1461058f5780637ecebe00146105a457806384b0196e146105c457600080fd5b806323b872dd116101dd5780633b97e856116101a15780633b97e8561461046a578063561cbfab14610480578063647846a5146104b457806368f3bc74146104d45780636af6400d146104f457806370a082311461052457600080fd5b806323b872dd146103d95780632b8b7b4b146103f9578063313ce567146104195780633644e51514610435578063395093511461044a57600080fd5b806315cce2241161022457806315cce2241461034e57806318160ddd14610370578063190f39401461038f5780631c1992e9146103af5780631e06f826146103c457600080fd5b8062e1d8d01461026057806301ffc9a7146102a457806306fdde03146102d4578063095ea7b3146102f65780631528dd7714610316575b600080fd5b34801561026c57600080fd5b5061028061027b3660046130b6565b6107ce565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b3480156102b057600080fd5b506102c46102bf3660046130d8565b6107e7565b604051901515815260200161029b565b3480156102e057600080fd5b506102e961081e565b60405161029b9190613159565b34801561030257600080fd5b506102c4610311366004613181565b6108b0565b34801561032257600080fd5b50600154610336906001600160a01b031681565b6040516001600160a01b03909116815260200161029b565b34801561035a57600080fd5b5061036e6103693660046131ad565b6108c8565b005b34801561037c57600080fd5b506007545b60405190815260200161029b565b34801561039b57600080fd5b5061036e6103aa3660046132ce565b610975565b3480156103bb57600080fd5b50610381610af1565b3480156103d057600080fd5b50610381600081565b3480156103e557600080fd5b506102c46103f4366004613369565b610b01565b34801561040557600080fd5b5061036e6104143660046131ad565b610b25565b34801561042557600080fd5b506040516012815260200161029b565b34801561044157600080fd5b50610381610bd7565b34801561045657600080fd5b506102c4610465366004613181565b610be1565b34801561047657600080fd5b50610381600a5481565b34801561048c57600080fd5b506103817f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c881565b3480156104c057600080fd5b50600254610336906001600160a01b031681565b3480156104e057600080fd5b506102e96104ef3660046133aa565b610c03565b34801561050057600080fd5b506102c461050f3660046133aa565b60046020526000908152604090205460ff1681565b34801561053057600080fd5b5061038161053f3660046131ad565b6001600160a01b031660009081526005602052604090205490565b34801561056657600080fd5b5061036e610ca5565b34801561057b57600080fd5b5061036e61058a366004613181565b610cb9565b34801561059b57600080fd5b50610381600181565b3480156105b057600080fd5b506103816105bf3660046131ad565b610cd0565b3480156105d057600080fd5b506105d9610cee565b60405161029b97969594939291906133c3565b61036e6105fa366004613459565b610d77565b34801561060b57600080fd5b506000546001600160a01b0316610336565b34801561062957600080fd5b506102e9610d8b565b34801561063e57600080fd5b506102e9610da7565b34801561065357600080fd5b506102e96106623660046134c3565b610db6565b34801561067357600080fd5b506103817f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57381565b3480156106a757600080fd5b506102c46106b6366004613181565b610fd4565b3480156106c757600080fd5b506102c46106d6366004613181565b61104f565b3480156106e757600080fd5b5061036e6106f6366004613573565b61105d565b34801561070757600080fd5b506103816298968081565b34801561071e57600080fd5b5061036e61072d3660046135de565b6111b5565b34801561073e57600080fd5b5061038161074d366004613655565b611319565b61036e61076036600461368e565b611344565b34801561077157600080fd5b5061036e6107803660046131ad565b61135c565b34801561079157600080fd5b5061038161520881565b3480156107a757600080fd5b506102e96107b63660046133aa565b6113d5565b3480156107c757600080fd5b5030610336565b6000806107db848461146f565b915091505b9250929050565b60006001600160e01b03198216634696da6960e11b148061081857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606008805461082d90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461085990613745565b80156108a65780601f1061087b576101008083540402835291602001916108a6565b820191906000526020600020905b81548152906001019060200180831161088957829003601f168201915b5050505050905090565b6000336108be81858561150b565b5060019392505050565b6108d061162f565b6001600160a01b03811661092b5760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c69642066656520746f6b656e0060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f0842bcbb92ca6d47ae89816778a843992dff9b876fad009865e1c5df73d46d1f90600090a250565b3330146109d25760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c6572206d757374206265204d4f52433260448201526430436f726560d81b6064820152608401610922565b60006109df308688611689565b90508784600080516020613f74833981519152898885604051610a0493929190613779565b60405180910390a36000856001600160a01b031663cb05b6f05a8b8b8b8a8a8a6040518863ffffffff1660e01b8152600401610a45969594939291906137d0565b60206040518083038160008887f1158015610a64573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610a899190613808565b905080610ae65760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c4f6e4d4f5243323052656365697665646044820152640819985a5b60da1b6064820152608401610922565b505050505050505050565b6000610afc60075490565b905090565b600033610b0f8582856116db565b610b1a858585611755565b506001949350505050565b610b2d61162f565b6001600160a01b038116610b8d5760405162461bcd60e51b815260206004820152602160248201527f4d61706f4578656375746f723a20696e76616c6964206d6f73206164647265736044820152607360f81b6064820152608401610922565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f4dac21cd18f86f988c6cb57f54a5fc95e6c8e24ad536d4d13040797db555d82f90600090a250565b6000610afc611900565b6000336108be818585610bf48383611319565b610bfe9190613840565b61150b565b6000818152600360205260409020805460609190610c2090613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c90613745565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b50505050509050919050565b610cad61162f565b610cb76000611a2b565b565b610cc161162f565b610ccc823383611a7b565b5050565b6001600160a01b0381166000908152600d6020526040812054610818565b600060608082808083610d227f0000000000000000000000000000000000000000000000000000000000000000600b611aac565b610d4d7f0000000000000000000000000000000000000000000000000000000000000000600c611aac565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610d848585858585611b57565b5050505050565b6040518060600160405280602a8152602001613f94602a913981565b60606009805461082d90613745565b6001546060906001600160a01b0316336001600160a01b031614610e1c5760405162461bcd60e51b815260206004820181905260248201527f4d61706f4578656375746f723a20696e76616c6964206d6f732063616c6c65726044820152606401610922565b60008881526003602052604081208054610e3590613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6190613745565b8015610eae5780601f10610e8357610100808354040283529160200191610eae565b820191906000526020600020905b815481529060010190602001808311610e9157829003601f168201915b50505050509050805187879050148015610ec9575060008151115b8015610ef1575080516020820120604051610ee79089908990613853565b6040518091039020145b610f505760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c696420736f7572636520636861604482015269696e206164647265737360b01b6064820152608401610922565b610fc7898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a81528c935091508a908a9081908401838280828437600092019190915250611c9a92505050565b9998505050505050505050565b60003381610fe28286611319565b9050838110156110425760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610922565b610b1a828686840361150b565b6000336108be818585611755565b61106561162f565b8281146110c75760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a2061646472657373206f7220636861696e4964604482015269040dcdee840dac2e8c6d60b31b6064820152608401610922565b60005b83811015610d84578282828181106110e4576110e4613863565b90506020028101906110f69190613879565b6003600088888681811061110c5761110c613863565b905060200201358152602001908152602001600020918261112e92919061390d565b5084848281811061114157611141613863565b905060200201357f6e534b334194d22563fa33a8f94163835c7378f39c7770229441983cec7f82a784848481811061117b5761117b613863565b905060200281019061118d9190613879565b60405161119b9291906139cc565b60405180910390a2806111ad816139e0565b9150506110ca565b834211156112055760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610922565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112348c611ded565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061128f82611e15565b9050600061129f82878787611e42565b9050896001600160a01b0316816001600160a01b0316146113025760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610922565b61130d8a8a8a61150b565b50505050505050505050565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b61135387878787878787611e6c565b50505050505050565b61136461162f565b6001600160a01b0381166113c95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610922565b6113d281611a2b565b50565b600360205260009081526040902080546113ee90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461141a90613745565b80156114675780601f1061143c57610100808354040283529160200191611467565b820191906000526020600020905b81548152906001019060200180831161144a57829003601f168201915b505050505081565b600154600254604051634b7157ab60e11b8152600481018590526001600160a01b03918216602482015260448101849052600092839283929116906396e2af56906064016040805180830381865afa1580156114cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f391906139f9565b506002546001600160a01b0316969095509350505050565b6001600160a01b03831661156d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610922565b6001600160a01b0382166115ce5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610922565b6001600160a01b0383811660008181526006602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000546001600160a01b03163314610cb75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b600033306001600160a01b038616148015906116b75750806001600160a01b0316856001600160a01b031614155b156116c7576116c78582856116db565b6116d2858585611755565b50909392505050565b60006116e78484611319565b9050600019811461174f57818110156117425760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610922565b61174f848484840361150b565b50505050565b6001600160a01b0383166117b95760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610922565b6001600160a01b03821661181b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610922565b6001600160a01b038316600090815260056020526040902054818110156118935760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610922565b6001600160a01b0380851660008181526005602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906118f39086815260200190565b60405180910390a361174f565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561195957507f000000000000000000000000000000000000000000000000000000000000000046145b1561198357507f000000000000000000000000000000000000000000000000000000000000000090565b610afc604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611a8483611fb7565b15611a9857611a938282611ff0565b505050565b611a936001600160a01b0384168383612109565b606060ff8314611ac657611abf8361216c565b9050610818565b818054611ad290613745565b80601f0160208091040260200160405190810160405280929190818152602001828054611afe90613745565b8015611b4b5780601f10611b2057610100808354040283529160200191611b4b565b820191906000526020600020905b815481529060010190602001808311611b2e57829003601f168201915b50505050509050610818565b600080611b66878787876121ab565b9150915060008211611bba5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611bc5886121e6565b9050600081878585604051602001611be09493929190613a1e565b604051602081830303815290604052905060007f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c882604051602001611c26929190613a57565b60405160208183030381529060405290506000611c468a6000848a61221c565b9050898b6001600160a01b0316827fe6292bde937d194a85f952b8bc8c86392c382249460fe6d13d860b78956162268c8c604051611c85929190613a70565b60405180910390a45050505050505050505050565b60008281526004602052604090205460609060ff1615611cfc5760405162461bcd60e51b815260206004820152601b60248201527f4d4f52433230436f72653a20696e76616c6964206f72646572496400000000006044820152606401610922565b60008083806020019051810190611d139190613ad7565b6000878152600460205260409020805460ff1916600117905590925090507fe21871479a7cfa5a7e4d0e9ef3698f84fdfb2a3459587d4cec98dfba05a578388201611d6857611d63888683612530565b611de2565b7f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd5738203611d9a57611d638886836125a4565b60405162461bcd60e51b815260206004820181905260248201527f4d4f52433230436f72653a20756e6b6e6f776e206d65737361676520747970656044820152606401610922565b979650505050505050565b6001600160a01b0381166000908152600d602052604090208054600181018255905b50919050565b6000610818611e22611900565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000611e5387878787612810565b91509150611e60816128d1565b5090505b949350505050565b600080611e7b898989896121ab565b9150915060008211611ecf5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611eda8a6121e6565b90506000818985858989604051602001611ef996959493929190613b1d565b604051602081830303815290604052905060007f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57382604051602001611f3f929190613a57565b60405160208183030381529060405290506000611f5f8c6000848c61221c565b90508b8d6001600160a01b0316827f0d11bdbb8fc1f694035f53a0a2073673b4b88caec2faae2b203ae1a97bed389c8e8e88604051611fa093929190613b76565b60405180910390a450505050505050505050505050565b60006001600160a01b038216158061081857506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b804710156120405760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610922565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461208d576040519150601f19603f3d011682016040523d82523d6000602084013e612092565b606091505b5050905080611a935760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a1b565b6060600061217983612af0565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600080336001600160a01b03871681146121ca576121ca8782866116db565b6121d48785612b18565b5050600a548291505b94509492505050565b604051606082811b6bffffffffffffffffffffffff19166020830152906034016040516020818303038152906040529050919050565b6000848152600360205260408120805482919061223890613745565b80601f016020809104026020016040519081016040528092919081815260200182805461226490613745565b80156122b15780601f10612286576101008083540402835291602001916122b1565b820191906000526020600020905b81548152906001019060200180831161229457829003601f168201915b50505050509050600081511161231c5760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c69642072656d6f7465207472756044820152697374206164647265737360b01b6064820152608401610922565b6060856123575760006001838787600060405160200161234196959493929190613bc1565b60405160208183030381529060405290506123cf565b6001860361237c57600080838787600060405160200161234196959493929190613bc1565b60405162461bcd60e51b815260206004820152602260248201527f4d61706f4578656375746f723a20696e76616c6964206d657373616765207479604482015261706560f01b6064820152608401610922565b6000806123dc898761146f565b91509150600081116124305760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c6964206665652076616c7565006044820152606401610922565b6001600160a01b038216612493578034101561248e5760405162461bcd60e51b815260206004820152601960248201527f4d61706f4578656375746f723a20696e76616c696420666565000000000000006044820152606401610922565b6124b7565b61249f82333084612c4c565b6001546124b79083906001600160a01b031683612c84565b60015460405163a39ed3f960e01b81526001600160a01b039091169063a39ed3f99034906124ed908d9088908890600401613c2f565b60206040518083038185885af115801561250b573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610fc79190613c60565b6000806000808480602001905181019061254a9190613c79565b9350935093509350600061255f846014015190565b905061256d81898585612d99565b50508787600080516020613f7483398151915287848760405161259293929190613779565b60405180910390a35050505050505050565b600080600080600080868060200190518101906125c19190613cec565b95509550955095509550955060006125da866014015190565b905060006125ea308c8888612d99565b5090506001600160a01b0382163b6126ac576126113061260b866014015190565b83611689565b508a8a600080516020613f748339815191528a61262f886014015190565b8560405161263f93929190613779565b60405180910390a38a8a7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8a8560006040518060600160405280602a8152602001613f94602a91396040516126979493929190613daa565b60405180910390a35050505050505050505050565b600063190f394060e01b8c8a84868f896040516024016126d196959493929190613de6565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506000806127165a3090609686612df3565b915091508115612774578d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886001604051806020016040528060008152506040516127679493929190613daa565b60405180910390a3612800565b61278930612783896014015190565b86611689565b508d8d600080516020613f748339815191528d6127a78b6014015190565b886040516127b793929190613779565b60405180910390a38d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886000866040516127f79493929190613daa565b60405180910390a35b5050505050505050505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561284757506000905060036121dd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561289b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166128c4576000600192509250506121dd565b9660009650945050505050565b60008160048111156128e5576128e5613bab565b036128ed5750565b600181600481111561290157612901613bab565b0361294e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610922565b600281600481111561296257612962613bab565b036129af5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610922565b60038160048111156129c3576129c3613bab565b036113d25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610922565b6000612a70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e7d9092919063ffffffff16565b9050805160001480612a91575080806020019051810190612a919190613808565b611a935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610922565b600060ff8216601f81111561081857604051632cd44ac360e21b815260040160405180910390fd5b6001600160a01b038216612b785760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610922565b6001600160a01b03821660009081526005602052604090205481811015612bec5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610922565b6001600160a01b03831660008181526005602090815260408083208686039055600780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b038085166024830152831660448201526064810182905261174f9085906323b872dd60e01b90608401612135565b801580612cfe5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfc9190613c60565b155b612d695760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063095ea7b360e01b90606401612135565b60008082600a5403612dad57839150612ddc565b612db883600a613f12565b600a8054612dc591613f12565b612dcf9086613f1e565b612dd99190613f35565b91505b612de68683612e8c565b50600a5494509492505050565b6000606060008060008661ffff166001600160401b03811115612e1857612e186131ca565b6040519080825280601f01601f191660200182016040528015612e42576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612e64578692505b828152826000602083013e909890975095505050505050565b6060611e648484600085612f4d565b6001600160a01b038216612ee25760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610922565b8060076000828254612ef49190613840565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b606082471015612fae5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610922565b600080866001600160a01b03168587604051612fca9190613f57565b60006040518083038185875af1925050503d8060008114613007576040519150601f19603f3d011682016040523d82523d6000602084013e61300c565b606091505b5091509150611de28783838760608315613087578251600003613080576001600160a01b0385163b6130805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610922565b5081611e64565b611e64838381511561309c5781518083602001fd5b8060405162461bcd60e51b81526004016109229190613159565b600080604083850312156130c957600080fd5b50508035926020909101359150565b6000602082840312156130ea57600080fd5b81356001600160e01b03198116811461310257600080fd5b9392505050565b60005b8381101561312457818101518382015260200161310c565b50506000910152565b60008151808452613145816020860160208601613109565b601f01601f19169290920160200192915050565b602081526000613102602083018461312d565b6001600160a01b03811681146113d257600080fd5b6000806040838503121561319457600080fd5b823561319f8161316c565b946020939093013593505050565b6000602082840312156131bf57600080fd5b81356131028161316c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613208576132086131ca565b604052919050565b60006001600160401b03821115613229576132296131ca565b50601f01601f191660200190565b600082601f83011261324857600080fd5b813561325b61325682613210565b6131e0565b81815284602083860101111561327057600080fd5b816020850160208301376000918101602001919091529392505050565b60008083601f84011261329f57600080fd5b5081356001600160401b038111156132b657600080fd5b6020830191508360208285010111156107e057600080fd5b600080600080600080600060c0888a0312156132e957600080fd5b8735965060208801356001600160401b038082111561330757600080fd5b6133138b838c01613237565b975060408a0135965060608a0135915061332c8261316c565b9094506080890135935060a0890135908082111561334957600080fd5b506133568a828b0161328d565b989b979a50959850939692959293505050565b60008060006060848603121561337e57600080fd5b83356133898161316c565b925060208401356133998161316c565b929592945050506040919091013590565b6000602082840312156133bc57600080fd5b5035919050565b60ff60f81b881681526000602060e0818401526133e360e084018a61312d565b83810360408501526133f5818a61312d565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156134475783518352928401929184019160010161342b565b50909c9b505050505050505050505050565b600080600080600060a0868803121561347157600080fd5b853561347c8161316c565b94506020860135935060408601356001600160401b0381111561349e57600080fd5b6134aa88828901613237565b9598949750949560608101359550608001359392505050565b600080600080600080600060a0888a0312156134de57600080fd5b873596506020880135955060408801356001600160401b038082111561350357600080fd5b61350f8b838c0161328d565b909750955060608a0135945060808a013591508082111561334957600080fd5b60008083601f84011261354157600080fd5b5081356001600160401b0381111561355857600080fd5b6020830191508360208260051b85010111156107e057600080fd5b6000806000806040858703121561358957600080fd5b84356001600160401b03808211156135a057600080fd5b6135ac8883890161352f565b909650945060208701359150808211156135c557600080fd5b506135d28782880161352f565b95989497509550505050565b600080600080600080600060e0888a0312156135f957600080fd5b87356136048161316c565b965060208801356136148161316c565b95506040880135945060608801359350608088013560ff8116811461363857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561366857600080fd5b82356136738161316c565b915060208301356136838161316c565b809150509250929050565b600080600080600080600060e0888a0312156136a957600080fd5b87356136b48161316c565b96506020880135955060408801356001600160401b03808211156136d757600080fd5b6136e38b838c01613237565b965060608a0135955060808a0135945060a08a013591508082111561370757600080fd5b6137138b838c01613237565b935060c08a013591508082111561372957600080fd5b506137368a828b01613237565b91505092959891949750929550565b600181811c9082168061375957607f821691505b602082108103611e0f57634e487b7160e01b600052602260045260246000fd5b60608152600061378c606083018661312d565b6001600160a01b039490941660208301525060400152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b86815260a0602082015260006137e960a083018861312d565b8660408401528560608401528281036080840152610fc78185876137a7565b60006020828403121561381a57600080fd5b8151801515811461310257600080fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156108185761081861382a565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261389057600080fd5b8301803591506001600160401b038211156138aa57600080fd5b6020019150368190038213156107e057600080fd5b601f821115611a9357600081815260208120601f850160051c810160208610156138e65750805b601f850160051c820191505b81811015613905578281556001016138f2565b505050505050565b6001600160401b03831115613924576139246131ca565b613938836139328354613745565b836138bf565b6000601f84116001811461396c57600085156139545750838201355b600019600387901b1c1916600186901b178355610d84565b600083815260209020601f19861690835b8281101561399d578685013582556020948501946001909201910161397d565b50868210156139ba5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b602081526000611e646020830184866137a7565b6000600182016139f2576139f261382a565b5060010190565b60008060408385031215613a0c57600080fd5b8251915060208301516136838161316c565b608081526000613a31608083018761312d565b8281036020840152613a43818761312d565b604084019590955250506060015292915050565b828152604060208201526000611e64604083018461312d565b604081526000613a83604083018561312d565b90508260208301529392505050565b600082601f830112613aa357600080fd5b8151613ab161325682613210565b818152846020838601011115613ac657600080fd5b611e64826020830160208701613109565b60008060408385031215613aea57600080fd5b8251915060208301516001600160401b03811115613b0757600080fd5b613b1385828601613a92565b9150509250929050565b60c081526000613b3060c083018961312d565b8281036020840152613b42818961312d565b90508660408401528560608401528281036080840152613b62818661312d565b905082810360a0840152610fc7818561312d565b606081526000613b89606083018661312d565b8460208401528281036040840152613ba1818561312d565b9695505050505050565b634e487b7160e01b600052602160045260246000fd5b8615158152600060028710613be657634e487b7160e01b600052602160045260246000fd5b86602083015260c06040830152613c0060c083018761312d565b8281036060840152613c12818761312d565b91505083608083015260ff831660a0830152979650505050505050565b838152606060208201526000613c48606083018561312d565b905060018060a01b0383166040830152949350505050565b600060208284031215613c7257600080fd5b5051919050565b60008060008060808587031215613c8f57600080fd5b84516001600160401b0380821115613ca657600080fd5b613cb288838901613a92565b95506020870151915080821115613cc857600080fd5b50613cd587828801613a92565b604087015160609097015195989097509350505050565b60008060008060008060c08789031215613d0557600080fd5b86516001600160401b0380821115613d1c57600080fd5b613d288a838b01613a92565b97506020890151915080821115613d3e57600080fd5b613d4a8a838b01613a92565b965060408901519550606089015194506080890151915080821115613d6e57600080fd5b613d7a8a838b01613a92565b935060a0890151915080821115613d9057600080fd5b50613d9d89828a01613a92565b9150509295509295509295565b608081526000613dbd608083018761312d565b6001600160a01b038616602084015284151560408401528281036060840152611de2818561312d565b86815260c060208201526000613dff60c083018861312d565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152610fc7818561312d565b600181815b80851115613e69578160001904821115613e4f57613e4f61382a565b80851615613e5c57918102915b93841c9390800290613e33565b509250929050565b600082613e8057506001610818565b81613e8d57506000610818565b8160018114613ea35760028114613ead57613ec9565b6001915050610818565b60ff841115613ebe57613ebe61382a565b50506001821b610818565b5060208310610133831016604e8410600b8410161715613eec575081810a610818565b613ef68383613e2e565b8060001904821115613f0a57613f0a61382a565b029392505050565b60006131028383613e71565b80820281158282048414176108185761081861382a565b600082613f5257634e487b7160e01b600052601260045260246000fd5b500490565b60008251613f69818460208701613109565b919091019291505056fecac681649d11d73aa22d1f83297c03f511c36a9c26f355bbc6446b1b65278ed4307834653466353435663433346634653534353234313433353435663431343434343532343535333533a2646970667358221220d5f54f3678a011ff4d56dc613b5a415636f45c23826c34dc6b8cd8107913887364736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000008c3ccc219721b206da4a2070fd96e4911a48cb4f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038bcf8d2d48c084b661e3f2b3c514b4244b4d90000000000000000000000000000000000000000000000000000000000000000c4d41502050726f746f636f6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d41504f00000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061025b5760003560e01c8063715018a611610144578063a457c2d7116100b6578063dd62ed3e1161007a578063dd62ed3e14610732578063ea093f3814610752578063f2fde38b14610765578063f32d49f714610785578063f4bf6a711461079b578063fc0c546a146107bb57600080fd5b8063a457c2d71461069b578063a9059cbb146106bb578063c697caec146106db578063d1dedf58146106fb578063d505accf1461071257600080fd5b806387d095b91161010857806387d095b9146105ec5780638da5cb5b146105ff578063950d4fcc1461061d57806395d89b4114610632578063994e919a14610647578063a2784c7a1461066757600080fd5b8063715018a61461055a57806378e3214f1461056f5780637c0ec54a1461058f5780637ecebe00146105a457806384b0196e146105c457600080fd5b806323b872dd116101dd5780633b97e856116101a15780633b97e8561461046a578063561cbfab14610480578063647846a5146104b457806368f3bc74146104d45780636af6400d146104f457806370a082311461052457600080fd5b806323b872dd146103d95780632b8b7b4b146103f9578063313ce567146104195780633644e51514610435578063395093511461044a57600080fd5b806315cce2241161022457806315cce2241461034e57806318160ddd14610370578063190f39401461038f5780631c1992e9146103af5780631e06f826146103c457600080fd5b8062e1d8d01461026057806301ffc9a7146102a457806306fdde03146102d4578063095ea7b3146102f65780631528dd7714610316575b600080fd5b34801561026c57600080fd5b5061028061027b3660046130b6565b6107ce565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b3480156102b057600080fd5b506102c46102bf3660046130d8565b6107e7565b604051901515815260200161029b565b3480156102e057600080fd5b506102e961081e565b60405161029b9190613159565b34801561030257600080fd5b506102c4610311366004613181565b6108b0565b34801561032257600080fd5b50600154610336906001600160a01b031681565b6040516001600160a01b03909116815260200161029b565b34801561035a57600080fd5b5061036e6103693660046131ad565b6108c8565b005b34801561037c57600080fd5b506007545b60405190815260200161029b565b34801561039b57600080fd5b5061036e6103aa3660046132ce565b610975565b3480156103bb57600080fd5b50610381610af1565b3480156103d057600080fd5b50610381600081565b3480156103e557600080fd5b506102c46103f4366004613369565b610b01565b34801561040557600080fd5b5061036e6104143660046131ad565b610b25565b34801561042557600080fd5b506040516012815260200161029b565b34801561044157600080fd5b50610381610bd7565b34801561045657600080fd5b506102c4610465366004613181565b610be1565b34801561047657600080fd5b50610381600a5481565b34801561048c57600080fd5b506103817f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c881565b3480156104c057600080fd5b50600254610336906001600160a01b031681565b3480156104e057600080fd5b506102e96104ef3660046133aa565b610c03565b34801561050057600080fd5b506102c461050f3660046133aa565b60046020526000908152604090205460ff1681565b34801561053057600080fd5b5061038161053f3660046131ad565b6001600160a01b031660009081526005602052604090205490565b34801561056657600080fd5b5061036e610ca5565b34801561057b57600080fd5b5061036e61058a366004613181565b610cb9565b34801561059b57600080fd5b50610381600181565b3480156105b057600080fd5b506103816105bf3660046131ad565b610cd0565b3480156105d057600080fd5b506105d9610cee565b60405161029b97969594939291906133c3565b61036e6105fa366004613459565b610d77565b34801561060b57600080fd5b506000546001600160a01b0316610336565b34801561062957600080fd5b506102e9610d8b565b34801561063e57600080fd5b506102e9610da7565b34801561065357600080fd5b506102e96106623660046134c3565b610db6565b34801561067357600080fd5b506103817f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57381565b3480156106a757600080fd5b506102c46106b6366004613181565b610fd4565b3480156106c757600080fd5b506102c46106d6366004613181565b61104f565b3480156106e757600080fd5b5061036e6106f6366004613573565b61105d565b34801561070757600080fd5b506103816298968081565b34801561071e57600080fd5b5061036e61072d3660046135de565b6111b5565b34801561073e57600080fd5b5061038161074d366004613655565b611319565b61036e61076036600461368e565b611344565b34801561077157600080fd5b5061036e6107803660046131ad565b61135c565b34801561079157600080fd5b5061038161520881565b3480156107a757600080fd5b506102e96107b63660046133aa565b6113d5565b3480156107c757600080fd5b5030610336565b6000806107db848461146f565b915091505b9250929050565b60006001600160e01b03198216634696da6960e11b148061081857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606008805461082d90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461085990613745565b80156108a65780601f1061087b576101008083540402835291602001916108a6565b820191906000526020600020905b81548152906001019060200180831161088957829003601f168201915b5050505050905090565b6000336108be81858561150b565b5060019392505050565b6108d061162f565b6001600160a01b03811661092b5760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c69642066656520746f6b656e0060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f0842bcbb92ca6d47ae89816778a843992dff9b876fad009865e1c5df73d46d1f90600090a250565b3330146109d25760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c6572206d757374206265204d4f52433260448201526430436f726560d81b6064820152608401610922565b60006109df308688611689565b90508784600080516020613f74833981519152898885604051610a0493929190613779565b60405180910390a36000856001600160a01b031663cb05b6f05a8b8b8b8a8a8a6040518863ffffffff1660e01b8152600401610a45969594939291906137d0565b60206040518083038160008887f1158015610a64573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610a899190613808565b905080610ae65760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c4f6e4d4f5243323052656365697665646044820152640819985a5b60da1b6064820152608401610922565b505050505050505050565b6000610afc60075490565b905090565b600033610b0f8582856116db565b610b1a858585611755565b506001949350505050565b610b2d61162f565b6001600160a01b038116610b8d5760405162461bcd60e51b815260206004820152602160248201527f4d61706f4578656375746f723a20696e76616c6964206d6f73206164647265736044820152607360f81b6064820152608401610922565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f4dac21cd18f86f988c6cb57f54a5fc95e6c8e24ad536d4d13040797db555d82f90600090a250565b6000610afc611900565b6000336108be818585610bf48383611319565b610bfe9190613840565b61150b565b6000818152600360205260409020805460609190610c2090613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c90613745565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b50505050509050919050565b610cad61162f565b610cb76000611a2b565b565b610cc161162f565b610ccc823383611a7b565b5050565b6001600160a01b0381166000908152600d6020526040812054610818565b600060608082808083610d227f4d41502050726f746f636f6c000000000000000000000000000000000000000c600b611aac565b610d4d7f3100000000000000000000000000000000000000000000000000000000000001600c611aac565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610d848585858585611b57565b5050505050565b6040518060600160405280602a8152602001613f94602a913981565b60606009805461082d90613745565b6001546060906001600160a01b0316336001600160a01b031614610e1c5760405162461bcd60e51b815260206004820181905260248201527f4d61706f4578656375746f723a20696e76616c6964206d6f732063616c6c65726044820152606401610922565b60008881526003602052604081208054610e3590613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6190613745565b8015610eae5780601f10610e8357610100808354040283529160200191610eae565b820191906000526020600020905b815481529060010190602001808311610e9157829003601f168201915b50505050509050805187879050148015610ec9575060008151115b8015610ef1575080516020820120604051610ee79089908990613853565b6040518091039020145b610f505760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c696420736f7572636520636861604482015269696e206164647265737360b01b6064820152608401610922565b610fc7898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a81528c935091508a908a9081908401838280828437600092019190915250611c9a92505050565b9998505050505050505050565b60003381610fe28286611319565b9050838110156110425760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610922565b610b1a828686840361150b565b6000336108be818585611755565b61106561162f565b8281146110c75760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a2061646472657373206f7220636861696e4964604482015269040dcdee840dac2e8c6d60b31b6064820152608401610922565b60005b83811015610d84578282828181106110e4576110e4613863565b90506020028101906110f69190613879565b6003600088888681811061110c5761110c613863565b905060200201358152602001908152602001600020918261112e92919061390d565b5084848281811061114157611141613863565b905060200201357f6e534b334194d22563fa33a8f94163835c7378f39c7770229441983cec7f82a784848481811061117b5761117b613863565b905060200281019061118d9190613879565b60405161119b9291906139cc565b60405180910390a2806111ad816139e0565b9150506110ca565b834211156112055760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610922565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112348c611ded565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061128f82611e15565b9050600061129f82878787611e42565b9050896001600160a01b0316816001600160a01b0316146113025760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610922565b61130d8a8a8a61150b565b50505050505050505050565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b61135387878787878787611e6c565b50505050505050565b61136461162f565b6001600160a01b0381166113c95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610922565b6113d281611a2b565b50565b600360205260009081526040902080546113ee90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461141a90613745565b80156114675780601f1061143c57610100808354040283529160200191611467565b820191906000526020600020905b81548152906001019060200180831161144a57829003601f168201915b505050505081565b600154600254604051634b7157ab60e11b8152600481018590526001600160a01b03918216602482015260448101849052600092839283929116906396e2af56906064016040805180830381865afa1580156114cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f391906139f9565b506002546001600160a01b0316969095509350505050565b6001600160a01b03831661156d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610922565b6001600160a01b0382166115ce5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610922565b6001600160a01b0383811660008181526006602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000546001600160a01b03163314610cb75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b600033306001600160a01b038616148015906116b75750806001600160a01b0316856001600160a01b031614155b156116c7576116c78582856116db565b6116d2858585611755565b50909392505050565b60006116e78484611319565b9050600019811461174f57818110156117425760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610922565b61174f848484840361150b565b50505050565b6001600160a01b0383166117b95760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610922565b6001600160a01b03821661181b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610922565b6001600160a01b038316600090815260056020526040902054818110156118935760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610922565b6001600160a01b0380851660008181526005602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906118f39086815260200190565b60405180910390a361174f565b6000306001600160a01b037f00000000000000000000000066d79b8f60ec93bfce0b56f5ac14a2714e509a991614801561195957507f000000000000000000000000000000000000000000000000000000000000000146145b1561198357507ff1a6163fe94512e03bdbf1d9f8fdf9c3676f9fb4474f18bd8e496ddd9071926190565b610afc604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f473f7c10b56aad6a3afbd89ffff89f72cec6b014124850bf59110c150e6cd235918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611a8483611fb7565b15611a9857611a938282611ff0565b505050565b611a936001600160a01b0384168383612109565b606060ff8314611ac657611abf8361216c565b9050610818565b818054611ad290613745565b80601f0160208091040260200160405190810160405280929190818152602001828054611afe90613745565b8015611b4b5780601f10611b2057610100808354040283529160200191611b4b565b820191906000526020600020905b815481529060010190602001808311611b2e57829003601f168201915b50505050509050610818565b600080611b66878787876121ab565b9150915060008211611bba5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611bc5886121e6565b9050600081878585604051602001611be09493929190613a1e565b604051602081830303815290604052905060007f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c882604051602001611c26929190613a57565b60405160208183030381529060405290506000611c468a6000848a61221c565b9050898b6001600160a01b0316827fe6292bde937d194a85f952b8bc8c86392c382249460fe6d13d860b78956162268c8c604051611c85929190613a70565b60405180910390a45050505050505050505050565b60008281526004602052604090205460609060ff1615611cfc5760405162461bcd60e51b815260206004820152601b60248201527f4d4f52433230436f72653a20696e76616c6964206f72646572496400000000006044820152606401610922565b60008083806020019051810190611d139190613ad7565b6000878152600460205260409020805460ff1916600117905590925090507fe21871479a7cfa5a7e4d0e9ef3698f84fdfb2a3459587d4cec98dfba05a578388201611d6857611d63888683612530565b611de2565b7f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd5738203611d9a57611d638886836125a4565b60405162461bcd60e51b815260206004820181905260248201527f4d4f52433230436f72653a20756e6b6e6f776e206d65737361676520747970656044820152606401610922565b979650505050505050565b6001600160a01b0381166000908152600d602052604090208054600181018255905b50919050565b6000610818611e22611900565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000611e5387878787612810565b91509150611e60816128d1565b5090505b949350505050565b600080611e7b898989896121ab565b9150915060008211611ecf5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611eda8a6121e6565b90506000818985858989604051602001611ef996959493929190613b1d565b604051602081830303815290604052905060007f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57382604051602001611f3f929190613a57565b60405160208183030381529060405290506000611f5f8c6000848c61221c565b90508b8d6001600160a01b0316827f0d11bdbb8fc1f694035f53a0a2073673b4b88caec2faae2b203ae1a97bed389c8e8e88604051611fa093929190613b76565b60405180910390a450505050505050505050505050565b60006001600160a01b038216158061081857506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b804710156120405760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610922565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461208d576040519150601f19603f3d011682016040523d82523d6000602084013e612092565b606091505b5050905080611a935760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a1b565b6060600061217983612af0565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600080336001600160a01b03871681146121ca576121ca8782866116db565b6121d48785612b18565b5050600a548291505b94509492505050565b604051606082811b6bffffffffffffffffffffffff19166020830152906034016040516020818303038152906040529050919050565b6000848152600360205260408120805482919061223890613745565b80601f016020809104026020016040519081016040528092919081815260200182805461226490613745565b80156122b15780601f10612286576101008083540402835291602001916122b1565b820191906000526020600020905b81548152906001019060200180831161229457829003601f168201915b50505050509050600081511161231c5760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c69642072656d6f7465207472756044820152697374206164647265737360b01b6064820152608401610922565b6060856123575760006001838787600060405160200161234196959493929190613bc1565b60405160208183030381529060405290506123cf565b6001860361237c57600080838787600060405160200161234196959493929190613bc1565b60405162461bcd60e51b815260206004820152602260248201527f4d61706f4578656375746f723a20696e76616c6964206d657373616765207479604482015261706560f01b6064820152608401610922565b6000806123dc898761146f565b91509150600081116124305760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c6964206665652076616c7565006044820152606401610922565b6001600160a01b038216612493578034101561248e5760405162461bcd60e51b815260206004820152601960248201527f4d61706f4578656375746f723a20696e76616c696420666565000000000000006044820152606401610922565b6124b7565b61249f82333084612c4c565b6001546124b79083906001600160a01b031683612c84565b60015460405163a39ed3f960e01b81526001600160a01b039091169063a39ed3f99034906124ed908d9088908890600401613c2f565b60206040518083038185885af115801561250b573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610fc79190613c60565b6000806000808480602001905181019061254a9190613c79565b9350935093509350600061255f846014015190565b905061256d81898585612d99565b50508787600080516020613f7483398151915287848760405161259293929190613779565b60405180910390a35050505050505050565b600080600080600080868060200190518101906125c19190613cec565b95509550955095509550955060006125da866014015190565b905060006125ea308c8888612d99565b5090506001600160a01b0382163b6126ac576126113061260b866014015190565b83611689565b508a8a600080516020613f748339815191528a61262f886014015190565b8560405161263f93929190613779565b60405180910390a38a8a7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8a8560006040518060600160405280602a8152602001613f94602a91396040516126979493929190613daa565b60405180910390a35050505050505050505050565b600063190f394060e01b8c8a84868f896040516024016126d196959493929190613de6565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506000806127165a3090609686612df3565b915091508115612774578d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886001604051806020016040528060008152506040516127679493929190613daa565b60405180910390a3612800565b61278930612783896014015190565b86611689565b508d8d600080516020613f748339815191528d6127a78b6014015190565b886040516127b793929190613779565b60405180910390a38d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886000866040516127f79493929190613daa565b60405180910390a35b5050505050505050505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561284757506000905060036121dd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561289b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166128c4576000600192509250506121dd565b9660009650945050505050565b60008160048111156128e5576128e5613bab565b036128ed5750565b600181600481111561290157612901613bab565b0361294e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610922565b600281600481111561296257612962613bab565b036129af5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610922565b60038160048111156129c3576129c3613bab565b036113d25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610922565b6000612a70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e7d9092919063ffffffff16565b9050805160001480612a91575080806020019051810190612a919190613808565b611a935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610922565b600060ff8216601f81111561081857604051632cd44ac360e21b815260040160405180910390fd5b6001600160a01b038216612b785760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610922565b6001600160a01b03821660009081526005602052604090205481811015612bec5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610922565b6001600160a01b03831660008181526005602090815260408083208686039055600780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b038085166024830152831660448201526064810182905261174f9085906323b872dd60e01b90608401612135565b801580612cfe5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfc9190613c60565b155b612d695760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063095ea7b360e01b90606401612135565b60008082600a5403612dad57839150612ddc565b612db883600a613f12565b600a8054612dc591613f12565b612dcf9086613f1e565b612dd99190613f35565b91505b612de68683612e8c565b50600a5494509492505050565b6000606060008060008661ffff166001600160401b03811115612e1857612e186131ca565b6040519080825280601f01601f191660200182016040528015612e42576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612e64578692505b828152826000602083013e909890975095505050505050565b6060611e648484600085612f4d565b6001600160a01b038216612ee25760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610922565b8060076000828254612ef49190613840565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b606082471015612fae5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610922565b600080866001600160a01b03168587604051612fca9190613f57565b60006040518083038185875af1925050503d8060008114613007576040519150601f19603f3d011682016040523d82523d6000602084013e61300c565b606091505b5091509150611de28783838760608315613087578251600003613080576001600160a01b0385163b6130805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610922565b5081611e64565b611e64838381511561309c5781518083602001fd5b8060405162461bcd60e51b81526004016109229190613159565b600080604083850312156130c957600080fd5b50508035926020909101359150565b6000602082840312156130ea57600080fd5b81356001600160e01b03198116811461310257600080fd5b9392505050565b60005b8381101561312457818101518382015260200161310c565b50506000910152565b60008151808452613145816020860160208601613109565b601f01601f19169290920160200192915050565b602081526000613102602083018461312d565b6001600160a01b03811681146113d257600080fd5b6000806040838503121561319457600080fd5b823561319f8161316c565b946020939093013593505050565b6000602082840312156131bf57600080fd5b81356131028161316c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613208576132086131ca565b604052919050565b60006001600160401b03821115613229576132296131ca565b50601f01601f191660200190565b600082601f83011261324857600080fd5b813561325b61325682613210565b6131e0565b81815284602083860101111561327057600080fd5b816020850160208301376000918101602001919091529392505050565b60008083601f84011261329f57600080fd5b5081356001600160401b038111156132b657600080fd5b6020830191508360208285010111156107e057600080fd5b600080600080600080600060c0888a0312156132e957600080fd5b8735965060208801356001600160401b038082111561330757600080fd5b6133138b838c01613237565b975060408a0135965060608a0135915061332c8261316c565b9094506080890135935060a0890135908082111561334957600080fd5b506133568a828b0161328d565b989b979a50959850939692959293505050565b60008060006060848603121561337e57600080fd5b83356133898161316c565b925060208401356133998161316c565b929592945050506040919091013590565b6000602082840312156133bc57600080fd5b5035919050565b60ff60f81b881681526000602060e0818401526133e360e084018a61312d565b83810360408501526133f5818a61312d565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156134475783518352928401929184019160010161342b565b50909c9b505050505050505050505050565b600080600080600060a0868803121561347157600080fd5b853561347c8161316c565b94506020860135935060408601356001600160401b0381111561349e57600080fd5b6134aa88828901613237565b9598949750949560608101359550608001359392505050565b600080600080600080600060a0888a0312156134de57600080fd5b873596506020880135955060408801356001600160401b038082111561350357600080fd5b61350f8b838c0161328d565b909750955060608a0135945060808a013591508082111561334957600080fd5b60008083601f84011261354157600080fd5b5081356001600160401b0381111561355857600080fd5b6020830191508360208260051b85010111156107e057600080fd5b6000806000806040858703121561358957600080fd5b84356001600160401b03808211156135a057600080fd5b6135ac8883890161352f565b909650945060208701359150808211156135c557600080fd5b506135d28782880161352f565b95989497509550505050565b600080600080600080600060e0888a0312156135f957600080fd5b87356136048161316c565b965060208801356136148161316c565b95506040880135945060608801359350608088013560ff8116811461363857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561366857600080fd5b82356136738161316c565b915060208301356136838161316c565b809150509250929050565b600080600080600080600060e0888a0312156136a957600080fd5b87356136b48161316c565b96506020880135955060408801356001600160401b03808211156136d757600080fd5b6136e38b838c01613237565b965060608a0135955060808a0135945060a08a013591508082111561370757600080fd5b6137138b838c01613237565b935060c08a013591508082111561372957600080fd5b506137368a828b01613237565b91505092959891949750929550565b600181811c9082168061375957607f821691505b602082108103611e0f57634e487b7160e01b600052602260045260246000fd5b60608152600061378c606083018661312d565b6001600160a01b039490941660208301525060400152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b86815260a0602082015260006137e960a083018861312d565b8660408401528560608401528281036080840152610fc78185876137a7565b60006020828403121561381a57600080fd5b8151801515811461310257600080fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156108185761081861382a565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261389057600080fd5b8301803591506001600160401b038211156138aa57600080fd5b6020019150368190038213156107e057600080fd5b601f821115611a9357600081815260208120601f850160051c810160208610156138e65750805b601f850160051c820191505b81811015613905578281556001016138f2565b505050505050565b6001600160401b03831115613924576139246131ca565b613938836139328354613745565b836138bf565b6000601f84116001811461396c57600085156139545750838201355b600019600387901b1c1916600186901b178355610d84565b600083815260209020601f19861690835b8281101561399d578685013582556020948501946001909201910161397d565b50868210156139ba5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b602081526000611e646020830184866137a7565b6000600182016139f2576139f261382a565b5060010190565b60008060408385031215613a0c57600080fd5b8251915060208301516136838161316c565b608081526000613a31608083018761312d565b8281036020840152613a43818761312d565b604084019590955250506060015292915050565b828152604060208201526000611e64604083018461312d565b604081526000613a83604083018561312d565b90508260208301529392505050565b600082601f830112613aa357600080fd5b8151613ab161325682613210565b818152846020838601011115613ac657600080fd5b611e64826020830160208701613109565b60008060408385031215613aea57600080fd5b8251915060208301516001600160401b03811115613b0757600080fd5b613b1385828601613a92565b9150509250929050565b60c081526000613b3060c083018961312d565b8281036020840152613b42818961312d565b90508660408401528560608401528281036080840152613b62818661312d565b905082810360a0840152610fc7818561312d565b606081526000613b89606083018661312d565b8460208401528281036040840152613ba1818561312d565b9695505050505050565b634e487b7160e01b600052602160045260246000fd5b8615158152600060028710613be657634e487b7160e01b600052602160045260246000fd5b86602083015260c06040830152613c0060c083018761312d565b8281036060840152613c12818761312d565b91505083608083015260ff831660a0830152979650505050505050565b838152606060208201526000613c48606083018561312d565b905060018060a01b0383166040830152949350505050565b600060208284031215613c7257600080fd5b5051919050565b60008060008060808587031215613c8f57600080fd5b84516001600160401b0380821115613ca657600080fd5b613cb288838901613a92565b95506020870151915080821115613cc857600080fd5b50613cd587828801613a92565b604087015160609097015195989097509350505050565b60008060008060008060c08789031215613d0557600080fd5b86516001600160401b0380821115613d1c57600080fd5b613d288a838b01613a92565b97506020890151915080821115613d3e57600080fd5b613d4a8a838b01613a92565b965060408901519550606089015194506080890151915080821115613d6e57600080fd5b613d7a8a838b01613a92565b935060a0890151915080821115613d9057600080fd5b50613d9d89828a01613a92565b9150509295509295509295565b608081526000613dbd608083018761312d565b6001600160a01b038616602084015284151560408401528281036060840152611de2818561312d565b86815260c060208201526000613dff60c083018861312d565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152610fc7818561312d565b600181815b80851115613e69578160001904821115613e4f57613e4f61382a565b80851615613e5c57918102915b93841c9390800290613e33565b509250929050565b600082613e8057506001610818565b81613e8d57506000610818565b8160018114613ea35760028114613ead57613ec9565b6001915050610818565b60ff841115613ebe57613ebe61382a565b50506001821b610818565b5060208310610133831016604e8410600b8410161715613eec575081810a610818565b613ef68383613e2e565b8060001904821115613f0a57613f0a61382a565b029392505050565b60006131028383613e71565b80820281158282048414176108185761081861382a565b600082613f5257634e487b7160e01b600052601260045260246000fd5b500490565b60008251613f69818460208701613109565b919091019291505056fecac681649d11d73aa22d1f83297c03f511c36a9c26f355bbc6446b1b65278ed4307834653466353435663433346634653534353234313433353435663431343434343532343535333533a2646970667358221220d5f54f3678a011ff4d56dc613b5a415636f45c23826c34dc6b8cd8107913887364736f6c63430008140033

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

00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000008c3ccc219721b206da4a2070fd96e4911a48cb4f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038bcf8d2d48c084b661e3f2b3c514b4244b4d90000000000000000000000000000000000000000000000000000000000000000c4d41502050726f746f636f6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d41504f00000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): MAP Protocol
Arg [1] : _symbol (string): MAPO
Arg [2] : _mosAddress (address): 0x8C3cCc219721B206DA4A2070fD96E4911a48CB4f
Arg [3] : _initialSupply (uint256): 0
Arg [4] : _owner (address): 0x038BCF8d2d48C084B661E3f2B3c514b4244B4D90

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000008c3ccc219721b206da4a2070fd96e4911a48cb4f
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 000000000000000000000000038bcf8d2d48c084b661e3f2b3c514b4244b4d90
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [6] : 4d41502050726f746f636f6c0000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 4d41504f00000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

167:368:25:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1169:210:33;;;;;;;;;;-1:-1:-1;1169:210:33;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;459:32:35;;;441:51;;523:2;508:18;;501:34;;;;414:18;1169:210:33;;;;;;;;951:212;;;;;;;;;;-1:-1:-1;951:212:33;;;;;:::i;:::-;;:::i;:::-;;;1002:14:35;;995:22;977:41;;965:2;950:18;951:212:33;837:187:35;2158:98:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4444:197::-;;;;;;;;;;-1:-1:-1;4444:197:5;;;;;:::i;:::-;;:::i;605:17:26:-;;;;;;;;;;-1:-1:-1;605:17:26;;;;-1:-1:-1;;;;;605:17:26;;;;;;-1:-1:-1;;;;;2419:32:35;;;2401:51;;2389:2;2374:18;605:17:26;2241:217:35;4172:210:26;;;;;;;;;;-1:-1:-1;4172:210:26;;;;;:::i;:::-;;:::i;:::-;;3255:106:5;;;;;;;;;;-1:-1:-1;3342:12:5;;3255:106;;;2861:25:35;;;2849:2;2834:18;3255:106:5;2715:177:35;4521:862:33;;;;;;;;;;-1:-1:-1;4521:862:33;;;;;:::i;:::-;;:::i;436:111:34:-;;;;;;;;;;;;;:::i;392:48:26:-;;;;;;;;;;;;439:1;392:48;;5203:256:5;;;;;;;;;;-1:-1:-1;5203:256:5;;;;;:::i;:::-;;:::i;4388:199:26:-;;;;;;;;;;-1:-1:-1;4388:199:26;;;;;:::i;:::-;;:::i;3104:91:5:-;;;;;;;;;;-1:-1:-1;3104:91:5;;3186:2;5897:36:35;;5885:2;5870:18;3104:91:5;5755:184:35;2836:113:9;;;;;;;;;;;;;:::i;5854:234:5:-;;;;;;;;;;-1:-1:-1;5854:234:5;;;;;:::i;:::-;;:::i;190:28:34:-;;;;;;;;;;;;;;;;538:87:33;;;;;;;;;;;;584:41;538:87;;628:23:26;;;;;;;;;;-1:-1:-1;628:23:26;;;;-1:-1:-1;;;;;628:23:26;;;3544:139;;;;;;;;;;-1:-1:-1;3544:139:26;;;;;:::i;:::-;;:::i;836:41:33:-;;;;;;;;;;-1:-1:-1;836:41:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;3419:125:5;;;;;;;;;;-1:-1:-1;3419:125:5;;;;;:::i;:::-;-1:-1:-1;;;;;3519:18:5;3493:7;3519:18;;;:9;:18;;;;;;;3419:125;1824:101:2;;;;;;;;;;;;;:::i;4593:135:26:-;;;;;;;;;;-1:-1:-1;4593:135:26;;;;;:::i;:::-;;:::i;446:50::-;;;;;;;;;;;;495:1;446:50;;2603:126:9;;;;;;;;;;-1:-1:-1;2603:126:9;;;;;:::i;:::-;;:::i;5021:633:20:-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;1385:303:33:-;;;;;;:::i;:::-;;:::i;1201:85:2:-;;;;;;;;;;-1:-1:-1;1247:7:2;1273:6;-1:-1:-1;;;;;1273:6:2;1201:85;;740:89:33;;;;;;;;;;;;;:::i;2369:102:5:-;;;;;;;;;;;;;:::i;1039:744:26:-;;;;;;;;;;-1:-1:-1;1039:744:26;;;;;:::i;:::-;;:::i;631:103:33:-;;;;;;;;;;;;686:48;631:103;;6575:427:5;;;;;;;;;;-1:-1:-1;6575:427:5;;;;;:::i;:::-;;:::i;3740:189::-;;;;;;;;;;-1:-1:-1;3740:189:5;;;;;:::i;:::-;;:::i;3689:477:26:-;;;;;;;;;;-1:-1:-1;3689:477:26;;;;;:::i;:::-;;:::i;552:46::-;;;;;;;;;;;;590:8;552:46;;1923:626:9;;;;;;;;;;-1:-1:-1;1923:626:9;;;;;:::i;:::-;;:::i;3987:149:5:-;;;;;;;;;;-1:-1:-1;3987:149:5;;;;;:::i;:::-;;:::i;1694:513:33:-;;;;;;:::i;:::-;;:::i;2074:198:2:-;;;;;;;;;;-1:-1:-1;2074:198:2;;;;;:::i;:::-;;:::i;503:43:26:-;;;;;;;;;;;;541:5;503:43;;657:44;;;;;;;;;;-1:-1:-1;657:44:26;;;;;:::i;:::-;;:::i;553:101:34:-;;;;;;;;;;-1:-1:-1;642:4:34;553:101;;1169:210:33;1289:16;1307:11;1337:35;1352:8;1362:9;1337:14;:35::i;:::-;1330:42;;;;1169:210;;;;;;:::o;951:212::-;1053:4;-1:-1:-1;;;;;;1076:40:33;;-1:-1:-1;;;1076:40:33;;:80;;-1:-1:-1;;;;;;;;;;937:40:21;;;1120:36:33;1069:87;951:212;-1:-1:-1;;951:212:33:o;2158:98:5:-;2212:13;2244:5;2237:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2158:98;:::o;4444:197::-;4527:4;734:10:14;4581:32:5;734:10:14;4597:7:5;4606:6;4581:8;:32::i;:::-;-1:-1:-1;4630:4:5;;4444:197;-1:-1:-1;;;4444:197:5:o;4172:210:26:-;1094:13:2;:11;:13::i;:::-;-1:-1:-1;;;;;4249:23:26;::::1;4241:67;;;::::0;-1:-1:-1;;;4241:67:26;;13845:2:35;4241:67:26::1;::::0;::::1;13827:21:35::0;13884:2;13864:18;;;13857:30;13923:33;13903:18;;;13896:61;13974:18;;4241:67:26::1;;;;;;;;;4318:8;:20:::0;;-1:-1:-1;;;;;;4318:20:26::1;-1:-1:-1::0;;;;;4318:20:26;::::1;::::0;;::::1;::::0;;;4353:22:::1;::::0;::::1;::::0;-1:-1:-1;;4353:22:26::1;4172:210:::0;:::o;4521:862:33:-;734:10:14;4797:4:33;4773:29;4765:79;;;;-1:-1:-1;;;4765:79:33;;14205:2:35;4765:79:33;;;14187:21:35;14244:2;14224:18;;;14217:30;14283:34;14263:18;;;14256:62;-1:-1:-1;;;14334:18:35;;;14327:35;14379:19;;4765:79:33;14003:401:35;4765:79:33;4871:14;4888:55;4910:4;4917:16;4935:7;4888:13;:55::i;:::-;4871:72;;4981:12;4971:8;-1:-1:-1;;;;;;;;;;;4995:12:33;5009:16;5027:6;4958:76;;;;;;;;:::i;:::-;;;;;;;;5101:12;5132:16;-1:-1:-1;;;;;5116:50:33;;5172:9;5196:12;5222;5248:7;5269:8;5291;;5116:193;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5101:208;;5327:7;5319:57;;;;-1:-1:-1;;;5319:57:33;;16181:2:35;5319:57:33;;;16163:21:35;16220:2;16200:18;;;16193:30;16259:34;16239:18;;;16232:62;-1:-1:-1;;;16310:18:35;;;16303:35;16355:19;;5319:57:33;15979:401:35;5319:57:33;4755:628;;4521:862;;;;;;;:::o;436:111:34:-;504:4;527:13;3342:12:5;;;3255:106;527:13:34;520:20;;436:111;:::o;5203:256:5:-;5300:4;734:10:14;5356:38:5;5372:4;734:10:14;5387:6:5;5356:15;:38::i;:::-;5404:27;5414:4;5420:2;5424:6;5404:9;:27::i;:::-;-1:-1:-1;5448:4:5;;5203:256;-1:-1:-1;;;;5203:256:5:o;4388:199:26:-;1094:13:2;:11;:13::i;:::-;-1:-1:-1;;;;;4462:18:26;::::1;4454:64;;;::::0;-1:-1:-1;;;4454:64:26;;16587:2:35;4454:64:26::1;::::0;::::1;16569:21:35::0;16626:2;16606:18;;;16599:30;16665:34;16645:18;;;16638:62;-1:-1:-1;;;16716:18:35;;;16709:31;16757:19;;4454:64:26::1;16385:397:35::0;4454:64:26::1;4528:3;:18:::0;;-1:-1:-1;;;;;;4528:18:26::1;-1:-1:-1::0;;;;;4528:18:26;::::1;::::0;;::::1;::::0;;;4561:19:::1;::::0;::::1;::::0;-1:-1:-1;;4561:19:26::1;4388:199:::0;:::o;2836:113:9:-;2896:7;2922:20;:18;:20::i;5854:234:5:-;5942:4;734:10:14;5996:64:5;734:10:14;6012:7:5;6049:10;6021:25;734:10:14;6012:7:5;6021:9;:25::i;:::-;:38;;;;:::i;:::-;5996:8;:64::i;3544:139:26:-;3649:27;;;;:11;:27;;;;;3642:34;;3618:12;;3649:27;3642:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3544:139;;;:::o;1824:101:2:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;4593:135:26:-;1094:13:2;:11;:13::i;:::-;4676:45:26::1;4693:6;4701:10;4713:7;4676:16;:45::i;:::-;4593:135:::0;;:::o;2603:126:9:-;-1:-1:-1;;;;;2698:14:9;;2672:7;2698:14;;;:7;:14;;;;;918::15;2698:24:9;827:112:15;5021:633:20;5136:13;5163:18;;5136:13;;;5163:18;5427:41;:5;5454:13;5427:26;:41::i;:::-;5482:47;:8;5512:16;5482:29;:47::i;:::-;5621:16;;;5605:1;5621:16;;;;;;;;;-1:-1:-1;;;5376:271:20;;;-1:-1:-1;5376:271:20;;-1:-1:-1;5543:13:20;;-1:-1:-1;5578:4:20;;-1:-1:-1;5605:1:20;-1:-1:-1;5621:16:20;-1:-1:-1;5376:271:20;-1:-1:-1;5021:633:20:o;1385:303:33:-;1605:76;1620:12;1634:10;1646;1658:11;1671:9;1605:14;:76::i;:::-;1385:303;;;;;:::o;740:89::-;;;;;;;;;;;;;;;;;;;:::o;2369:102:5:-;2425:13;2457:7;2450:14;;;;;:::i;1039:744:26:-;1318:3;;1251:23;;-1:-1:-1;;;;;1318:3:26;734:10:14;-1:-1:-1;;;;;1294:28:26;;1286:73;;;;-1:-1:-1;;;1286:73:26;;17251:2:35;1286:73:26;;;17233:21:35;;;17270:18;;;17263:30;17329:34;17309:18;;;17302:62;17381:18;;1286:73:26;17049:356:35;1286:73:26;1370:28;1401:23;;;:11;:23;;;;;1370:54;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1479:15;:22;1456:12;;:19;;:45;:91;;;;;1546:1;1521:15;:22;:26;1456:91;:164;;;;-1:-1:-1;1594:26:26;;;;;;1567:23;;;;1577:12;;;;1567:23;:::i;:::-;;;;;;;;:53;1456:164;1435:253;;;;-1:-1:-1;;;1435:253:26;;17888:2:35;1435:253:26;;;17870:21:35;17927:2;17907:18;;;17900:30;17966:34;17946:18;;;17939:62;-1:-1:-1;;;18017:18:35;;;18010:40;18067:19;;1435:253:26;17686:406:35;1435:253:26;1712:64;1721:10;1733:8;1743:12;;1712:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1712:64:26;;;;;;;;;;;;;;;;;;;;;;1757:8;;-1:-1:-1;1712:64:26;-1:-1:-1;1767:8:26;;;;;;1712:64;;1767:8;;;;1712:64;;;;;;;;;-1:-1:-1;1712:8:26;;-1:-1:-1;;;1712:64:26:i;:::-;1699:77;1039:744;-1:-1:-1;;;;;;;;;1039:744:26:o;6575:427:5:-;6668:4;734:10:14;6668:4:5;6749:25;734:10:14;6766:7:5;6749:9;:25::i;:::-;6722:52;;6812:15;6792:16;:35;;6784:85;;;;-1:-1:-1;;;6784:85:5;;18299:2:35;6784:85:5;;;18281:21:35;18338:2;18318:18;;;18311:30;18377:34;18357:18;;;18350:62;-1:-1:-1;;;18428:18:35;;;18421:35;18473:19;;6784:85:5;18097:401:35;6784:85:5;6903:60;6912:5;6919:7;6947:15;6928:16;:34;6903:8;:60::i;3740:189::-;3819:4;734:10:14;3873:28:5;734:10:14;3890:2:5;3894:6;3873:9;:28::i;3689:477:26:-;1094:13:2;:11;:13::i;:::-;3846:49:26;;::::1;3838:104;;;::::0;-1:-1:-1;;;3838:104:26;;18705:2:35;3838:104:26::1;::::0;::::1;18687:21:35::0;18744:2;18724:18;;;18717:30;18783:34;18763:18;;;18756:62;-1:-1:-1;;;18834:18:35;;;18827:40;18884:19;;3838:104:26::1;18503:406:35::0;3838:104:26::1;3957:9;3952:208;3972:26:::0;;::::1;3952:208;;;4053:16;;4070:1;4053:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;4019:11;:31;4031:15;;4047:1;4031:18;;;;;;;:::i;:::-;;;;;;;4019:31;;;;;;;;;;;:53;;;;;;;:::i;:::-;;4109:15;;4125:1;4109:18;;;;;;;:::i;:::-;;;;;;;4091:58;4129:16;;4146:1;4129:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;4091:58;;;;;;;:::i;:::-;;;;;;;;4000:3:::0;::::1;::::0;::::1;:::i;:::-;;;;3952:208;;1923:626:9::0;2158:8;2139:15;:27;;2131:69;;;;-1:-1:-1;;;2131:69:9;;22215:2:35;2131:69:9;;;22197:21:35;22254:2;22234:18;;;22227:30;22293:31;22273:18;;;22266:59;22342:18;;2131:69:9;22013:353:35;2131:69:9;2211:18;1125:95;2271:5;2278:7;2287:5;2294:16;2304:5;2294:9;:16::i;:::-;2242:79;;;;;;22658:25:35;;;;-1:-1:-1;;;;;22757:15:35;;;22737:18;;;22730:43;22809:15;;;;22789:18;;;22782:43;22841:18;;;22834:34;22884:19;;;22877:35;22928:19;;;22921:35;;;22630:19;;2242:79:9;;;;;;;;;;;;2232:90;;;;;;2211:111;;2333:12;2348:28;2365:10;2348:16;:28::i;:::-;2333:43;;2387:14;2404:28;2418:4;2424:1;2427;2430;2404:13;:28::i;:::-;2387:45;;2460:5;-1:-1:-1;;;;;2450:15:9;:6;-1:-1:-1;;;;;2450:15:9;;2442:58;;;;-1:-1:-1;;;2442:58:9;;23169:2:35;2442:58:9;;;23151:21:35;23208:2;23188:18;;;23181:30;23247:32;23227:18;;;23220:60;23297:18;;2442:58:9;22967:354:35;2442:58:9;2511:31;2520:5;2527:7;2536:5;2511:8;:31::i;:::-;2121:428;;;1923:626;;;;;;;:::o;3987:149:5:-;-1:-1:-1;;;;;4102:18:5;;;4076:7;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3987:149::o;1694:513:33:-;1993:207;2028:12;2054:10;2078;2102:11;2127:9;2150:14;2178:12;1993:21;:207::i;:::-;1694:513;;;;;;;:::o;2074:198:2:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:2;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:2;;23528:2:35;2154:73:2::1;::::0;::::1;23510:21:35::0;23567:2;23547:18;;;23540:30;23606:34;23586:18;;;23579:62;-1:-1:-1;;;23657:18:35;;;23650:36;23703:19;;2154:73:2::1;23326:402:35::0;2154:73:2::1;2237:28;2256:8;2237:18;:28::i;:::-;2074:198:::0;:::o;657:44:26:-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3307:231::-;3450:3;;3478:8;;3450:48;;-1:-1:-1;;;3450:48:26;;;;;23935:25:35;;;-1:-1:-1;;;;;3478:8:26;;;23976:18:35;;;23969:60;24045:18;;;24038:34;;;3391:13:26;;;;;;3450:3;;;:17;;23908:18:35;;3450:48:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3517:8:26;;-1:-1:-1;;;;;3517:8:26;;3432:66;;-1:-1:-1;3307:231:26;-1:-1:-1;;;;3307:231:26:o;10457:340:5:-;-1:-1:-1;;;;;10558:19:5;;10550:68;;;;-1:-1:-1;;;10550:68:5;;24602:2:35;10550:68:5;;;24584:21:35;24641:2;24621:18;;;24614:30;24680:34;24660:18;;;24653:62;-1:-1:-1;;;24731:18:35;;;24724:34;24775:19;;10550:68:5;24400:400:35;10550:68:5;-1:-1:-1;;;;;10636:21:5;;10628:68;;;;-1:-1:-1;;;10628:68:5;;25007:2:35;10628:68:5;;;24989:21:35;25046:2;25026:18;;;25019:30;25085:34;25065:18;;;25058:62;-1:-1:-1;;;25136:18:35;;;25129:32;25178:19;;10628:68:5;24805:398:35;10628:68:5;-1:-1:-1;;;;;10707:18:5;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10758:32;;2861:25:35;;;10758:32:5;;2834:18:35;10758:32:5;;;;;;;10457:340;;;:::o;1359:130:2:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:2;734:10:14;1422:23:2;1414:68;;;;-1:-1:-1;;;1414:68:2;;25410:2:35;1414:68:2;;;25392:21:35;;;25429:18;;;25422:30;25488:34;25468:18;;;25461:62;25540:18;;1414:68:2;25208:356:35;1608:415:34;1711:7;734:10:14;1861:4:34;-1:-1:-1;;;;;1844:22:34;;;;;;:42;;;1879:7;-1:-1:-1;;;;;1870:16:34;:5;-1:-1:-1;;;;;1870:16:34;;;1844:42;1840:113;;;1902:40;1918:5;1925:7;1934;1902:15;:40::i;:::-;1962:30;1972:5;1979:3;1984:7;1962:9;:30::i;:::-;-1:-1:-1;2009:7:34;;1608:415;-1:-1:-1;;;1608:415:34:o;11078:411:5:-;11178:24;11205:25;11215:5;11222:7;11205:9;:25::i;:::-;11178:52;;-1:-1:-1;;11244:16:5;:37;11240:243;;11325:6;11305:16;:26;;11297:68;;;;-1:-1:-1;;;11297:68:5;;25771:2:35;11297:68:5;;;25753:21:35;25810:2;25790:18;;;25783:30;25849:31;25829:18;;;25822:59;25898:18;;11297:68:5;25569:353:35;11297:68:5;11407:51;11416:5;11423:7;11451:6;11432:16;:25;11407:8;:51::i;:::-;11168:321;11078:411;;;:::o;7456:788::-;-1:-1:-1;;;;;7552:18:5;;7544:68;;;;-1:-1:-1;;;7544:68:5;;26129:2:35;7544:68:5;;;26111:21:35;26168:2;26148:18;;;26141:30;26207:34;26187:18;;;26180:62;-1:-1:-1;;;26258:18:35;;;26251:35;26303:19;;7544:68:5;25927:401:35;7544:68:5;-1:-1:-1;;;;;7630:16:5;;7622:64;;;;-1:-1:-1;;;7622:64:5;;26535:2:35;7622:64:5;;;26517:21:35;26574:2;26554:18;;;26547:30;26613:34;26593:18;;;26586:62;-1:-1:-1;;;26664:18:35;;;26657:33;26707:19;;7622:64:5;26333:399:35;7622:64:5;-1:-1:-1;;;;;7768:15:5;;7746:19;7768:15;;;:9;:15;;;;;;7801:21;;;;7793:72;;;;-1:-1:-1;;;7793:72:5;;26939:2:35;7793:72:5;;;26921:21:35;26978:2;26958:18;;;26951:30;27017:34;26997:18;;;26990:62;-1:-1:-1;;;27068:18:35;;;27061:36;27114:19;;7793:72:5;26737:402:35;7793:72:5;-1:-1:-1;;;;;7899:15:5;;;;;;;:9;:15;;;;;;7917:20;;;7899:38;;8114:13;;;;;;;;;;:23;;;;;;8163:26;;;;;;7931:6;2861:25:35;;2849:2;2834:18;;2715:177;8163:26:5;;;;;;;;8200:37;780:250:32;3695:262:20;3748:7;3779:4;-1:-1:-1;;;;;3788:11:20;3771:28;;:63;;;;;3820:14;3803:13;:31;3771:63;3767:184;;;-1:-1:-1;3857:22:20;;3695:262::o;3767:184::-;3917:23;4054:81;;;1929:95;4054:81;;;31747:25:35;4077:11:20;31788:18:35;;;31781:34;;;;4090:14:20;31831:18:35;;;31824:34;4106:13:20;31874:18:35;;;31867:34;4129:4:20;31917:19:35;;;31910:61;4018:7:20;;31719:19:35;;4054:81:20;;;;;;;;;;;;4044:92;;;;;;4037:99;;3963:180;;2426:187:2;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:2;;;-1:-1:-1;;;;;;2534:17:2;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;780:250:32:-;868:17;878:6;868:9;:17::i;:::-;864:160;;;901:40;927:3;933:7;901:17;:40::i;:::-;780:250;;;:::o;864:160::-;972:41;-1:-1:-1;;;;;972:27:32;;1000:3;1005:7;972:27;:41::i;3367:268:16:-;3461:13;1371:66;3490:47;;3486:143;;3560:15;3569:5;3560:8;:15::i;:::-;3553:22;;;;3486:143;3613:5;3606:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2213:797:33;2418:14;2434:16;2454:68;2472:12;2486:10;2498;2510:11;2454:17;:68::i;:::-;2417:105;;;;2550:1;2541:6;:10;2533:51;;;;-1:-1:-1;;;2533:51:33;;27346:2:35;2533:51:33;;;27328:21:35;27385:2;27365:18;;;27358:30;27424;27404:18;;;27397:58;27472:18;;2533:51:33;27144:352:35;2533:51:33;2595:24;2622:29;2638:12;2622:15;:29::i;:::-;2595:56;;2661:23;2698:11;2711:10;2723:6;2731:8;2687:53;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2661:79;;2750:20;584:41;2805:10;2773:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2750:66;;2827:15;2845:69;2861:10;439:1:26;2895:7:33;2904:9;2845:15;:69::i;:::-;2827:87;;2967:10;2953:12;-1:-1:-1;;;;;2930:73:33;2944:7;2930:73;2979:10;2991:11;2930:73;;;;;;;:::i;:::-;;;;;;;;2407:603;;;;;;2213:797;;;;;:::o;7271:751::-;7487:19;;;;:9;:19;;;;;;7454:12;;7487:19;;7486:20;7478:60;;;;-1:-1:-1;;;7478:60:33;;28819:2:35;7478:60:33;;;28801:21:35;28858:2;28838:18;;;28831:30;28897:29;28877:18;;;28870:57;28944:18;;7478:60:33;28617:351:35;7478:60:33;7550:17;7569:20;7604:8;7593:38;;;;;;;;;;;;:::i;:::-;7642:19;;;;:9;:19;;;;;:26;;-1:-1:-1;;7642:26:33;7664:4;7642:26;;;7549:82;;-1:-1:-1;7549:82:33;-1:-1:-1;7683:32:33;;;7679:312;;7731:44;7745:10;7757:8;7767:7;7731:13;:44::i;:::-;7679:312;;;686:48;7796:9;:41;7792:199;;7853:54;7877:10;7889:8;7899:7;7853:23;:54::i;7792:199::-;7938:42;;-1:-1:-1;;;7938:42:33;;30022:2:35;7938:42:33;;;30004:21:35;;;30041:18;;;30034:30;30100:34;30080:18;;;30073:62;30152:18;;7938:42:33;29820:356:35;7792:199:33;8008:7;7271:751;-1:-1:-1;;;;;;;7271:751:33:o;3080:203:9:-;-1:-1:-1;;;;;3200:14:9;;3140:15;3200:14;;;:7;:14;;;;;918::15;;1050:1;1032:19;;;;918:14;3259:17:9;3157:126;3080:203;;;:::o;4768:165:20:-;4845:7;4871:55;4893:20;:18;:20::i;:::-;4915:10;8536:4:19;8530:11;-1:-1:-1;;;8554:23:19;;8606:4;8597:14;;8590:39;;;;8658:4;8649:14;;8642:34;8712:4;8697:20;;;8336:397;6598:232;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:19;-1:-1:-1;6598:232:19;;;;;;;:::o;3016:973:33:-;3300:14;3316:16;3336:68;3354:12;3368:10;3380;3392:11;3336:17;:68::i;:::-;3299:105;;;;3471:1;3462:6;:10;3454:51;;;;-1:-1:-1;;;3454:51:33;;27346:2:35;3454:51:33;;;27328:21:35;27385:2;27365:18;;;27358:30;27424;27404:18;;;27397:58;27472:18;;3454:51:33;27144:352:35;3454:51:33;3516:24;3543:29;3559:12;3543:15;:29::i;:::-;3516:56;;3582:23;3619:11;3632:10;3644:6;3652:8;3662:14;3678:12;3608:83;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3582:109;;3701:20;686:48;3765:10;3724:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3701:75;;3787:15;3805:69;3821:10;439:1:26;3855:7:33;3864:9;3805:15;:69::i;:::-;3787:87;;3934:10;3920:12;-1:-1:-1;;;;;3890:92:33;3911:7;3890:92;3946:10;3958:11;3971:10;3890:92;;;;;;;;:::i;:::-;;;;;;;;3289:700;;;;;;3016:973;;;;;;;:::o;385:137:32:-;442:4;-1:-1:-1;;;;;466:21:32;;;;:48;;-1:-1:-1;;;;;;491:23:32;;336:42;491:23;458:57;385:137;-1:-1:-1;;385:137:32:o;2647:312:13:-;2761:6;2736:21;:31;;2728:73;;;;-1:-1:-1;;;2728:73:13;;32184:2:35;2728:73:13;;;32166:21:35;32223:2;32203:18;;;32196:30;32262:31;32242:18;;;32235:59;32311:18;;2728:73:13;31982:353:35;2728:73:13;2813:12;2831:9;-1:-1:-1;;;;;2831:14:13;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;-1:-1:-1;;;2874:78:13;;32752:2:35;2874:78:13;;;32734:21:35;32791:2;32771:18;;;32764:30;32830:34;32810:18;;;32803:62;32901:28;32881:18;;;32874:56;32947:19;;2874:78:13;32550:422:35;941:175:12;1050:58;;-1:-1:-1;;;;;459:32:35;;1050:58:12;;;441:51:35;508:18;;;501:34;;;1023:86:12;;1043:5;;-1:-1:-1;;;1073:23:12;414:18:35;;1050:58:12;;;;-1:-1:-1;;1050:58:12;;;;;;;;;;;;;;-1:-1:-1;;;;;1050:58:12;-1:-1:-1;;;;;;1050:58:12;;;;;;;;;;1023:19;:86::i;2059:405:16:-;2118:13;2143:11;2157:16;2168:4;2157:10;:16::i;:::-;2281:14;;;2292:2;2281:14;;;;;;;;;2143:30;;-1:-1:-1;2261:17:16;;2281:14;;;;;;;;;-1:-1:-1;;;2371:16:16;;;-1:-1:-1;2416:4:16;2407:14;;2400:28;;;;-1:-1:-1;2371:16:16;2059:405::o;660:449:34:-;826:14;;734:10:14;-1:-1:-1;;;;;914:23:34;;;;910:105;;953:51;969:12;983:7;992:11;953:15;:51::i;:::-;1024:32;1030:12;1044:11;1024:5;:32::i;:::-;-1:-1:-1;;1088:13:34;;1075:11;;-1:-1:-1;660:449:34;;;;;;;;:::o;1461:114:32:-;1546:22;;1516:14;33122:15:35;;;-1:-1:-1;;33118:53:35;1546:22:32;;;33106:66:35;1516:14:32;33188:12:35;;1546:22:32;;;;;;;;;;;;1542:26;;1461:114;;;:::o;2005:1296:26:-;2171:7;2215:21;;;:11;:21;;;;;2190:46;;2171:7;;2215:21;2190:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2273:1;2254:9;:16;:20;2246:75;;;;-1:-1:-1;;;2246:75:26;;33413:2:35;2246:75:26;;;33395:21:35;33452:2;33432:18;;;33425:30;33491:34;33471:18;;;33464:62;-1:-1:-1;;;33542:18:35;;;33535:40;33592:19;;2246:75:26;33211:406:35;2246:75:26;2332:29;2375:7;2371:414;;2452:5;2459:26;2487:9;2498:8;2508:9;2519:1;2441:80;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2422:99;;2371:414;;;495:1;2542:7;:33;2538:247;;2621:5;2628:27;2657:9;2668:8;2678:9;2689:1;2610:81;;;;;;;;;;;;;:::i;2538:247::-;2722:52;;-1:-1:-1;;;2722:52:26;;34819:2:35;2722:52:26;;;34801:21:35;34858:2;34838:18;;;34831:30;34897:34;34877:18;;;34870:62;-1:-1:-1;;;34948:18:35;;;34941:32;34990:19;;2722:52:26;34617:398:35;2722:52:26;2796:13;2811:11;2826:35;2841:8;2851:9;2826:14;:35::i;:::-;2795:66;;;;2885:1;2879:3;:7;2871:51;;;;-1:-1:-1;;;2871:51:26;;35222:2:35;2871:51:26;;;35204:21:35;35261:2;35241:18;;;35234:30;35300:33;35280:18;;;35273:61;35351:18;;2871:51:26;35020:355:35;2871:51:26;-1:-1:-1;;;;;2936:19:26;;2932:277;;2992:3;2979:9;:16;;2971:54;;;;-1:-1:-1;;;2971:54:26;;35582:2:35;2971:54:26;;;35564:21:35;35621:2;35601:18;;;35594:30;35660:27;35640:18;;;35633:55;35705:18;;2971:54:26;35380:349:35;2971:54:26;2932:277;;;3056:73;3090:5;3098:10;3118:4;3125:3;3056:26;:73::i;:::-;3188:3;;3143:55;;3172:5;;-1:-1:-1;;;;;3188:3:26;3194;3143:21;:55::i;:::-;3226:3;;:68;;-1:-1:-1;;;3226:68:26;;-1:-1:-1;;;;;3226:3:26;;;;:15;;3249:9;;3226:68;;3260:8;;3270:16;;3288:5;;3226:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3995:520:33:-;4107:22;4131:26;4159:14;4175:16;4219:8;4195:88;;;;;;;;;;;;:::i;:::-;4106:177;;;;;;;;4293:23;4319:32;4337:13;1435:2:32;1426:12;1420:19;;1304:151;4319:32:33;4293:58;;4361:61;4376:15;4393:10;4405:6;4413:8;4361:14;:61::i;:::-;;;4461:10;4451:8;-1:-1:-1;;;;;;;;;;;4473:9:33;4484:15;4501:6;4438:70;;;;;;;;:::i;:::-;;;;;;;;4096:419;;;;;3995:520;;;:::o;5389:1876::-;5524:23;5561:26;5601:14;5629:16;5659:24;5697;5745:8;5734:68;;;;;;;;;;;;:::i;:::-;5510:292;;;;;;;;;;;;5813:23;5839:32;5857:13;1435:2:32;1426:12;1420:19;;1304:151;5839:32:33;5813:58;;5882:15;5903:59;5926:4;5933:10;5945:6;5953:8;5903:14;:59::i;:::-;-1:-1:-1;5881:81:33;-1:-1:-1;;;;;;5978:26:33;;1702:19:13;5973:376:33;;6022:69;6044:4;6051:30;6069:11;1435:2:32;1426:12;1420:19;;1304:151;6051:30:33;6083:7;6022:13;:69::i;:::-;;6133:10;6123:8;-1:-1:-1;;;;;;;;;;;6145:10:33;6157:30;6175:11;1435:2:32;1426:12;1420:19;;1304:151;6157:30:33;6189:7;6110:87;;;;;;;;:::i;:::-;;;;;;;;6249:10;6239:8;6216:102;6261:10;6273:15;6290:5;6297:20;;;;;;;;;;;;;;;;;6216:102;;;;;;;;;:::i;:::-;;;;;;;;6332:7;;;;;;;;5389:1876;;;:::o;5973:376::-;6359:41;6439:34;;;6487:10;6511;6535:7;6556:15;6585:8;6607:11;6403:225;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;6403:225:33;;;;;;;;;;;;;;-1:-1:-1;;;;;6403:225:33;-1:-1:-1;;;;;;6403:225:33;;;;;;;;;;;-1:-1:-1;;;6677:125:33;6724:9;6685:4;;6747:3;6764:28;6677:33;:125::i;:::-;6639:163;;;;6817:7;6813:446;;;6878:10;6868:8;6845:90;6890:10;6902:15;6919:4;6925:9;;;;;;;;;;;;6845:90;;;;;;;;;:::i;:::-;;;;;;;;6813:446;;;6966:69;6988:4;6995:30;7013:11;1435:2:32;1426:12;1420:19;;1304:151;6995:30:33;7027:7;6966:13;:69::i;:::-;;7077:10;7067:8;-1:-1:-1;;;;;;;;;;;7089:10:33;7101:30;7119:11;1435:2:32;1426:12;1420:19;;1304:151;7101:30:33;7133:7;7054:87;;;;;;;;:::i;:::-;;;;;;;;7193:10;7183:8;7160:88;7205:10;7217:15;7234:5;7241:6;7160:88;;;;;;;;;:::i;:::-;;;;;;;;6813:446;5500:1765;;;;;;;;;;;5389:1876;;;:::o;5009:1456:19:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:19;;-1:-1:-1;6123:30:19;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;39581:25:35;;;39654:4;39642:17;;39622:18;;;39615:45;;;;39676:18;;;39669:34;;;39719:18;;;39712:34;;;6276:24:19;;39553:19:35;;6276:24:19;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:19;;-1:-1:-1;;6276:24:19;;;-1:-1:-1;;;;;;;6314:20:19;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;6437:20;;-1:-1:-1;5009:1456:19;-1:-1:-1;;;;;5009:1456:19:o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:19;;39959:2:35;788:34:19;;;39941:21:35;39998:2;39978:18;;;39971:30;40037:26;40017:18;;;40010:54;40081:18;;788:34:19;39757:348:35;730:345:19;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:19;;40312:2:35;903:41:19;;;40294:21:35;40351:2;40331:18;;;40324:30;40390:33;40370:18;;;40363:61;40441:18;;903:41:19;40110:355:35;839:236:19;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:19;;40672:2:35;1020:44:19;;;40654:21:35;40711:2;40691:18;;;40684:30;40750:34;40730:18;;;40723:62;-1:-1:-1;;;40801:18:35;;;40794:32;40843:19;;1020:44:19;40470:398:35;5196:642:12;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;-1:-1:-1;;;;;5641:27:12;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:12;;41075:2:35;5720:111:12;;;41057:21:35;41114:2;41094:18;;;41087:30;41153:34;41133:18;;;41126:62;-1:-1:-1;;;41204:18:35;;;41197:40;41254:19;;5720:111:12;40873:406:35;2536:245:16;2597:7;2669:4;2633:40;;2696:2;2687:11;;2683:69;;;2721:20;;-1:-1:-1;;;2721:20:16;;;;;;;;;;;9375:659:5;-1:-1:-1;;;;;9458:21:5;;9450:67;;;;-1:-1:-1;;;9450:67:5;;41486:2:35;9450:67:5;;;41468:21:35;41525:2;41505:18;;;41498:30;41564:34;41544:18;;;41537:62;-1:-1:-1;;;41615:18:35;;;41608:31;41656:19;;9450:67:5;41284:397:35;9450:67:5;-1:-1:-1;;;;;9613:18:5;;9588:22;9613:18;;;:9;:18;;;;;;9649:24;;;;9641:71;;;;-1:-1:-1;;;9641:71:5;;41888:2:35;9641:71:5;;;41870:21:35;41927:2;41907:18;;;41900:30;41966:34;41946:18;;;41939:62;-1:-1:-1;;;42017:18:35;;;42010:32;42059:19;;9641:71:5;41686:398:35;9641:71:5;-1:-1:-1;;;;;9746:18:5;;;;;;:9;:18;;;;;;;;9767:23;;;9746:44;;9883:12;:22;;;;;;;9931:37;2861:25:35;;;9746:18:5;;;9931:37;;2834:18:35;9931:37:5;;;;;;;780:250:32;;;:::o;1355:203:12:-;1482:68;;-1:-1:-1;;;;;42347:15:35;;;1482:68:12;;;42329:34:35;42399:15;;42379:18;;;42372:43;42431:18;;;42424:34;;;1455:96:12;;1475:5;;-1:-1:-1;;;1505:27:12;42264:18:35;;1482:68:12;42089:375:35;1818:573:12;2143:10;;;2142:62;;-1:-1:-1;2159:39:12;;-1:-1:-1;;;2159:39:12;;2183:4;2159:39;;;42681:34:35;-1:-1:-1;;;;;42751:15:35;;;42731:18;;;42724:43;2159:15:12;;;;;42616:18:35;;2159:39:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2142:62;2121:163;;;;-1:-1:-1;;;2121:163:12;;43169:2:35;2121:163:12;;;43151:21:35;43208:2;43188:18;;;43181:30;43247:34;43227:18;;;43220:62;-1:-1:-1;;;43298:18:35;;;43291:52;43360:19;;2121:163:12;42967:418:35;2121:163:12;2321:62;;-1:-1:-1;;;;;459:32:35;;2321:62:12;;;441:51:35;508:18;;;501:34;;;2294:90:12;;2314:5;;-1:-1:-1;;;2344:22:12;414:18:35;;2321:62:12;267:274:35;1115:487:34;1291:14;1307:16;1356:13;1339;;:30;1335:178;;1394:11;1385:20;;1335:178;;;1483:19;1489:13;1483:2;:19;:::i;:::-;1466:13;;;1460:19;;;:::i;:::-;1446:33;;:11;:33;:::i;:::-;1445:57;;;;:::i;:::-;1436:66;;1335:178;1523:31;1529:16;1547:6;1523:5;:31::i;:::-;-1:-1:-1;1581:13:34;;1115:487;;;;;;;:::o;1100:1280:31:-;1257:4;1263:12;1323:15;1348:13;1371:24;1408:8;1398:19;;-1:-1:-1;;;;;1398:19:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1398:19:31;;1371:46;;1914:1;1885;1848:9;1842:16;1810:4;1799:9;1795:20;1761:1;1723:7;1694:4;1672:267;1660:279;;2006:16;1995:27;;2050:8;2041:7;2038:21;2035:76;;;2089:8;2078:19;;2035:76;2196:7;2183:11;2176:28;2316:7;2313:1;2306:4;2293:11;2289:22;2274:50;2351:8;;;;-1:-1:-1;1100:1280:31;-1:-1:-1;;;;;;1100:1280:31:o;4108:223:13:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4272:21;:52::i;8520:535:5:-;-1:-1:-1;;;;;8603:21:5;;8595:65;;;;-1:-1:-1;;;8595:65:5;;45361:2:35;8595:65:5;;;45343:21:35;45400:2;45380:18;;;45373:30;45439:33;45419:18;;;45412:61;45490:18;;8595:65:5;45159:355:35;8595:65:5;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:5;;;;;;:9;:18;;;;;;;;:28;;;;;;8952:37;2861:25:35;;;8952:37:5;;2834:18:35;8952:37:5;;;;;;;4593:135:26;;:::o;5165:446:13:-;5330:12;5387:5;5362:21;:30;;5354:81;;;;-1:-1:-1;;;5354:81:13;;45721:2:35;5354:81:13;;;45703:21:35;45760:2;45740:18;;;45733:30;45799:34;45779:18;;;45772:62;-1:-1:-1;;;45850:18:35;;;45843:36;45896:19;;5354:81:13;45519:402:35;5354:81:13;5446:12;5460:23;5487:6;-1:-1:-1;;;;;5487:11:13;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;7851;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;-1:-1:-1;;;;;1702:19:13;;;8113:60;;;;-1:-1:-1;;;8113:60:13;;46420:2:35;8113:60:13;;;46402:21:35;46459:2;46439:18;;;46432:30;46498:31;46478:18;;;46471:59;46547:18;;8113:60:13;46218:353:35;8113:60:13;-1:-1:-1;8208:10:13;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:13;;;;;;;;:::i;14:248:35:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:35;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:35:o;546:286::-;604:6;657:2;645:9;636:7;632:23;628:32;625:52;;;673:1;670;663:12;625:52;699:23;;-1:-1:-1;;;;;;751:32:35;;741:43;;731:71;;798:1;795;788:12;731:71;821:5;546:286;-1:-1:-1;;;546:286:35:o;1029:250::-;1114:1;1124:113;1138:6;1135:1;1132:13;1124:113;;;1214:11;;;1208:18;1195:11;;;1188:39;1160:2;1153:10;1124:113;;;-1:-1:-1;;1271:1:35;1253:16;;1246:27;1029:250::o;1284:271::-;1326:3;1364:5;1358:12;1391:6;1386:3;1379:19;1407:76;1476:6;1469:4;1464:3;1460:14;1453:4;1446:5;1442:16;1407:76;:::i;:::-;1537:2;1516:15;-1:-1:-1;;1512:29:35;1503:39;;;;1544:4;1499:50;;1284:271;-1:-1:-1;;1284:271:35:o;1560:220::-;1709:2;1698:9;1691:21;1672:4;1729:45;1770:2;1759:9;1755:18;1747:6;1729:45;:::i;1785:131::-;-1:-1:-1;;;;;1860:31:35;;1850:42;;1840:70;;1906:1;1903;1896:12;1921:315;1989:6;1997;2050:2;2038:9;2029:7;2025:23;2021:32;2018:52;;;2066:1;2063;2056:12;2018:52;2105:9;2092:23;2124:31;2149:5;2124:31;:::i;:::-;2174:5;2226:2;2211:18;;;;2198:32;;-1:-1:-1;;;1921:315:35:o;2463:247::-;2522:6;2575:2;2563:9;2554:7;2550:23;2546:32;2543:52;;;2591:1;2588;2581:12;2543:52;2630:9;2617:23;2649:31;2674:5;2649:31;:::i;2897:127::-;2958:10;2953:3;2949:20;2946:1;2939:31;2989:4;2986:1;2979:15;3013:4;3010:1;3003:15;3029:275;3100:2;3094:9;3165:2;3146:13;;-1:-1:-1;;3142:27:35;3130:40;;-1:-1:-1;;;;;3185:34:35;;3221:22;;;3182:62;3179:88;;;3247:18;;:::i;:::-;3283:2;3276:22;3029:275;;-1:-1:-1;3029:275:35:o;3309:186::-;3357:4;-1:-1:-1;;;;;3382:6:35;3379:30;3376:56;;;3412:18;;:::i;:::-;-1:-1:-1;3478:2:35;3457:15;-1:-1:-1;;3453:29:35;3484:4;3449:40;;3309:186::o;3500:462::-;3542:5;3595:3;3588:4;3580:6;3576:17;3572:27;3562:55;;3613:1;3610;3603:12;3562:55;3649:6;3636:20;3680:48;3696:31;3724:2;3696:31;:::i;:::-;3680:48;:::i;:::-;3753:2;3744:7;3737:19;3799:3;3792:4;3787:2;3779:6;3775:15;3771:26;3768:35;3765:55;;;3816:1;3813;3806:12;3765:55;3881:2;3874:4;3866:6;3862:17;3855:4;3846:7;3842:18;3829:55;3929:1;3904:16;;;3922:4;3900:27;3893:38;;;;3908:7;3500:462;-1:-1:-1;;;3500:462:35:o;3967:347::-;4018:8;4028:6;4082:3;4075:4;4067:6;4063:17;4059:27;4049:55;;4100:1;4097;4090:12;4049:55;-1:-1:-1;4123:20:35;;-1:-1:-1;;;;;4155:30:35;;4152:50;;;4198:1;4195;4188:12;4152:50;4235:4;4227:6;4223:17;4211:29;;4287:3;4280:4;4271:6;4263;4259:19;4255:30;4252:39;4249:59;;;4304:1;4301;4294:12;4319:970;4443:6;4451;4459;4467;4475;4483;4491;4544:3;4532:9;4523:7;4519:23;4515:33;4512:53;;;4561:1;4558;4551:12;4512:53;4597:9;4584:23;4574:33;;4658:2;4647:9;4643:18;4630:32;-1:-1:-1;;;;;4722:2:35;4714:6;4711:14;4708:34;;;4738:1;4735;4728:12;4708:34;4761:49;4802:7;4793:6;4782:9;4778:22;4761:49;:::i;:::-;4751:59;;4857:2;4846:9;4842:18;4829:32;4819:42;;4911:2;4900:9;4896:18;4883:32;4870:45;;4924:31;4949:5;4924:31;:::i;:::-;4974:5;;-1:-1:-1;5026:3:35;5011:19;;4998:33;;-1:-1:-1;5084:3:35;5069:19;;5056:33;;5101:16;;;5098:36;;;5130:1;5127;5120:12;5098:36;;5169:60;5221:7;5210:8;5199:9;5195:24;5169:60;:::i;:::-;4319:970;;;;-1:-1:-1;4319:970:35;;-1:-1:-1;4319:970:35;;;;5143:86;;-1:-1:-1;;;4319:970:35:o;5294:456::-;5371:6;5379;5387;5440:2;5428:9;5419:7;5415:23;5411:32;5408:52;;;5456:1;5453;5446:12;5408:52;5495:9;5482:23;5514:31;5539:5;5514:31;:::i;:::-;5564:5;-1:-1:-1;5621:2:35;5606:18;;5593:32;5634:33;5593:32;5634:33;:::i;:::-;5294:456;;5686:7;;-1:-1:-1;;;5740:2:35;5725:18;;;;5712:32;;5294:456::o;6334:180::-;6393:6;6446:2;6434:9;6425:7;6421:23;6417:32;6414:52;;;6462:1;6459;6452:12;6414:52;-1:-1:-1;6485:23:35;;6334:180;-1:-1:-1;6334:180:35:o;6927:1259::-;7333:3;7328;7324:13;7316:6;7312:26;7301:9;7294:45;7275:4;7358:2;7396:3;7391:2;7380:9;7376:18;7369:31;7423:46;7464:3;7453:9;7449:19;7441:6;7423:46;:::i;:::-;7517:9;7509:6;7505:22;7500:2;7489:9;7485:18;7478:50;7551:33;7577:6;7569;7551:33;:::i;:::-;7615:2;7600:18;;7593:34;;;-1:-1:-1;;;;;7664:32:35;;7658:3;7643:19;;7636:61;7684:3;7713:19;;7706:35;;;7778:22;;;7772:3;7757:19;;7750:51;7850:13;;7872:22;;;7948:15;;;;-1:-1:-1;7910:15:35;;;;-1:-1:-1;7991:169:35;8005:6;8002:1;7999:13;7991:169;;;8066:13;;8054:26;;8135:15;;;;8100:12;;;;8027:1;8020:9;7991:169;;;-1:-1:-1;8177:3:35;;6927:1259;-1:-1:-1;;;;;;;;;;;;6927:1259:35:o;8191:661::-;8295:6;8303;8311;8319;8327;8380:3;8368:9;8359:7;8355:23;8351:33;8348:53;;;8397:1;8394;8387:12;8348:53;8436:9;8423:23;8455:31;8480:5;8455:31;:::i;:::-;8505:5;-1:-1:-1;8557:2:35;8542:18;;8529:32;;-1:-1:-1;8612:2:35;8597:18;;8584:32;-1:-1:-1;;;;;8628:30:35;;8625:50;;;8671:1;8668;8661:12;8625:50;8694:49;8735:7;8726:6;8715:9;8711:22;8694:49;:::i;:::-;8191:661;;;;-1:-1:-1;8684:59:35;;8790:2;8775:18;;8762:32;;-1:-1:-1;8841:3:35;8826:19;8813:33;;8191:661;-1:-1:-1;;;8191:661:35:o;8857:923::-;8974:6;8982;8990;8998;9006;9014;9022;9075:3;9063:9;9054:7;9050:23;9046:33;9043:53;;;9092:1;9089;9082:12;9043:53;9128:9;9115:23;9105:33;;9185:2;9174:9;9170:18;9157:32;9147:42;;9240:2;9229:9;9225:18;9212:32;-1:-1:-1;;;;;9304:2:35;9296:6;9293:14;9290:34;;;9320:1;9317;9310:12;9290:34;9359:58;9409:7;9400:6;9389:9;9385:22;9359:58;:::i;:::-;9436:8;;-1:-1:-1;9333:84:35;-1:-1:-1;9518:2:35;9503:18;;9490:32;;-1:-1:-1;9575:3:35;9560:19;;9547:33;;-1:-1:-1;9592:16:35;;;9589:36;;;9621:1;9618;9611:12;9785:367;9848:8;9858:6;9912:3;9905:4;9897:6;9893:17;9889:27;9879:55;;9930:1;9927;9920:12;9879:55;-1:-1:-1;9953:20:35;;-1:-1:-1;;;;;9985:30:35;;9982:50;;;10028:1;10025;10018:12;9982:50;10065:4;10057:6;10053:17;10041:29;;10125:3;10118:4;10108:6;10105:1;10101:14;10093:6;10089:27;10085:38;10082:47;10079:67;;;10142:1;10139;10132:12;10157:784;10290:6;10298;10306;10314;10367:2;10355:9;10346:7;10342:23;10338:32;10335:52;;;10383:1;10380;10373:12;10335:52;10423:9;10410:23;-1:-1:-1;;;;;10493:2:35;10485:6;10482:14;10479:34;;;10509:1;10506;10499:12;10479:34;10548:70;10610:7;10601:6;10590:9;10586:22;10548:70;:::i;:::-;10637:8;;-1:-1:-1;10522:96:35;-1:-1:-1;10725:2:35;10710:18;;10697:32;;-1:-1:-1;10741:16:35;;;10738:36;;;10770:1;10767;10760:12;10738:36;;10809:72;10873:7;10862:8;10851:9;10847:24;10809:72;:::i;:::-;10157:784;;;;-1:-1:-1;10900:8:35;-1:-1:-1;;;;10157:784:35:o;10946:829::-;11057:6;11065;11073;11081;11089;11097;11105;11158:3;11146:9;11137:7;11133:23;11129:33;11126:53;;;11175:1;11172;11165:12;11126:53;11214:9;11201:23;11233:31;11258:5;11233:31;:::i;:::-;11283:5;-1:-1:-1;11340:2:35;11325:18;;11312:32;11353:33;11312:32;11353:33;:::i;:::-;11405:7;-1:-1:-1;11459:2:35;11444:18;;11431:32;;-1:-1:-1;11510:2:35;11495:18;;11482:32;;-1:-1:-1;11566:3:35;11551:19;;11538:33;11615:4;11602:18;;11590:31;;11580:59;;11635:1;11632;11625:12;11580:59;10946:829;;;;-1:-1:-1;10946:829:35;;;;11658:7;11712:3;11697:19;;11684:33;;-1:-1:-1;11764:3:35;11749:19;;;11736:33;;10946:829;-1:-1:-1;;10946:829:35:o;11780:388::-;11848:6;11856;11909:2;11897:9;11888:7;11884:23;11880:32;11877:52;;;11925:1;11922;11915:12;11877:52;11964:9;11951:23;11983:31;12008:5;11983:31;:::i;:::-;12033:5;-1:-1:-1;12090:2:35;12075:18;;12062:32;12103:33;12062:32;12103:33;:::i;:::-;12155:7;12145:17;;;11780:388;;;;;:::o;12173:1080::-;12313:6;12321;12329;12337;12345;12353;12361;12414:3;12402:9;12393:7;12389:23;12385:33;12382:53;;;12431:1;12428;12421:12;12382:53;12470:9;12457:23;12489:31;12514:5;12489:31;:::i;:::-;12539:5;-1:-1:-1;12591:2:35;12576:18;;12563:32;;-1:-1:-1;12646:2:35;12631:18;;12618:32;-1:-1:-1;;;;;12699:14:35;;;12696:34;;;12726:1;12723;12716:12;12696:34;12749:49;12790:7;12781:6;12770:9;12766:22;12749:49;:::i;:::-;12739:59;;12845:2;12834:9;12830:18;12817:32;12807:42;;12896:3;12885:9;12881:19;12868:33;12858:43;;12954:3;12943:9;12939:19;12926:33;12910:49;;12984:2;12974:8;12971:16;12968:36;;;13000:1;12997;12990:12;12968:36;13023:51;13066:7;13055:8;13044:9;13040:24;13023:51;:::i;:::-;13013:61;;13127:3;13116:9;13112:19;13099:33;13083:49;;13157:2;13147:8;13144:16;13141:36;;;13173:1;13170;13163:12;13141:36;;13196:51;13239:7;13228:8;13217:9;13213:24;13196:51;:::i;:::-;13186:61;;;12173:1080;;;;;;;;;;:::o;13258:380::-;13337:1;13333:12;;;;13380;;;13401:61;;13455:4;13447:6;13443:17;13433:27;;13401:61;13508:2;13500:6;13497:14;13477:18;13474:38;13471:161;;13554:10;13549:3;13545:20;13542:1;13535:31;13589:4;13586:1;13579:15;13617:4;13614:1;13607:15;14409:386;14612:2;14601:9;14594:21;14575:4;14632:45;14673:2;14662:9;14658:18;14650:6;14632:45;:::i;:::-;-1:-1:-1;;;;;14713:32:35;;;;14708:2;14693:18;;14686:60;-1:-1:-1;14777:2:35;14762:18;14755:34;14624:53;14409:386;-1:-1:-1;14409:386:35:o;14800:266::-;14888:6;14883:3;14876:19;14940:6;14933:5;14926:4;14921:3;14917:14;14904:43;-1:-1:-1;14992:1:35;14967:16;;;14985:4;14963:27;;;14956:38;;;;15048:2;15027:15;;;-1:-1:-1;;15023:29:35;15014:39;;;15010:50;;14800:266::o;15071:621::-;15358:6;15347:9;15340:25;15401:3;15396:2;15385:9;15381:18;15374:31;15321:4;15428:46;15469:3;15458:9;15454:19;15446:6;15428:46;:::i;:::-;15510:6;15505:2;15494:9;15490:18;15483:34;15553:6;15548:2;15537:9;15533:18;15526:34;15609:9;15601:6;15597:22;15591:3;15580:9;15576:19;15569:51;15637:49;15679:6;15671;15663;15637:49;:::i;15697:277::-;15764:6;15817:2;15805:9;15796:7;15792:23;15788:32;15785:52;;;15833:1;15830;15823:12;15785:52;15865:9;15859:16;15918:5;15911:13;15904:21;15897:5;15894:32;15884:60;;15940:1;15937;15930:12;16787:127;16848:10;16843:3;16839:20;16836:1;16829:31;16879:4;16876:1;16869:15;16903:4;16900:1;16893:15;16919:125;16984:9;;;17005:10;;;17002:36;;;17018:18;;:::i;17410:271::-;17593:6;17585;17580:3;17567:33;17549:3;17619:16;;17644:13;;;17619:16;17410:271;-1:-1:-1;17410:271:35:o;18914:127::-;18975:10;18970:3;18966:20;18963:1;18956:31;19006:4;19003:1;18996:15;19030:4;19027:1;19020:15;19046:521;19123:4;19129:6;19189:11;19176:25;19283:2;19279:7;19268:8;19252:14;19248:29;19244:43;19224:18;19220:68;19210:96;;19302:1;19299;19292:12;19210:96;19329:33;;19381:20;;;-1:-1:-1;;;;;;19413:30:35;;19410:50;;;19456:1;19453;19446:12;19410:50;19489:4;19477:17;;-1:-1:-1;19520:14:35;19516:27;;;19506:38;;19503:58;;;19557:1;19554;19547:12;19697:544;19798:2;19793:3;19790:11;19787:448;;;19834:1;19859:5;19855:2;19848:17;19904:4;19900:2;19890:19;19974:2;19962:10;19958:19;19955:1;19951:27;19945:4;19941:38;20010:4;19998:10;19995:20;19992:47;;;-1:-1:-1;20033:4:35;19992:47;20088:2;20083:3;20079:12;20076:1;20072:20;20066:4;20062:31;20052:41;;20143:82;20161:2;20154:5;20151:13;20143:82;;;20206:17;;;20187:1;20176:13;20143:82;;;20147:3;;;19697:544;;;:::o;20417:1202::-;-1:-1:-1;;;;;20534:3:35;20531:27;20528:53;;;20561:18;;:::i;:::-;20590:93;20679:3;20639:38;20671:4;20665:11;20639:38;:::i;:::-;20633:4;20590:93;:::i;:::-;20709:1;20734:2;20729:3;20726:11;20751:1;20746:615;;;;21405:1;21422:3;21419:93;;;-1:-1:-1;21478:19:35;;;21465:33;21419:93;-1:-1:-1;;20374:1:35;20370:11;;;20366:24;20362:29;20352:40;20398:1;20394:11;;;20349:57;21525:78;;20719:894;;20746:615;19644:1;19637:14;;;19681:4;19668:18;;-1:-1:-1;;20782:17:35;;;20882:9;20904:229;20918:7;20915:1;20912:14;20904:229;;;21007:19;;;20994:33;20979:49;;21114:4;21099:20;;;;21067:1;21055:14;;;;20934:12;20904:229;;;20908:3;21161;21152:7;21149:16;21146:159;;;21285:1;21281:6;21275:3;21269;21266:1;21262:11;21258:21;21254:34;21250:39;21237:9;21232:3;21228:19;21215:33;21211:79;21203:6;21196:95;21146:159;;;21348:1;21342:3;21339:1;21335:11;21331:19;21325:4;21318:33;20719:894;;20417:1202;;;:::o;21624:244::-;21781:2;21770:9;21763:21;21744:4;21801:61;21858:2;21847:9;21843:18;21835:6;21827;21801:61;:::i;21873:135::-;21912:3;21933:17;;;21930:43;;21953:18;;:::i;:::-;-1:-1:-1;22000:1:35;21989:13;;21873:135::o;24083:312::-;24162:6;24170;24223:2;24211:9;24202:7;24198:23;24194:32;24191:52;;;24239:1;24236;24229:12;24191:52;24268:9;24262:16;24252:26;;24321:2;24310:9;24306:18;24300:25;24334:31;24359:5;24334:31;:::i;27501:523::-;27750:3;27739:9;27732:22;27713:4;27777:46;27818:3;27807:9;27803:19;27795:6;27777:46;:::i;:::-;27871:9;27863:6;27859:22;27854:2;27843:9;27839:18;27832:50;27899:33;27925:6;27917;27899:33;:::i;:::-;27963:2;27948:18;;27941:34;;;;-1:-1:-1;;28006:2:35;27991:18;27984:34;27891:41;27501:523;-1:-1:-1;;27501:523:35:o;28029:289::-;28204:6;28193:9;28186:25;28247:2;28242;28231:9;28227:18;28220:30;28167:4;28267:45;28308:2;28297:9;28293:18;28285:6;28267:45;:::i;28323:289::-;28498:2;28487:9;28480:21;28461:4;28518:45;28559:2;28548:9;28544:18;28536:6;28518:45;:::i;:::-;28510:53;;28599:6;28594:2;28583:9;28579:18;28572:34;28323:289;;;;;:::o;28973:441::-;29026:5;29079:3;29072:4;29064:6;29060:17;29056:27;29046:55;;29097:1;29094;29087:12;29046:55;29126:6;29120:13;29157:48;29173:31;29201:2;29173:31;:::i;29157:48::-;29230:2;29221:7;29214:19;29276:3;29269:4;29264:2;29256:6;29252:15;29248:26;29245:35;29242:55;;;29293:1;29290;29283:12;29242:55;29306:77;29380:2;29373:4;29364:7;29360:18;29353:4;29345:6;29341:17;29306:77;:::i;29419:396::-;29507:6;29515;29568:2;29556:9;29547:7;29543:23;29539:32;29536:52;;;29584:1;29581;29574:12;29536:52;29613:9;29607:16;29597:26;;29667:2;29656:9;29652:18;29646:25;-1:-1:-1;;;;;29686:6:35;29683:30;29680:50;;;29726:1;29723;29716:12;29680:50;29749:60;29801:7;29792:6;29781:9;29777:22;29749:60;:::i;:::-;29739:70;;;29419:396;;;;;:::o;30181:847::-;30522:3;30511:9;30504:22;30485:4;30549:46;30590:3;30579:9;30575:19;30567:6;30549:46;:::i;:::-;30643:9;30635:6;30631:22;30626:2;30615:9;30611:18;30604:50;30677:33;30703:6;30695;30677:33;:::i;:::-;30663:47;;30746:6;30741:2;30730:9;30726:18;30719:34;30789:6;30784:2;30773:9;30769:18;30762:34;30845:9;30837:6;30833:22;30827:3;30816:9;30812:19;30805:51;30879:33;30905:6;30897;30879:33;:::i;:::-;30865:47;;30961:9;30953:6;30949:22;30943:3;30932:9;30928:19;30921:51;30989:33;31015:6;31007;30989:33;:::i;31033:450::-;31254:2;31243:9;31236:21;31217:4;31280:45;31321:2;31310:9;31306:18;31298:6;31280:45;:::i;:::-;31361:6;31356:2;31345:9;31341:18;31334:34;31416:9;31408:6;31404:22;31399:2;31388:9;31384:18;31377:50;31444:33;31470:6;31462;31444:33;:::i;:::-;31436:41;31033:450;-1:-1:-1;;;;;;31033:450:35:o;33622:127::-;33683:10;33678:3;33674:20;33671:1;33664:31;33714:4;33711:1;33704:15;33738:4;33735:1;33728:15;33754:858;34084:6;34077:14;34070:22;34059:9;34052:41;34033:4;34123:1;34115:6;34112:13;34102:144;;34168:10;34163:3;34159:20;34156:1;34149:31;34203:4;34200:1;34193:15;34231:4;34228:1;34221:15;34102:144;34282:6;34277:2;34266:9;34262:18;34255:34;34325:3;34320:2;34309:9;34305:18;34298:31;34352:46;34393:3;34382:9;34378:19;34370:6;34352:46;:::i;:::-;34446:9;34438:6;34434:22;34429:2;34418:9;34414:18;34407:50;34474:33;34500:6;34492;34474:33;:::i;:::-;34466:41;;;34544:6;34538:3;34527:9;34523:19;34516:35;34600:4;34592:6;34588:17;34582:3;34571:9;34567:19;34560:46;33754:858;;;;;;;;;:::o;35734:386::-;35937:6;35926:9;35919:25;35980:2;35975;35964:9;35960:18;35953:30;35900:4;36000:45;36041:2;36030:9;36026:18;36018:6;36000:45;:::i;:::-;35992:53;;36110:1;36106;36101:3;36097:11;36093:19;36085:6;36081:32;36076:2;36065:9;36061:18;36054:60;35734:386;;;;;;:::o;36125:184::-;36195:6;36248:2;36236:9;36227:7;36223:23;36219:32;36216:52;;;36264:1;36261;36254:12;36216:52;-1:-1:-1;36287:16:35;;36125:184;-1:-1:-1;36125:184:35:o;36314:681::-;36429:6;36437;36445;36453;36506:3;36494:9;36485:7;36481:23;36477:33;36474:53;;;36523:1;36520;36513:12;36474:53;36556:9;36550:16;-1:-1:-1;;;;;36626:2:35;36618:6;36615:14;36612:34;;;36642:1;36639;36632:12;36612:34;36665:60;36717:7;36708:6;36697:9;36693:22;36665:60;:::i;:::-;36655:70;;36771:2;36760:9;36756:18;36750:25;36734:41;;36800:2;36790:8;36787:16;36784:36;;;36816:1;36813;36806:12;36784:36;;36839:62;36893:7;36882:8;36871:9;36867:24;36839:62;:::i;:::-;36941:2;36926:18;;36920:25;36985:2;36970:18;;;36964:25;36314:681;;36829:72;;-1:-1:-1;36314:681:35;-1:-1:-1;;;;36314:681:35:o;37000:1087::-;37151:6;37159;37167;37175;37183;37191;37244:3;37232:9;37223:7;37219:23;37215:33;37212:53;;;37261:1;37258;37251:12;37212:53;37294:9;37288:16;-1:-1:-1;;;;;37364:2:35;37356:6;37353:14;37350:34;;;37380:1;37377;37370:12;37350:34;37403:60;37455:7;37446:6;37435:9;37431:22;37403:60;:::i;:::-;37393:70;;37509:2;37498:9;37494:18;37488:25;37472:41;;37538:2;37528:8;37525:16;37522:36;;;37554:1;37551;37544:12;37522:36;37577:62;37631:7;37620:8;37609:9;37605:24;37577:62;:::i;:::-;37567:72;;37679:2;37668:9;37664:18;37658:25;37648:35;;37723:2;37712:9;37708:18;37702:25;37692:35;;37773:3;37762:9;37758:19;37752:26;37736:42;;37803:2;37793:8;37790:16;37787:36;;;37819:1;37816;37809:12;37787:36;37842:62;37896:7;37885:8;37874:9;37870:24;37842:62;:::i;:::-;37832:72;;37950:3;37939:9;37935:19;37929:26;37913:42;;37980:2;37970:8;37967:16;37964:36;;;37996:1;37993;37986:12;37964:36;;38019:62;38073:7;38062:8;38051:9;38047:24;38019:62;:::i;:::-;38009:72;;;37000:1087;;;;;;;;:::o;38092:559::-;38335:3;38324:9;38317:22;38298:4;38362:46;38403:3;38392:9;38388:19;38380:6;38362:46;:::i;:::-;-1:-1:-1;;;;;38444:32:35;;38439:2;38424:18;;38417:60;38520:14;;38513:22;38508:2;38493:18;;38486:50;38572:22;;;38567:2;38552:18;;38545:50;38612:33;38576:6;38630;38612:33;:::i;38656:693::-;38961:6;38950:9;38943:25;39004:3;38999:2;38988:9;38984:18;38977:31;38924:4;39031:46;39072:3;39061:9;39057:19;39049:6;39031:46;:::i;:::-;39108:2;39093:18;;39086:34;;;-1:-1:-1;;;;;39156:32:35;;39151:2;39136:18;;39129:60;39220:3;39205:19;;39198:35;;;39270:22;;;39176:3;39249:19;;39242:51;39310:33;39274:6;39328;39310:33;:::i;43390:422::-;43479:1;43522:5;43479:1;43536:270;43557:7;43547:8;43544:21;43536:270;;;43616:4;43612:1;43608:6;43604:17;43598:4;43595:27;43592:53;;;43625:18;;:::i;:::-;43675:7;43665:8;43661:22;43658:55;;;43695:16;;;;43658:55;43774:22;;;;43734:15;;;;43536:270;;;43540:3;43390:422;;;;;:::o;43817:806::-;43866:5;43896:8;43886:80;;-1:-1:-1;43937:1:35;43951:5;;43886:80;43985:4;43975:76;;-1:-1:-1;44022:1:35;44036:5;;43975:76;44067:4;44085:1;44080:59;;;;44153:1;44148:130;;;;44060:218;;44080:59;44110:1;44101:10;;44124:5;;;44148:130;44185:3;44175:8;44172:17;44169:43;;;44192:18;;:::i;:::-;-1:-1:-1;;44248:1:35;44234:16;;44263:5;;44060:218;;44362:2;44352:8;44349:16;44343:3;44337:4;44334:13;44330:36;44324:2;44314:8;44311:16;44306:2;44300:4;44297:12;44293:35;44290:77;44287:159;;;-1:-1:-1;44399:19:35;;;44431:5;;44287:159;44478:34;44503:8;44497:4;44478:34;:::i;:::-;44548:6;44544:1;44540:6;44536:19;44527:7;44524:32;44521:58;;;44559:18;;:::i;:::-;44597:20;;43817:806;-1:-1:-1;;;43817:806:35:o;44628:131::-;44688:5;44717:36;44744:8;44738:4;44717:36;:::i;44764:168::-;44837:9;;;44868;;44885:15;;;44879:22;;44865:37;44855:71;;44906:18;;:::i;44937:217::-;44977:1;45003;44993:132;;45047:10;45042:3;45038:20;45035:1;45028:31;45082:4;45079:1;45072:15;45110:4;45107:1;45100:15;44993:132;-1:-1:-1;45139:9:35;;44937:217::o;45926:287::-;46055:3;46093:6;46087:13;46109:66;46168:6;46163:3;46156:4;46148:6;46144:17;46109:66;:::i;:::-;46191:16;;;;;45926:287;-1:-1:-1;;45926:287:35:o

Swarm Source

ipfs://d5f54f3678a011ff4d56dc613b5a415636f45c23826c34dc6b8cd81079138873

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

OVERVIEW

Map Protocol is A #Bitcoin L2 for peer-to-peer interoperability, built on ZK & light clients.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.