Token Bookie

 

Overview ERC-20

Price
$0.00 @ 0.000000 MATIC
Fully Diluted Market Cap
Total Supply:
73,877,351.766946 BOOK

Holders:
7,291 addresses

Transfers:
-

Contract:
0x8192759bf7f247cc92f74e39b3a4225516624fc10x8192759Bf7f247cC92F74E39B3A4225516624fC1

Decimals:
8

Social Profiles:
Not Available, Update ?

 
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BookieToken

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-17
*/

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

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


// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @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 @openzeppelin/contracts/utils/[email protected]

// OpenZeppelin Contracts v4.4.1 (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;
    }
}


// File @openzeppelin/contracts/token/ERC20/[email protected]

// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;



/**
 * @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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * 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}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * 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 value {ERC20} uses, unless this function is
     * 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:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, 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}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), 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}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - 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) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][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) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

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

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, 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;
        _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;
        }
        _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 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 @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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.
 */
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].
     */
    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 @openzeppelin/contracts/utils/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

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

    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");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' 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) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        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.
            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 if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } 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;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 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 (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // 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) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @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) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)

pragma solidity ^0.8.0;

/**
 * @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].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // 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 _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @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) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, 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);
    }
}


// File @openzeppelin/contracts/utils/[email protected]

// 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 @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)

pragma solidity ^0.8.0;





/**
 * @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 immutable _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

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

    /**
     * @dev See {IERC20Permit-permit}.
     */
    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);
    }

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

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // 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 @openzeppelin/contracts/utils/math/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @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 / b + (a % b == 0 ? 0 : 1);
    }
}


// File @openzeppelin/contracts/utils/math/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}


// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Votes.sol)

pragma solidity ^0.8.0;




/**
 * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
 * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
 *
 * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.
 *
 * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
 * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
 * power can be queried through the public accessors {getVotes} and {getPastVotes}.
 *
 * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
 * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
 * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
 * will significantly increase the base gas cost of transfers.
 *
 * _Available since v4.2._
 */
abstract contract ERC20Votes is ERC20Permit {
    struct Checkpoint {
        uint32 fromBlock;
        uint224 votes;
    }

    bytes32 private constant _DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) private _delegates;
    mapping(address => Checkpoint[]) private _checkpoints;
    Checkpoint[] private _totalSupplyCheckpoints;

    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Get the `pos`-th checkpoint for `account`.
     */
    function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
        return _checkpoints[account][pos];
    }

    /**
     * @dev Get number of checkpoints for `account`.
     */
    function numCheckpoints(address account) public view virtual returns (uint32) {
        return SafeCast.toUint32(_checkpoints[account].length);
    }

    /**
     * @dev Get the address `account` is currently delegating to.
     */
    function delegates(address account) public view virtual returns (address) {
        return _delegates[account];
    }

    /**
     * @dev Gets the current votes balance for `account`
     */
    function getVotes(address account) public view returns (uint256) {
        uint256 pos = _checkpoints[account].length;
        return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
    }

    /**
     * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {
        require(blockNumber < block.number, "ERC20Votes: block not yet mined");
        return _checkpointsLookup(_checkpoints[account], blockNumber);
    }

    /**
     * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
     * It is but NOT the sum of all the delegated votes!
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {
        require(blockNumber < block.number, "ERC20Votes: block not yet mined");
        return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
    }

    /**
     * @dev Lookup a value in a list of (sorted) checkpoints.
     */
    function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
        // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
        //
        // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
        // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.
        // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
        // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
        // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
        // out of bounds (in which case we're looking too far in the past and the result is 0).
        // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
        // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
        // the same.
        uint256 high = ckpts.length;
        uint256 low = 0;
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (ckpts[mid].fromBlock > blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        return high == 0 ? 0 : ckpts[high - 1].votes;
    }

    /**
     * @dev Delegate votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) public virtual {
        _delegate(_msgSender(), delegatee);
    }

    /**
     * @dev Delegates votes from signer to `delegatee`
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(block.timestamp <= expiry, "ERC20Votes: signature expired");
        address signer = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
            v,
            r,
            s
        );
        require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
        _delegate(signer, delegatee);
    }

    /**
     * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
     */
    function _maxSupply() internal view virtual returns (uint224) {
        return type(uint224).max;
    }

    /**
     * @dev Snapshots the totalSupply after it has been increased.
     */
    function _mint(address account, uint256 amount) internal virtual override {
        super._mint(account, amount);
        require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");

        _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
    }

    /**
     * @dev Snapshots the totalSupply after it has been decreased.
     */
    function _burn(address account, uint256 amount) internal virtual override {
        super._burn(account, amount);

        _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
    }

    /**
     * @dev Move voting power when tokens are transferred.
     *
     * Emits a {DelegateVotesChanged} event.
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._afterTokenTransfer(from, to, amount);

        _moveVotingPower(delegates(from), delegates(to), amount);
    }

    /**
     * @dev Change delegation for `delegator` to `delegatee`.
     *
     * Emits events {DelegateChanged} and {DelegateVotesChanged}.
     */
    function _delegate(address delegator, address delegatee) internal virtual {
        address currentDelegate = delegates(delegator);
        uint256 delegatorBalance = balanceOf(delegator);
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveVotingPower(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveVotingPower(
        address src,
        address dst,
        uint256 amount
    ) private {
        if (src != dst && amount > 0) {
            if (src != address(0)) {
                (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
                emit DelegateVotesChanged(src, oldWeight, newWeight);
            }

            if (dst != address(0)) {
                (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
                emit DelegateVotesChanged(dst, oldWeight, newWeight);
            }
        }
    }

    function _writeCheckpoint(
        Checkpoint[] storage ckpts,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) private returns (uint256 oldWeight, uint256 newWeight) {
        uint256 pos = ckpts.length;
        oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
        newWeight = op(oldWeight, delta);

        if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
            ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
        } else {
            ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));
        }
    }

    function _add(uint256 a, uint256 b) private pure returns (uint256) {
        return a + b;
    }

    function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
        return a - b;
    }
}


// File @openzeppelin/contracts/access/[email protected]

// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


// File @openzeppelin/contracts/utils/introspection/[email protected]

// 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 @openzeppelin/contracts/utils/introspection/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

/**
 * @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 @openzeppelin/contracts/access/[email protected]

// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)

pragma solidity ^0.8.0;




/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


// File contracts/BookieToken.sol

pragma solidity ^0.8.4;




contract BookieToken is ERC20, ERC20Permit, ERC20Votes, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant UPDATER_ROLE = keccak256("UPDATER_ROLE");
    uint256 public maxSupply;

    constructor(
        address admin,
        string memory tokenName,
        string memory tokenSymbol,
        uint256 maximalSupply,
        uint256 initialMintAmount
    ) ERC20(tokenName, tokenSymbol) ERC20Permit(tokenName) {
        _mint(admin, initialMintAmount);
        _setupRole(DEFAULT_ADMIN_ROLE, admin);
        maxSupply = maximalSupply;
    }

    function mint(address to, uint256 amount) 
        external 
        onlyRole(MINTER_ROLE) 
    {
        require(
            totalSupply() + amount <= maxSupply, 
            "Max supply exceeded"
        );
        _mint(to, amount);
    }

    function decimals() 
        public 
        view 
        virtual 
        override 
        returns (uint8) 
    {
        return 8;
    }

    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._afterTokenTransfer(from, to, amount);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._mint(to, amount);
    }

    function _burn(address account, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._burn(account, amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"maximalSupply","type":"uint256"},{"internalType":"uint256","name":"initialMintAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPDATER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20Votes.Checkpoint","name":"","type":"tuple"}],"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":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","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":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","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":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

6101606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610140908152503480156200003a57600080fd5b5060405162005bc638038062005bc6833981810160405281019062000060919062000df8565b83806040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525086868160039080519060200190620000b292919062000c9c565b508060049080519060200190620000cb92919062000c9c565b50505060008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508260e081815250508161010081815250504660a0818152505062000137818484620001bd60201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050806101208181525050505050505050620001968582620001f960201b60201c565b620001ab6000801b866200021460201b60201c565b81600a819055505050505050620014d9565b60008383834630604051602001620001da95949392919062000f8d565b6040516020818303038152906040528051906020012090509392505050565b6200021082826200022a60201b6200151b1760201c565b5050565b620002268282620002e860201b60201c565b5050565b620002418282620003da60201b620015a81760201c565b620002516200055360201b60201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166200027f6200057760201b60201c565b1115620002c3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002ba9062000fea565b60405180910390fd5b620002e260086200058160201b6200170817836200059960201b60201c565b50505050565b620002fa82826200084a60201b60201c565b620003d65760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200037b620008b560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200044d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004449062001050565b60405180910390fd5b6200046160008383620008bd60201b60201c565b80600260008282546200047591906200112c565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254620004cc91906200112c565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000533919062001072565b60405180910390a36200054f60008383620008c260201b60201c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b6000600254905090565b600081836200059191906200112c565b905092915050565b600080600085805490509050600081146200060e5785600182620005be919062001189565b81548110620005d257620005d16200130c565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1662000611565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1692506200063d83858760201c565b915060008111801562000696575043866001836200065c919062001189565b8154811062000670576200066f6200130c565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b156200073757620006b282620008df60201b6200171e1760201c565b86600183620006c2919062001189565b81548110620006d657620006d56200130c565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555062000841565b85604051806040016040528062000759436200094d60201b620017891760201c565b63ffffffff1681526020016200077a85620008df60201b6200171e1760201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b505050565b620008da838383620009a360201b620017dc1760201c565b505050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff801682111562000945576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200093c906200100c565b60405180910390fd5b819050919050565b600063ffffffff80168211156200099b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000992906200102e565b60405180910390fd5b819050919050565b620009bb838383620009f360201b620018071760201c565b620009ee620009d084620009f860201b60201c565b620009e184620009f860201b60201c565b8362000a6160201b60201c565b505050565b505050565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801562000a9e5750600081115b1562000c7f57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000b915760008062000b38600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002062000c8460201b6200180c17856200059960201b60201c565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000b869291906200108f565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000c7e5760008062000c25600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206200058160201b6200170817856200059960201b60201c565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000c739291906200108f565b60405180910390a250505b5b505050565b6000818362000c94919062001189565b905092915050565b82805462000caa9062001242565b90600052602060002090601f01602090048101928262000cce576000855562000d1a565b82601f1062000ce957805160ff191683800117855562000d1a565b8280016001018555821562000d1a579182015b8281111562000d1957825182559160200191906001019062000cfc565b5b50905062000d29919062000d2d565b5090565b5b8082111562000d4857600081600090555060010162000d2e565b5090565b600062000d6362000d5d84620010e5565b620010bc565b90508281526020810184848401111562000d825762000d816200136f565b5b62000d8f8482856200120c565b509392505050565b60008151905062000da881620014a5565b92915050565b600082601f83011262000dc65762000dc56200136a565b5b815162000dd884826020860162000d4c565b91505092915050565b60008151905062000df281620014bf565b92915050565b600080600080600060a0868803121562000e175762000e1662001379565b5b600062000e278882890162000d97565b955050602086015167ffffffffffffffff81111562000e4b5762000e4a62001374565b5b62000e598882890162000dae565b945050604086015167ffffffffffffffff81111562000e7d5762000e7c62001374565b5b62000e8b8882890162000dae565b935050606062000e9e8882890162000de1565b925050608062000eb18882890162000de1565b9150509295509295909350565b62000ec981620011c4565b82525050565b62000eda81620011d8565b82525050565b600062000eef6030836200111b565b915062000efc826200138f565b604082019050919050565b600062000f166027836200111b565b915062000f2382620013de565b604082019050919050565b600062000f3d6026836200111b565b915062000f4a826200142d565b604082019050919050565b600062000f64601f836200111b565b915062000f71826200147c565b602082019050919050565b62000f878162001202565b82525050565b600060a08201905062000fa4600083018862000ecf565b62000fb3602083018762000ecf565b62000fc2604083018662000ecf565b62000fd1606083018562000f7c565b62000fe0608083018462000ebe565b9695505050505050565b60006020820190508181036000830152620010058162000ee0565b9050919050565b60006020820190508181036000830152620010278162000f07565b9050919050565b60006020820190508181036000830152620010498162000f2e565b9050919050565b600060208201905081810360008301526200106b8162000f55565b9050919050565b600060208201905062001089600083018462000f7c565b92915050565b6000604082019050620010a6600083018562000f7c565b620010b5602083018462000f7c565b9392505050565b6000620010c8620010db565b9050620010d6828262001278565b919050565b6000604051905090565b600067ffffffffffffffff8211156200110357620011026200133b565b5b6200110e826200137e565b9050602081019050919050565b600082825260208201905092915050565b6000620011398262001202565b9150620011468362001202565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156200117e576200117d620012ae565b5b828201905092915050565b6000620011968262001202565b9150620011a38362001202565b925082821015620011b957620011b8620012ae565b5b828203905092915050565b6000620011d182620011e2565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b838110156200122c5780820151818401526020810190506200120f565b838111156200123c576000848401525b50505050565b600060028204905060018216806200125b57607f821691505b60208210811415620012725762001271620012dd565b5b50919050565b62001283826200137e565b810181811067ffffffffffffffff82111715620012a557620012a46200133b565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b620014b081620011c4565b8114620014bc57600080fd5b50565b620014ca8162001202565b8114620014d657600080fd5b50565b60805160a05160c05160601c60e05161010051610120516101405161468f62001537600039600061123601526000611f0c01526000611f4e01526000611f2d01526000611e6201526000611eb801526000611ee1015261468f6000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80636fcfff451161011a578063a457c2d7116100ad578063d53913931161007c578063d53913931461064a578063d547741f14610668578063d5abeb0114610684578063dd62ed3e146106a2578063f1127ed8146106d2576101fb565b8063a457c2d7146105b2578063a9059cbb146105e2578063c3cda52014610612578063d505accf1461062e576101fb565b806391d14854116100e957806391d148541461051657806395d89b41146105465780639ab24eb014610564578063a217fddf14610594576101fb565b80636fcfff451461045657806370a08231146104865780637ecebe00146104b65780638e539e8c146104e6576101fb565b80633644e5151161019257806340c10f191161016157806340c10f19146103d057806347e63380146103ec578063587cde1e1461040a5780635c19a95c1461043a576101fb565b80633644e5151461033657806336568abe1461035457806339509351146103705780633a46b1a8146103a0576101fb565b806323b872dd116101ce57806323b872dd1461029c578063248a9ca3146102cc5780632f2ff15d146102fc578063313ce56714610318576101fb565b806301ffc9a71461020057806306fdde0314610230578063095ea7b31461024e57806318160ddd1461027e575b600080fd5b61021a60048036038101906102159190613148565b610702565b60405161022791906136e4565b60405180910390f35b61023861077c565b6040516102459190613858565b60405180910390f35b61026860048036038101906102639190612fce565b61080e565b60405161027591906136e4565b60405180910390f35b61028661082c565b6040516102939190613b75565b60405180910390f35b6102b660048036038101906102b19190612ed9565b610836565b6040516102c391906136e4565b60405180910390f35b6102e660048036038101906102e191906130db565b61092e565b6040516102f391906136ff565b60405180910390f35b61031660048036038101906103119190613108565b61094e565b005b610320610977565b60405161032d9190613bd4565b60405180910390f35b61033e610980565b60405161034b91906136ff565b60405180910390f35b61036e60048036038101906103699190613108565b61098f565b005b61038a60048036038101906103859190612fce565b610a12565b60405161039791906136e4565b60405180910390f35b6103ba60048036038101906103b59190612fce565b610abe565b6040516103c79190613b75565b60405180910390f35b6103ea60048036038101906103e59190612fce565b610b52565b005b6103f4610bea565b60405161040191906136ff565b60405180910390f35b610424600480360381019061041f9190612e6c565b610c0e565b60405161043191906136c9565b60405180910390f35b610454600480360381019061044f9190612e6c565b610c77565b005b610470600480360381019061046b9190612e6c565b610c8b565b60405161047d9190613bb9565b60405180910390f35b6104a0600480360381019061049b9190612e6c565b610cdf565b6040516104ad9190613b75565b60405180910390f35b6104d060048036038101906104cb9190612e6c565b610d27565b6040516104dd9190613b75565b60405180910390f35b61050060048036038101906104fb9190613175565b610d77565b60405161050d9190613b75565b60405180910390f35b610530600480360381019061052b9190613108565b610dcd565b60405161053d91906136e4565b60405180910390f35b61054e610e38565b60405161055b9190613858565b60405180910390f35b61057e60048036038101906105799190612e6c565b610eca565b60405161058b9190613b75565b60405180910390f35b61059c610fdb565b6040516105a991906136ff565b60405180910390f35b6105cc60048036038101906105c79190612fce565b610fe2565b6040516105d991906136e4565b60405180910390f35b6105fc60048036038101906105f79190612fce565b6110cd565b60405161060991906136e4565b60405180910390f35b61062c6004803603810190610627919061300e565b6110eb565b005b61064860048036038101906106439190612f2c565b6111ef565b005b610652611331565b60405161065f91906136ff565b60405180910390f35b610682600480360381019061067d9190613108565b611355565b005b61068c61137e565b6040516106999190613b75565b60405180910390f35b6106bc60048036038101906106b79190612e99565b611384565b6040516106c99190613b75565b60405180910390f35b6106ec60048036038101906106e7919061309b565b61140b565b6040516106f99190613b5a565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610775575061077482611822565b5b9050919050565b60606003805461078b90613e4b565b80601f01602080910402602001604051908101604052809291908181526020018280546107b790613e4b565b80156108045780601f106107d957610100808354040283529160200191610804565b820191906000526020600020905b8154815290600101906020018083116107e757829003601f168201915b5050505050905090565b600061082261081b61188c565b8484611894565b6001905092915050565b6000600254905090565b6000610843848484611a5f565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061088e61188c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508281101561090e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090590613a3a565b60405180910390fd5b6109228561091a61188c565b858403611894565b60019150509392505050565b600060096000838152602001908152602001600020600101549050919050565b6109578261092e565b6109688161096361188c565b611ce0565b6109728383611d7d565b505050565b60006008905090565b600061098a611e5e565b905090565b61099761188c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fb90613b1a565b60405180910390fd5b610a0e8282611f78565b5050565b6000610ab4610a1f61188c565b848460016000610a2d61188c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610aaf9190613c16565b611894565b6001905092915050565b6000438210610b02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af9906138da565b60405180910390fd5b610b4a600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208361205a565b905092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b8481610b7f61188c565b611ce0565b600a5482610b9061082c565b610b9a9190613c16565b1115610bdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd2906138fa565b60405180910390fd5b610be58383612166565b505050565b7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab81565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c88610c8261188c565b82612174565b50565b6000610cd8600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611789565b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610d70600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061228e565b9050919050565b6000438210610dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db2906138da565b60405180910390fd5b610dc660088361205a565b9050919050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610e4790613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7390613e4b565b8015610ec05780601f10610e9557610100808354040283529160200191610ec0565b820191906000526020600020905b815481529060010190602001808311610ea357829003601f168201915b5050505050905090565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060008114610fb257600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600182610f669190613cf7565b81548110610f7757610f76613f43565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610fb5565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b60008060016000610ff161188c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156110ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a590613afa565b60405180910390fd5b6110c26110b961188c565b85858403611894565b600191505092915050565b60006110e16110da61188c565b8484611a5f565b6001905092915050565b8342111561112e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111259061391a565b60405180910390fd5b60006111906111887fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf89898960405160200161116d949392919061377b565b6040516020818303038152906040528051906020012061229c565b8585856122b6565b905061119b816122e1565b86146111dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d39061395a565b60405180910390fd5b6111e68188612174565b50505050505050565b83421115611232576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112299061399a565b60405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008888886112618c6122e1565b896040516020016112779695949392919061371a565b604051602081830303815290604052805190602001209050600061129a8261229c565b905060006112aa828787876122b6565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461131a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131190613a1a565b60405180910390fd5b6113258a8a8a611894565b50505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61135e8261092e565b61136f8161136a61188c565b611ce0565b6113798383611f78565b505050565b600a5481565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b611413612db0565b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff168154811061146a57611469613f43565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b61152582826115a8565b61152d61233f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661155361082c565b1115611594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158b90613a5a565b60405180910390fd5b6115a2600861170883612363565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160f90613b3a565b60405180910390fd5b611624600083836125db565b80600260008282546116369190613c16565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461168b9190613c16565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516116f09190613b75565b60405180910390a3611704600083836125e0565b5050565b600081836117169190613c16565b905092915050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115611781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177890613a7a565b60405180910390fd5b819050919050565b600063ffffffff80168211156117d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117cb90613aba565b60405180910390fd5b819050919050565b6117e7838383611807565b6118026117f384610c0e565b6117fc84610c0e565b836125f0565b505050565b505050565b6000818361181a9190613cf7565b905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611904576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fb90613ada565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b9061397a565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611a529190613b75565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611acf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac690613a9a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b36906138ba565b60405180910390fd5b611b4a8383836125db565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611bd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc7906139ba565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c639190613c16565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611cc79190613b75565b60405180910390a3611cda8484846125e0565b50505050565b611cea8282610dcd565b611d7957611d0f8173ffffffffffffffffffffffffffffffffffffffff1660146127e9565b611d1d8360001c60206127e9565b604051602001611d2e92919061368f565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d709190613858565b60405180910390fd5b5050565b611d878282610dcd565b611e5a5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611dff61188c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611eda57507f000000000000000000000000000000000000000000000000000000000000000046145b15611f07577f00000000000000000000000000000000000000000000000000000000000000009050611f75565b611f727f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612a25565b90505b90565b611f828282610dcd565b156120565760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ffb61188c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b818110156120d957600061207b8284612a5f565b90508486828154811061209157612090613f43565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff1611156120c3578092506120d3565b6001816120d09190613c16565b91505b50612067565b6000821461213b57846001836120ef9190613cf7565b81548110612100576120ff613f43565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661213e565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b612170828261151b565b5050565b600061217f83610c0e565b9050600061218c84610cdf565b905082600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46122888284836125f0565b50505050565b600081600001549050919050565b60006122af6122a9611e5e565b83612a85565b9050919050565b60008060006122c787878787612ab8565b915091506122d481612bc5565b8192505050949350505050565b600080600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061232e8161228e565b915061233981612d9a565b50919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b600080600085805490509050600081146123d157856001826123859190613cf7565b8154811061239657612395613f43565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166123d4565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16925061240283858763ffffffff16565b91506000811180156124555750438660018361241e9190613cf7565b8154811061242f5761242e613f43565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b156124e2576124638261171e565b866001836124719190613cf7565b8154811061248257612481613f43565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055506125d2565b8560405180604001604052806124f743611789565b63ffffffff16815260200161250b8561171e565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b505050565b6125eb8383836117dc565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561262c5750600081115b156127e457600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461270a576000806126b3600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061180c85612363565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516126ff929190613b90565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146127e35760008061278c600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170885612363565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516127d8929190613b90565b60405180910390a250505b5b505050565b6060600060028360026127fc9190613c9d565b6128069190613c16565b67ffffffffffffffff81111561281f5761281e613f72565b5b6040519080825280601f01601f1916602001820160405280156128515781602001600182028036833780820191505090505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061288957612888613f43565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106128ed576128ec613f43565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261292d9190613c9d565b6129379190613c16565b90505b60018111156129d7577f3031323334353637383961626364656600000000000000000000000000000000600f86166010811061297957612978613f43565b5b1a60f81b8282815181106129905761298f613f43565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806129d090613e21565b905061293a565b5060008414612a1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a129061389a565b60405180910390fd5b8091505092915050565b60008383834630604051602001612a409594939291906137c0565b6040516020818303038152906040528051906020012090509392505050565b60006002828418612a709190613c6c565b828416612a7d9190613c16565b905092915050565b60008282604051602001612a9a929190613658565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612af3576000600391509150612bbc565b601b8560ff1614158015612b0b5750601c8560ff1614155b15612b1d576000600491509150612bbc565b600060018787878760405160008152602001604052604051612b429493929190613813565b6020604051602081039080840390855afa158015612b64573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612bb357600060019250925050612bbc565b80600092509250505b94509492505050565b60006004811115612bd957612bd8613ee5565b5b816004811115612bec57612beb613ee5565b5b1415612bf757612d97565b60016004811115612c0b57612c0a613ee5565b5b816004811115612c1e57612c1d613ee5565b5b1415612c5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c569061387a565b60405180910390fd5b60026004811115612c7357612c72613ee5565b5b816004811115612c8657612c85613ee5565b5b1415612cc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cbe9061393a565b60405180910390fd5b60036004811115612cdb57612cda613ee5565b5b816004811115612cee57612ced613ee5565b5b1415612d2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d26906139da565b60405180910390fd5b600480811115612d4257612d41613ee5565b5b816004811115612d5557612d54613ee5565b5b1415612d96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d8d906139fa565b60405180910390fd5b5b50565b6001816000016000828254019250508190555050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600081359050612dfd816145cf565b92915050565b600081359050612e12816145e6565b92915050565b600081359050612e27816145fd565b92915050565b600081359050612e3c81614614565b92915050565b600081359050612e518161462b565b92915050565b600081359050612e6681614642565b92915050565b600060208284031215612e8257612e81613fa1565b5b6000612e9084828501612dee565b91505092915050565b60008060408385031215612eb057612eaf613fa1565b5b6000612ebe85828601612dee565b9250506020612ecf85828601612dee565b9150509250929050565b600080600060608486031215612ef257612ef1613fa1565b5b6000612f0086828701612dee565b9350506020612f1186828701612dee565b9250506040612f2286828701612e2d565b9150509250925092565b600080600080600080600060e0888a031215612f4b57612f4a613fa1565b5b6000612f598a828b01612dee565b9750506020612f6a8a828b01612dee565b9650506040612f7b8a828b01612e2d565b9550506060612f8c8a828b01612e2d565b9450506080612f9d8a828b01612e57565b93505060a0612fae8a828b01612e03565b92505060c0612fbf8a828b01612e03565b91505092959891949750929550565b60008060408385031215612fe557612fe4613fa1565b5b6000612ff385828601612dee565b925050602061300485828601612e2d565b9150509250929050565b60008060008060008060c0878903121561302b5761302a613fa1565b5b600061303989828a01612dee565b965050602061304a89828a01612e2d565b955050604061305b89828a01612e2d565b945050606061306c89828a01612e57565b935050608061307d89828a01612e03565b92505060a061308e89828a01612e03565b9150509295509295509295565b600080604083850312156130b2576130b1613fa1565b5b60006130c085828601612dee565b92505060206130d185828601612e42565b9150509250929050565b6000602082840312156130f1576130f0613fa1565b5b60006130ff84828501612e03565b91505092915050565b6000806040838503121561311f5761311e613fa1565b5b600061312d85828601612e03565b925050602061313e85828601612dee565b9150509250929050565b60006020828403121561315e5761315d613fa1565b5b600061316c84828501612e18565b91505092915050565b60006020828403121561318b5761318a613fa1565b5b600061319984828501612e2d565b91505092915050565b6131ab81613d2b565b82525050565b6131ba81613d3d565b82525050565b6131c981613d49565b82525050565b6131e06131db82613d49565b613e7d565b82525050565b60006131f182613bef565b6131fb8185613bfa565b935061320b818560208601613dee565b61321481613fa6565b840191505092915050565b600061322a82613bef565b6132348185613c0b565b9350613244818560208601613dee565b80840191505092915050565b600061325d601883613bfa565b915061326882613fb7565b602082019050919050565b6000613280602083613bfa565b915061328b82613fe0565b602082019050919050565b60006132a3602383613bfa565b91506132ae82614009565b604082019050919050565b60006132c6601f83613bfa565b91506132d182614058565b602082019050919050565b60006132e9601383613bfa565b91506132f482614081565b602082019050919050565b600061330c601d83613bfa565b9150613317826140aa565b602082019050919050565b600061332f601f83613bfa565b915061333a826140d3565b602082019050919050565b6000613352601983613bfa565b915061335d826140fc565b602082019050919050565b6000613375602283613bfa565b915061338082614125565b604082019050919050565b6000613398600283613c0b565b91506133a382614174565b600282019050919050565b60006133bb601d83613bfa565b91506133c68261419d565b602082019050919050565b60006133de602683613bfa565b91506133e9826141c6565b604082019050919050565b6000613401602283613bfa565b915061340c82614215565b604082019050919050565b6000613424602283613bfa565b915061342f82614264565b604082019050919050565b6000613447601e83613bfa565b9150613452826142b3565b602082019050919050565b600061346a602883613bfa565b9150613475826142dc565b604082019050919050565b600061348d603083613bfa565b91506134988261432b565b604082019050919050565b60006134b0602783613bfa565b91506134bb8261437a565b604082019050919050565b60006134d3602583613bfa565b91506134de826143c9565b604082019050919050565b60006134f6602683613bfa565b915061350182614418565b604082019050919050565b6000613519602483613bfa565b915061352482614467565b604082019050919050565b600061353c601783613c0b565b9150613547826144b6565b601782019050919050565b600061355f602583613bfa565b915061356a826144df565b604082019050919050565b6000613582601183613c0b565b915061358d8261452e565b601182019050919050565b60006135a5602f83613bfa565b91506135b082614557565b604082019050919050565b60006135c8601f83613bfa565b91506135d3826145a6565b602082019050919050565b6040820160008201516135f4600085018261362b565b506020820151613607602085018261360d565b50505050565b61361681613d9f565b82525050565b61362581613dc7565b82525050565b61363481613dd1565b82525050565b61364381613dd1565b82525050565b61365281613de1565b82525050565b60006136638261338b565b915061366f82856131cf565b60208201915061367f82846131cf565b6020820191508190509392505050565b600061369a8261352f565b91506136a6828561321f565b91506136b182613575565b91506136bd828461321f565b91508190509392505050565b60006020820190506136de60008301846131a2565b92915050565b60006020820190506136f960008301846131b1565b92915050565b600060208201905061371460008301846131c0565b92915050565b600060c08201905061372f60008301896131c0565b61373c60208301886131a2565b61374960408301876131a2565b613756606083018661361c565b613763608083018561361c565b61377060a083018461361c565b979650505050505050565b600060808201905061379060008301876131c0565b61379d60208301866131a2565b6137aa604083018561361c565b6137b7606083018461361c565b95945050505050565b600060a0820190506137d560008301886131c0565b6137e260208301876131c0565b6137ef60408301866131c0565b6137fc606083018561361c565b61380960808301846131a2565b9695505050505050565b600060808201905061382860008301876131c0565b6138356020830186613649565b61384260408301856131c0565b61384f60608301846131c0565b95945050505050565b6000602082019050818103600083015261387281846131e6565b905092915050565b6000602082019050818103600083015261389381613250565b9050919050565b600060208201905081810360008301526138b381613273565b9050919050565b600060208201905081810360008301526138d381613296565b9050919050565b600060208201905081810360008301526138f3816132b9565b9050919050565b60006020820190508181036000830152613913816132dc565b9050919050565b60006020820190508181036000830152613933816132ff565b9050919050565b6000602082019050818103600083015261395381613322565b9050919050565b6000602082019050818103600083015261397381613345565b9050919050565b6000602082019050818103600083015261399381613368565b9050919050565b600060208201905081810360008301526139b3816133ae565b9050919050565b600060208201905081810360008301526139d3816133d1565b9050919050565b600060208201905081810360008301526139f3816133f4565b9050919050565b60006020820190508181036000830152613a1381613417565b9050919050565b60006020820190508181036000830152613a338161343a565b9050919050565b60006020820190508181036000830152613a538161345d565b9050919050565b60006020820190508181036000830152613a7381613480565b9050919050565b60006020820190508181036000830152613a93816134a3565b9050919050565b60006020820190508181036000830152613ab3816134c6565b9050919050565b60006020820190508181036000830152613ad3816134e9565b9050919050565b60006020820190508181036000830152613af38161350c565b9050919050565b60006020820190508181036000830152613b1381613552565b9050919050565b60006020820190508181036000830152613b3381613598565b9050919050565b60006020820190508181036000830152613b53816135bb565b9050919050565b6000604082019050613b6f60008301846135de565b92915050565b6000602082019050613b8a600083018461361c565b92915050565b6000604082019050613ba5600083018561361c565b613bb2602083018461361c565b9392505050565b6000602082019050613bce600083018461363a565b92915050565b6000602082019050613be96000830184613649565b92915050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000613c2182613dc7565b9150613c2c83613dc7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613c6157613c60613e87565b5b828201905092915050565b6000613c7782613dc7565b9150613c8283613dc7565b925082613c9257613c91613eb6565b5b828204905092915050565b6000613ca882613dc7565b9150613cb383613dc7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613cec57613ceb613e87565b5b828202905092915050565b6000613d0282613dc7565b9150613d0d83613dc7565b925082821015613d2057613d1f613e87565b5b828203905092915050565b6000613d3682613d7f565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b60005b83811015613e0c578082015181840152602081019050613df1565b83811115613e1b576000848401525b50505050565b6000613e2c82613dc7565b91506000821415613e4057613e3f613e87565b5b600182039050919050565b60006002820490506001821680613e6357607f821691505b60208210811415613e7757613e76613f14565b5b50919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b6000601f19601f8301169050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b7f4d617820737570706c7920657863656564656400000000000000000000000000600082015250565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6145d881613d2b565b81146145e357600080fd5b50565b6145ef81613d49565b81146145fa57600080fd5b50565b61460681613d53565b811461461157600080fd5b50565b61461d81613dc7565b811461462857600080fd5b50565b61463481613dd1565b811461463f57600080fd5b50565b61464b81613de1565b811461465657600080fd5b5056fea26469706673582212209c87fc11128436757f8b9f2a6dd8b6446fab15a39659586497c58746ed04390d64736f6c634300080700330000000000000000000000001cb484c87cca254411b365079370021592361e0d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000000000000000006426f6f6b696500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004424f4f4b00000000000000000000000000000000000000000000000000000000

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

0000000000000000000000001cb484c87cca254411b365079370021592361e0d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000000000000000006426f6f6b696500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004424f4f4b00000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : admin (address): 0x1cb484c87cca254411b365079370021592361e0d
Arg [1] : tokenName (string): Bookie
Arg [2] : tokenSymbol (string): BOOK
Arg [3] : maximalSupply (uint256): 100000000000000000
Arg [4] : initialMintAmount (uint256): 5000000000000000

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000001cb484c87cca254411b365079370021592361e0d
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 000000000000000000000000000000000000000000000000016345785d8a0000
Arg [4] : 0000000000000000000000000000000000000000000000000011c37937e08000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [6] : 426f6f6b69650000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 424f4f4b00000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

71556:1553:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66523:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6641:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8808:169;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7761:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9459:492;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67934:123;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68319:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72441:148;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39215:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69367:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10360:215;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52366:251;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72182;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71702:64;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51766:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54805:105;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51522:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7932:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38957:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52906:242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66819:139;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6860:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51969:195;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65910:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11078:413;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8272:175;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54992:582;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38246:645;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71633:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68711:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71773:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8510:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51292:150;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66523:204;66608:4;66647:32;66632:47;;;:11;:47;;;;:87;;;;66683:36;66707:11;66683:23;:36::i;:::-;66632:87;66625:94;;66523:204;;;:::o;6641:100::-;6695:13;6728:5;6721:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6641:100;:::o;8808:169::-;8891:4;8908:39;8917:12;:10;:12::i;:::-;8931:7;8940:6;8908:8;:39::i;:::-;8965:4;8958:11;;8808:169;;;;:::o;7761:108::-;7822:7;7849:12;;7842:19;;7761:108;:::o;9459:492::-;9599:4;9616:36;9626:6;9634:9;9645:6;9616:9;:36::i;:::-;9665:24;9692:11;:19;9704:6;9692:19;;;;;;;;;;;;;;;:33;9712:12;:10;:12::i;:::-;9692:33;;;;;;;;;;;;;;;;9665:60;;9764:6;9744:16;:26;;9736:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;9851:57;9860:6;9868:12;:10;:12::i;:::-;9901:6;9882:16;:25;9851:8;:57::i;:::-;9939:4;9932:11;;;9459:492;;;;;:::o;67934:123::-;68000:7;68027:6;:12;68034:4;68027:12;;;;;;;;;;;:22;;;68020:29;;67934:123;;;:::o;68319:147::-;68402:18;68415:4;68402:12;:18::i;:::-;66401:30;66412:4;66418:12;:10;:12::i;:::-;66401:10;:30::i;:::-;68433:25:::1;68444:4;68450:7;68433:10;:25::i;:::-;68319:147:::0;;;:::o;72441:148::-;72549:5;72580:1;72573:8;;72441:148;:::o;39215:115::-;39275:7;39302:20;:18;:20::i;:::-;39295:27;;39215:115;:::o;69367:218::-;69474:12;:10;:12::i;:::-;69463:23;;:7;:23;;;69455:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;69551:26;69563:4;69569:7;69551:11;:26::i;:::-;69367:218;;:::o;10360:215::-;10448:4;10465:80;10474:12;:10;:12::i;:::-;10488:7;10534:10;10497:11;:25;10509:12;:10;:12::i;:::-;10497:25;;;;;;;;;;;;;;;:34;10523:7;10497:34;;;;;;;;;;;;;;;;:47;;;;:::i;:::-;10465:8;:80::i;:::-;10563:4;10556:11;;10360:215;;;;:::o;52366:251::-;52447:7;52489:12;52475:11;:26;52467:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;52555:54;52574:12;:21;52587:7;52574:21;;;;;;;;;;;;;;;52597:11;52555:18;:54::i;:::-;52548:61;;52366:251;;;;:::o;72182:::-;71671:24;66401:30;66412:4;66418:12;:10;:12::i;:::-;66401:10;:30::i;:::-;72340:9:::1;;72330:6;72314:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;72292:105;;;;;;;;;;;;:::i;:::-;;;;;;;;;72408:17;72414:2;72418:6;72408:5;:17::i;:::-;72182:251:::0;;;:::o;71702:64::-;71741:25;71702:64;:::o;51766:119::-;51831:7;51858:10;:19;51869:7;51858:19;;;;;;;;;;;;;;;;;;;;;;;;;51851:26;;51766:119;;;:::o;54805:105::-;54868:34;54878:12;:10;:12::i;:::-;54892:9;54868;:34::i;:::-;54805:105;:::o;51522:151::-;51592:6;51618:47;51636:12;:21;51649:7;51636:21;;;;;;;;;;;;;;;:28;;;;51618:17;:47::i;:::-;51611:54;;51522:151;;;:::o;7932:127::-;8006:7;8033:9;:18;8043:7;8033:18;;;;;;;;;;;;;;;;8026:25;;7932:127;;;:::o;38957:128::-;39026:7;39053:24;:7;:14;39061:5;39053:14;;;;;;;;;;;;;;;:22;:24::i;:::-;39046:31;;38957:128;;;:::o;52906:242::-;52976:7;53018:12;53004:11;:26;52996:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;53084:56;53103:23;53128:11;53084:18;:56::i;:::-;53077:63;;52906:242;;;:::o;66819:139::-;66897:4;66921:6;:12;66928:4;66921:12;;;;;;;;;;;:20;;:29;66942:7;66921:29;;;;;;;;;;;;;;;;;;;;;;;;;66914:36;;66819:139;;;;:::o;6860:104::-;6916:13;6949:7;6942:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6860:104;:::o;51969:195::-;52025:7;52045:11;52059:12;:21;52072:7;52059:21;;;;;;;;;;;;;;;:28;;;;52045:42;;52112:1;52105:3;:8;:51;;52120:12;:21;52133:7;52120:21;;;;;;;;;;;;;;;52148:1;52142:3;:7;;;;:::i;:::-;52120:30;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;;;;;;;;;52105:51;;;52116:1;52105:51;52098:58;;;;;51969:195;;;:::o;65910:49::-;65955:4;65910:49;;;:::o;11078:413::-;11171:4;11188:24;11215:11;:25;11227:12;:10;:12::i;:::-;11215:25;;;;;;;;;;;;;;;:34;11241:7;11215:34;;;;;;;;;;;;;;;;11188:61;;11288:15;11268:16;:35;;11260:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;11381:67;11390:12;:10;:12::i;:::-;11404:7;11432:15;11413:16;:34;11381:8;:67::i;:::-;11479:4;11472:11;;;11078:413;;;;:::o;8272:175::-;8358:4;8375:42;8385:12;:10;:12::i;:::-;8399:9;8410:6;8375:9;:42::i;:::-;8435:4;8428:11;;8272:175;;;;:::o;54992:582::-;55210:6;55191:15;:25;;55183:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;55261:14;55278:174;55306:87;50543:71;55366:9;55377:5;55384:6;55333:58;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55323:69;;;;;;55306:16;:87::i;:::-;55408:1;55424;55440;55278:13;:174::i;:::-;55261:191;;55480:17;55490:6;55480:9;:17::i;:::-;55471:5;:26;55463:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;55538:28;55548:6;55556:9;55538;:28::i;:::-;55172:402;54992:582;;;;;;:::o;38246:645::-;38490:8;38471:15;:27;;38463:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;38545:18;38587:16;38605:5;38612:7;38621:5;38628:16;38638:5;38628:9;:16::i;:::-;38646:8;38576:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;38566:90;;;;;;38545:111;;38669:12;38684:28;38701:10;38684:16;:28::i;:::-;38669:43;;38725:14;38742:28;38756:4;38762:1;38765;38768;38742:13;:28::i;:::-;38725:45;;38799:5;38789:15;;:6;:15;;;38781:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;38852:31;38861:5;38868:7;38877:5;38852:8;:31::i;:::-;38452:439;;;38246:645;;;;;;;:::o;71633:62::-;71671:24;71633:62;:::o;68711:149::-;68795:18;68808:4;68795:12;:18::i;:::-;66401:30;66412:4;66418:12;:10;:12::i;:::-;66401:10;:30::i;:::-;68826:26:::1;68838:4;68844:7;68826:11;:26::i;:::-;68711:149:::0;;;:::o;71773:24::-;;;;:::o;8510:151::-;8599:7;8626:11;:18;8638:5;8626:18;;;;;;;;;;;;;;;:27;8645:7;8626:27;;;;;;;;;;;;;;;;8619:34;;8510:151;;;;:::o;51292:150::-;51371:17;;:::i;:::-;51408:12;:21;51421:7;51408:21;;;;;;;;;;;;;;;51430:3;51408:26;;;;;;;;;;:::i;:::-;;;;;;;;;51401:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51292:150;;;;:::o;55880:290::-;55965:28;55977:7;55986:6;55965:11;:28::i;:::-;56029:12;:10;:12::i;:::-;56012:29;;:13;:11;:13::i;:::-;:29;;56004:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;56107:55;56124:23;56149:4;56155:6;56107:16;:55::i;:::-;;;55880:290;;:::o;13001:399::-;13104:1;13085:21;;:7;:21;;;;13077:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;13155:49;13184:1;13188:7;13197:6;13155:20;:49::i;:::-;13233:6;13217:12;;:22;;;;;;;:::i;:::-;;;;;;;;13272:6;13250:9;:18;13260:7;13250:18;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;13315:7;13294:37;;13311:1;13294:37;;;13324:6;13294:37;;;;;;:::i;:::-;;;;;;;;13344:48;13372:1;13376:7;13385:6;13344:19;:48::i;:::-;13001:399;;:::o;58724:98::-;58782:7;58813:1;58809;:5;;;;:::i;:::-;58802:12;;58724:98;;;;:::o;42171:195::-;42228:7;42265:17;42256:26;;:5;:26;;42248:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;42352:5;42337:21;;42171:195;;;:::o;44141:190::-;44197:6;44233:16;44224:25;;:5;:25;;44216:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;44317:5;44303:20;;44141:190;;;:::o;56598:262::-;56740:43;56766:4;56772:2;56776:6;56740:25;:43::i;:::-;56796:56;56813:15;56823:4;56813:9;:15::i;:::-;56830:13;56840:2;56830:9;:13::i;:::-;56845:6;56796:16;:56::i;:::-;56598:262;;;:::o;16471:124::-;;;;:::o;58830:103::-;58893:7;58924:1;58920;:5;;;;:::i;:::-;58913:12;;58830:103;;;;:::o;63779:157::-;63864:4;63903:25;63888:40;;;:11;:40;;;;63881:47;;63779:157;;;:::o;4292:98::-;4345:7;4372:10;4365:17;;4292:98;:::o;14762:380::-;14915:1;14898:19;;:5;:19;;;;14890:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;14996:1;14977:21;;:7;:21;;;;14969:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;15080:6;15050:11;:18;15062:5;15050:18;;;;;;;;;;;;;;;:27;15069:7;15050:27;;;;;;;;;;;;;;;:36;;;;15118:7;15102:32;;15111:5;15102:32;;;15127:6;15102:32;;;;;;:::i;:::-;;;;;;;;14762:380;;;:::o;11981:733::-;12139:1;12121:20;;:6;:20;;;;12113:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;12223:1;12202:23;;:9;:23;;;;12194:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;12278:47;12299:6;12307:9;12318:6;12278:20;:47::i;:::-;12338:21;12362:9;:17;12372:6;12362:17;;;;;;;;;;;;;;;;12338:41;;12415:6;12398:13;:23;;12390:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;12536:6;12520:13;:22;12500:9;:17;12510:6;12500:17;;;;;;;;;;;;;;;:42;;;;12588:6;12564:9;:20;12574:9;12564:20;;;;;;;;;;;;;;;;:30;;;;;;;:::i;:::-;;;;;;;;12629:9;12612:35;;12621:6;12612:35;;;12640:6;12612:35;;;;;;:::i;:::-;;;;;;;;12660:46;12680:6;12688:9;12699:6;12660:19;:46::i;:::-;12102:612;11981:733;;;:::o;67248:497::-;67329:22;67337:4;67343:7;67329;:22::i;:::-;67324:414;;67517:41;67545:7;67517:41;;67555:2;67517:19;:41::i;:::-;67631:38;67659:4;67651:13;;67666:2;67631:19;:38::i;:::-;67422:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;67368:358;;;;;;;;;;;:::i;:::-;;;;;;;;67324:414;67248:497;;:::o;70868:238::-;70952:22;70960:4;70966:7;70952;:22::i;:::-;70947:152;;71023:4;70991:6;:12;70998:4;70991:12;;;;;;;;;;;:20;;:29;71012:7;70991:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;71074:12;:10;:12::i;:::-;71047:40;;71065:7;71047:40;;71059:4;71047:40;;;;;;;;;;70947:152;70868:238;;:::o;33907:314::-;33960:7;34001:12;33984:29;;33992:4;33984:29;;;:66;;;;;34034:16;34017:13;:33;33984:66;33980:234;;;34074:24;34067:31;;;;33980:234;34138:64;34160:10;34172:12;34186:15;34138:21;:64::i;:::-;34131:71;;33907:314;;:::o;71238:239::-;71322:22;71330:4;71336:7;71322;:22::i;:::-;71318:152;;;71393:5;71361:6;:12;71368:4;71361:12;;;;;;;;;;;:20;;:29;71382:7;71361:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;71445:12;:10;:12::i;:::-;71418:40;;71436:7;71418:40;;71430:4;71418:40;;;;;;;;;;71318:152;71238:239;;:::o;53237:1482::-;53336:7;54355:12;54370:5;:12;;;;54355:27;;54393:11;54419:236;54432:4;54426:3;:10;54419:236;;;54453:11;54467:23;54480:3;54485:4;54467:12;:23::i;:::-;54453:37;;54532:11;54509:5;54515:3;54509:10;;;;;;;;:::i;:::-;;;;;;;;;:20;;;;;;;;;;;;:34;;;54505:139;;;54571:3;54564:10;;54505:139;;;54627:1;54621:3;:7;;;;:::i;:::-;54615:13;;54505:139;54438:217;54419:236;;;54682:1;54674:4;:9;:37;;54690:5;54703:1;54696:4;:8;;;;:::i;:::-;54690:15;;;;;;;;:::i;:::-;;;;;;;;;:21;;;;;;;;;;;;54674:37;;;54686:1;54674:37;54667:44;;;;;;53237:1482;;;;:::o;72798:145::-;72912:23;72924:2;72928:6;72912:11;:23::i;:::-;72798:145;;:::o;57024:388::-;57109:23;57135:20;57145:9;57135;:20::i;:::-;57109:46;;57166:24;57193:20;57203:9;57193;:20::i;:::-;57166:47;;57248:9;57224:10;:21;57235:9;57224:21;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;57319:9;57275:54;;57302:15;57275:54;;57291:9;57275:54;;;;;;;;;;;;57342:62;57359:15;57376:9;57387:16;57342;:62::i;:::-;57098:314;;57024:388;;:::o;36186:114::-;36251:7;36278;:14;;;36271:21;;36186:114;;;:::o;35134:167::-;35211:7;35238:55;35260:20;:18;:20::i;:::-;35282:10;35238:21;:55::i;:::-;35231:62;;35134:167;;;:::o;28779:279::-;28907:7;28928:17;28947:18;28969:25;28980:4;28986:1;28989;28992;28969:10;:25::i;:::-;28927:67;;;;29005:18;29017:5;29005:11;:18::i;:::-;29041:9;29034:16;;;;28779:279;;;;;;:::o;39468:207::-;39528:15;39556:30;39589:7;:14;39597:5;39589:14;;;;;;;;;;;;;;;39556:47;;39624:15;:5;:13;:15::i;:::-;39614:25;;39650:17;:5;:15;:17::i;:::-;39545:130;39468:207;;;:::o;55681:105::-;55734:7;55761:17;55754:24;;55681:105;:::o;58071:645::-;58245:17;58264;58294:11;58308:5;:12;;;;58294:26;;58350:1;58343:3;:8;:35;;58358:5;58370:1;58364:3;:7;;;;:::i;:::-;58358:14;;;;;;;;:::i;:::-;;;;;;;;;:20;;;;;;;;;;;;58343:35;;;58354:1;58343:35;58331:47;;;;58401:20;58404:9;58415:5;58401:2;:20;;:::i;:::-;58389:32;;58444:1;58438:3;:7;:51;;;;;58477:12;58449:5;58461:1;58455:3;:7;;;;:::i;:::-;58449:14;;;;;;;;:::i;:::-;;;;;;;;;:24;;;;;;;;;;;;:40;;;58438:51;58434:275;;;58529:29;58548:9;58529:18;:29::i;:::-;58506:5;58518:1;58512:3;:7;;;;:::i;:::-;58506:14;;;;;;;;:::i;:::-;;;;;;;;;:20;;;:52;;;;;;;;;;;;;;;;;;58434:275;;;58591:5;58602:94;;;;;;;;58625:31;58643:12;58625:17;:31::i;:::-;58602:94;;;;;;58665:29;58684:9;58665:18;:29::i;:::-;58602:94;;;;;58591:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58434:275;58283:433;58071:645;;;;;;:::o;15742:125::-;;;;:::o;72597:193::-;72739:43;72765:4;72771:2;72775:6;72739:25;:43::i;:::-;72597:193;;;:::o;57420:643::-;57552:3;57545:10;;:3;:10;;;;:24;;;;;57568:1;57559:6;:10;57545:24;57541:515;;;57605:1;57590:17;;:3;:17;;;57586:224;;57629:17;57648;57669:54;57686:12;:17;57699:3;57686:17;;;;;;;;;;;;;;;57705:9;57716:6;57669:16;:54::i;:::-;57628:95;;;;57768:3;57747:47;;;57773:9;57784;57747:47;;;;;;;:::i;:::-;;;;;;;;57609:201;;57586:224;57845:1;57830:17;;:3;:17;;;57826:219;;57869:17;57888;57909:49;57926:12;:17;57939:3;57926:17;;;;;;;;;;;;;;;57945:4;57951:6;57909:16;:49::i;:::-;57868:90;;;;58003:3;57982:47;;;58008:9;58019;57982:47;;;;;;;:::i;:::-;;;;;;;;57849:196;;57826:219;57541:515;57420:643;;;:::o;20645:451::-;20720:13;20746:19;20791:1;20782:6;20778:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;20768:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20746:47;;20804:15;:6;20811:1;20804:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;20830;:6;20837:1;20830:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;20861:9;20886:1;20877:6;20873:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;20861:26;;20856:135;20893:1;20889;:5;20856:135;;;20928:12;20949:3;20941:5;:11;20928:25;;;;;;;:::i;:::-;;;;;20916:6;20923:1;20916:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;20978:1;20968:11;;;;;20896:3;;;;:::i;:::-;;;20856:135;;;;21018:1;21009:5;:10;21001:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;21081:6;21067:21;;;20645:451;;;;:::o;34229:263::-;34373:7;34421:8;34431;34441:11;34454:13;34477:4;34410:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;34400:84;;;;;;34393:91;;34229:263;;;;;:::o;40403:156::-;40465:7;40550:1;40545;40541;:5;40540:11;;;;:::i;:::-;40535:1;40531;:5;40530:21;;;;:::i;:::-;40523:28;;40403:156;;;;:::o;30470:196::-;30563:7;30629:15;30646:10;30600:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;30590:68;;;;;;30583:75;;30470:196;;;;:::o;27008:1632::-;27139:7;27148:12;28073:66;28068:1;28060:10;;:79;28056:163;;;28172:1;28176:30;28156:51;;;;;;28056:163;28238:2;28233:1;:7;;;;:18;;;;;28249:2;28244:1;:7;;;;28233:18;28229:102;;;28284:1;28288:30;28268:51;;;;;;28229:102;28428:14;28445:24;28455:4;28461:1;28464;28467;28445:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28428:41;;28502:1;28484:20;;:6;:20;;;28480:103;;;28537:1;28541:29;28521:50;;;;;;;28480:103;28603:6;28611:20;28595:37;;;;;27008:1632;;;;;;;;:::o;21670:643::-;21748:20;21739:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;21735:571;;;21785:7;;21735:571;21846:29;21837:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;21833:473;;;21892:34;;;;;;;;;;:::i;:::-;;;;;;;;21833:473;21957:35;21948:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;21944:362;;;22009:41;;;;;;;;;;:::i;:::-;;;;;;;;21944:362;22081:30;22072:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;22068:238;;;22128:44;;;;;;;;;;:::i;:::-;;;;;;;;22068:238;22203:30;22194:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;22190:116;;;22250:44;;;;;;;;;;:::i;:::-;;;;;;;;22190:116;21670:643;;:::o;36308:127::-;36415:1;36397:7;:14;;;:19;;;;;;;;;;;36308:127;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::o;7:139:1:-;53:5;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;7:139;;;;:::o;152:::-;198:5;236:6;223:20;214:29;;252:33;279:5;252:33;:::i;:::-;152:139;;;;:::o;297:137::-;342:5;380:6;367:20;358:29;;396:32;422:5;396:32;:::i;:::-;297:137;;;;:::o;440:139::-;486:5;524:6;511:20;502:29;;540:33;567:5;540:33;:::i;:::-;440:139;;;;:::o;585:137::-;630:5;668:6;655:20;646:29;;684:32;710:5;684:32;:::i;:::-;585:137;;;;:::o;728:135::-;772:5;810:6;797:20;788:29;;826:31;851:5;826:31;:::i;:::-;728:135;;;;:::o;869:329::-;928:6;977:2;965:9;956:7;952:23;948:32;945:119;;;983:79;;:::i;:::-;945:119;1103:1;1128:53;1173:7;1164:6;1153:9;1149:22;1128:53;:::i;:::-;1118:63;;1074:117;869:329;;;;:::o;1204:474::-;1272:6;1280;1329:2;1317:9;1308:7;1304:23;1300:32;1297:119;;;1335:79;;:::i;:::-;1297:119;1455:1;1480:53;1525:7;1516:6;1505:9;1501:22;1480:53;:::i;:::-;1470:63;;1426:117;1582:2;1608:53;1653:7;1644:6;1633:9;1629:22;1608:53;:::i;:::-;1598:63;;1553:118;1204:474;;;;;:::o;1684:619::-;1761:6;1769;1777;1826:2;1814:9;1805:7;1801:23;1797:32;1794:119;;;1832:79;;:::i;:::-;1794:119;1952:1;1977:53;2022:7;2013:6;2002:9;1998:22;1977:53;:::i;:::-;1967:63;;1923:117;2079:2;2105:53;2150:7;2141:6;2130:9;2126:22;2105:53;:::i;:::-;2095:63;;2050:118;2207:2;2233:53;2278:7;2269:6;2258:9;2254:22;2233:53;:::i;:::-;2223:63;;2178:118;1684:619;;;;;:::o;2309:1199::-;2420:6;2428;2436;2444;2452;2460;2468;2517:3;2505:9;2496:7;2492:23;2488:33;2485:120;;;2524:79;;:::i;:::-;2485:120;2644:1;2669:53;2714:7;2705:6;2694:9;2690:22;2669:53;:::i;:::-;2659:63;;2615:117;2771:2;2797:53;2842:7;2833:6;2822:9;2818:22;2797:53;:::i;:::-;2787:63;;2742:118;2899:2;2925:53;2970:7;2961:6;2950:9;2946:22;2925:53;:::i;:::-;2915:63;;2870:118;3027:2;3053:53;3098:7;3089:6;3078:9;3074:22;3053:53;:::i;:::-;3043:63;;2998:118;3155:3;3182:51;3225:7;3216:6;3205:9;3201:22;3182:51;:::i;:::-;3172:61;;3126:117;3282:3;3309:53;3354:7;3345:6;3334:9;3330:22;3309:53;:::i;:::-;3299:63;;3253:119;3411:3;3438:53;3483:7;3474:6;3463:9;3459:22;3438:53;:::i;:::-;3428:63;;3382:119;2309:1199;;;;;;;;;;:::o;3514:474::-;3582:6;3590;3639:2;3627:9;3618:7;3614:23;3610:32;3607:119;;;3645:79;;:::i;:::-;3607:119;3765:1;3790:53;3835:7;3826:6;3815:9;3811:22;3790:53;:::i;:::-;3780:63;;3736:117;3892:2;3918:53;3963:7;3954:6;3943:9;3939:22;3918:53;:::i;:::-;3908:63;;3863:118;3514:474;;;;;:::o;3994:1053::-;4096:6;4104;4112;4120;4128;4136;4185:3;4173:9;4164:7;4160:23;4156:33;4153:120;;;4192:79;;:::i;:::-;4153:120;4312:1;4337:53;4382:7;4373:6;4362:9;4358:22;4337:53;:::i;:::-;4327:63;;4283:117;4439:2;4465:53;4510:7;4501:6;4490:9;4486:22;4465:53;:::i;:::-;4455:63;;4410:118;4567:2;4593:53;4638:7;4629:6;4618:9;4614:22;4593:53;:::i;:::-;4583:63;;4538:118;4695:2;4721:51;4764:7;4755:6;4744:9;4740:22;4721:51;:::i;:::-;4711:61;;4666:116;4821:3;4848:53;4893:7;4884:6;4873:9;4869:22;4848:53;:::i;:::-;4838:63;;4792:119;4950:3;4977:53;5022:7;5013:6;5002:9;4998:22;4977:53;:::i;:::-;4967:63;;4921:119;3994:1053;;;;;;;;:::o;5053:472::-;5120:6;5128;5177:2;5165:9;5156:7;5152:23;5148:32;5145:119;;;5183:79;;:::i;:::-;5145:119;5303:1;5328:53;5373:7;5364:6;5353:9;5349:22;5328:53;:::i;:::-;5318:63;;5274:117;5430:2;5456:52;5500:7;5491:6;5480:9;5476:22;5456:52;:::i;:::-;5446:62;;5401:117;5053:472;;;;;:::o;5531:329::-;5590:6;5639:2;5627:9;5618:7;5614:23;5610:32;5607:119;;;5645:79;;:::i;:::-;5607:119;5765:1;5790:53;5835:7;5826:6;5815:9;5811:22;5790:53;:::i;:::-;5780:63;;5736:117;5531:329;;;;:::o;5866:474::-;5934:6;5942;5991:2;5979:9;5970:7;5966:23;5962:32;5959:119;;;5997:79;;:::i;:::-;5959:119;6117:1;6142:53;6187:7;6178:6;6167:9;6163:22;6142:53;:::i;:::-;6132:63;;6088:117;6244:2;6270:53;6315:7;6306:6;6295:9;6291:22;6270:53;:::i;:::-;6260:63;;6215:118;5866:474;;;;;:::o;6346:327::-;6404:6;6453:2;6441:9;6432:7;6428:23;6424:32;6421:119;;;6459:79;;:::i;:::-;6421:119;6579:1;6604:52;6648:7;6639:6;6628:9;6624:22;6604:52;:::i;:::-;6594:62;;6550:116;6346:327;;;;:::o;6679:329::-;6738:6;6787:2;6775:9;6766:7;6762:23;6758:32;6755:119;;;6793:79;;:::i;:::-;6755:119;6913:1;6938:53;6983:7;6974:6;6963:9;6959:22;6938:53;:::i;:::-;6928:63;;6884:117;6679:329;;;;:::o;7014:118::-;7101:24;7119:5;7101:24;:::i;:::-;7096:3;7089:37;7014:118;;:::o;7138:109::-;7219:21;7234:5;7219:21;:::i;:::-;7214:3;7207:34;7138:109;;:::o;7253:118::-;7340:24;7358:5;7340:24;:::i;:::-;7335:3;7328:37;7253:118;;:::o;7377:157::-;7482:45;7502:24;7520:5;7502:24;:::i;:::-;7482:45;:::i;:::-;7477:3;7470:58;7377:157;;:::o;7540:364::-;7628:3;7656:39;7689:5;7656:39;:::i;:::-;7711:71;7775:6;7770:3;7711:71;:::i;:::-;7704:78;;7791:52;7836:6;7831:3;7824:4;7817:5;7813:16;7791:52;:::i;:::-;7868:29;7890:6;7868:29;:::i;:::-;7863:3;7859:39;7852:46;;7632:272;7540:364;;;;:::o;7910:377::-;8016:3;8044:39;8077:5;8044:39;:::i;:::-;8099:89;8181:6;8176:3;8099:89;:::i;:::-;8092:96;;8197:52;8242:6;8237:3;8230:4;8223:5;8219:16;8197:52;:::i;:::-;8274:6;8269:3;8265:16;8258:23;;8020:267;7910:377;;;;:::o;8293:366::-;8435:3;8456:67;8520:2;8515:3;8456:67;:::i;:::-;8449:74;;8532:93;8621:3;8532:93;:::i;:::-;8650:2;8645:3;8641:12;8634:19;;8293:366;;;:::o;8665:::-;8807:3;8828:67;8892:2;8887:3;8828:67;:::i;:::-;8821:74;;8904:93;8993:3;8904:93;:::i;:::-;9022:2;9017:3;9013:12;9006:19;;8665:366;;;:::o;9037:::-;9179:3;9200:67;9264:2;9259:3;9200:67;:::i;:::-;9193:74;;9276:93;9365:3;9276:93;:::i;:::-;9394:2;9389:3;9385:12;9378:19;;9037:366;;;:::o;9409:::-;9551:3;9572:67;9636:2;9631:3;9572:67;:::i;:::-;9565:74;;9648:93;9737:3;9648:93;:::i;:::-;9766:2;9761:3;9757:12;9750:19;;9409:366;;;:::o;9781:::-;9923:3;9944:67;10008:2;10003:3;9944:67;:::i;:::-;9937:74;;10020:93;10109:3;10020:93;:::i;:::-;10138:2;10133:3;10129:12;10122:19;;9781:366;;;:::o;10153:::-;10295:3;10316:67;10380:2;10375:3;10316:67;:::i;:::-;10309:74;;10392:93;10481:3;10392:93;:::i;:::-;10510:2;10505:3;10501:12;10494:19;;10153:366;;;:::o;10525:::-;10667:3;10688:67;10752:2;10747:3;10688:67;:::i;:::-;10681:74;;10764:93;10853:3;10764:93;:::i;:::-;10882:2;10877:3;10873:12;10866:19;;10525:366;;;:::o;10897:::-;11039:3;11060:67;11124:2;11119:3;11060:67;:::i;:::-;11053:74;;11136:93;11225:3;11136:93;:::i;:::-;11254:2;11249:3;11245:12;11238:19;;10897:366;;;:::o;11269:::-;11411:3;11432:67;11496:2;11491:3;11432:67;:::i;:::-;11425:74;;11508:93;11597:3;11508:93;:::i;:::-;11626:2;11621:3;11617:12;11610:19;;11269:366;;;:::o;11641:400::-;11801:3;11822:84;11904:1;11899:3;11822:84;:::i;:::-;11815:91;;11915:93;12004:3;11915:93;:::i;:::-;12033:1;12028:3;12024:11;12017:18;;11641:400;;;:::o;12047:366::-;12189:3;12210:67;12274:2;12269:3;12210:67;:::i;:::-;12203:74;;12286:93;12375:3;12286:93;:::i;:::-;12404:2;12399:3;12395:12;12388:19;;12047:366;;;:::o;12419:::-;12561:3;12582:67;12646:2;12641:3;12582:67;:::i;:::-;12575:74;;12658:93;12747:3;12658:93;:::i;:::-;12776:2;12771:3;12767:12;12760:19;;12419:366;;;:::o;12791:::-;12933:3;12954:67;13018:2;13013:3;12954:67;:::i;:::-;12947:74;;13030:93;13119:3;13030:93;:::i;:::-;13148:2;13143:3;13139:12;13132:19;;12791:366;;;:::o;13163:::-;13305:3;13326:67;13390:2;13385:3;13326:67;:::i;:::-;13319:74;;13402:93;13491:3;13402:93;:::i;:::-;13520:2;13515:3;13511:12;13504:19;;13163:366;;;:::o;13535:::-;13677:3;13698:67;13762:2;13757:3;13698:67;:::i;:::-;13691:74;;13774:93;13863:3;13774:93;:::i;:::-;13892:2;13887:3;13883:12;13876:19;;13535:366;;;:::o;13907:::-;14049:3;14070:67;14134:2;14129:3;14070:67;:::i;:::-;14063:74;;14146:93;14235:3;14146:93;:::i;:::-;14264:2;14259:3;14255:12;14248:19;;13907:366;;;:::o;14279:::-;14421:3;14442:67;14506:2;14501:3;14442:67;:::i;:::-;14435:74;;14518:93;14607:3;14518:93;:::i;:::-;14636:2;14631:3;14627:12;14620:19;;14279:366;;;:::o;14651:::-;14793:3;14814:67;14878:2;14873:3;14814:67;:::i;:::-;14807:74;;14890:93;14979:3;14890:93;:::i;:::-;15008:2;15003:3;14999:12;14992:19;;14651:366;;;:::o;15023:::-;15165:3;15186:67;15250:2;15245:3;15186:67;:::i;:::-;15179:74;;15262:93;15351:3;15262:93;:::i;:::-;15380:2;15375:3;15371:12;15364:19;;15023:366;;;:::o;15395:::-;15537:3;15558:67;15622:2;15617:3;15558:67;:::i;:::-;15551:74;;15634:93;15723:3;15634:93;:::i;:::-;15752:2;15747:3;15743:12;15736:19;;15395:366;;;:::o;15767:::-;15909:3;15930:67;15994:2;15989:3;15930:67;:::i;:::-;15923:74;;16006:93;16095:3;16006:93;:::i;:::-;16124:2;16119:3;16115:12;16108:19;;15767:366;;;:::o;16139:402::-;16299:3;16320:85;16402:2;16397:3;16320:85;:::i;:::-;16313:92;;16414:93;16503:3;16414:93;:::i;:::-;16532:2;16527:3;16523:12;16516:19;;16139:402;;;:::o;16547:366::-;16689:3;16710:67;16774:2;16769:3;16710:67;:::i;:::-;16703:74;;16786:93;16875:3;16786:93;:::i;:::-;16904:2;16899:3;16895:12;16888:19;;16547:366;;;:::o;16919:402::-;17079:3;17100:85;17182:2;17177:3;17100:85;:::i;:::-;17093:92;;17194:93;17283:3;17194:93;:::i;:::-;17312:2;17307:3;17303:12;17296:19;;16919:402;;;:::o;17327:366::-;17469:3;17490:67;17554:2;17549:3;17490:67;:::i;:::-;17483:74;;17566:93;17655:3;17566:93;:::i;:::-;17684:2;17679:3;17675:12;17668:19;;17327:366;;;:::o;17699:::-;17841:3;17862:67;17926:2;17921:3;17862:67;:::i;:::-;17855:74;;17938:93;18027:3;17938:93;:::i;:::-;18056:2;18051:3;18047:12;18040:19;;17699:366;;;:::o;18139:517::-;18292:4;18287:3;18283:14;18384:4;18377:5;18373:16;18367:23;18403:61;18458:4;18453:3;18449:14;18435:12;18403:61;:::i;:::-;18307:167;18557:4;18550:5;18546:16;18540:23;18576:63;18633:4;18628:3;18624:14;18610:12;18576:63;:::i;:::-;18484:165;18261:395;18139:517;;:::o;18662:108::-;18739:24;18757:5;18739:24;:::i;:::-;18734:3;18727:37;18662:108;;:::o;18776:118::-;18863:24;18881:5;18863:24;:::i;:::-;18858:3;18851:37;18776:118;;:::o;18900:105::-;18975:23;18992:5;18975:23;:::i;:::-;18970:3;18963:36;18900:105;;:::o;19011:115::-;19096:23;19113:5;19096:23;:::i;:::-;19091:3;19084:36;19011:115;;:::o;19132:112::-;19215:22;19231:5;19215:22;:::i;:::-;19210:3;19203:35;19132:112;;:::o;19250:663::-;19491:3;19513:148;19657:3;19513:148;:::i;:::-;19506:155;;19671:75;19742:3;19733:6;19671:75;:::i;:::-;19771:2;19766:3;19762:12;19755:19;;19784:75;19855:3;19846:6;19784:75;:::i;:::-;19884:2;19879:3;19875:12;19868:19;;19904:3;19897:10;;19250:663;;;;;:::o;19919:967::-;20301:3;20323:148;20467:3;20323:148;:::i;:::-;20316:155;;20488:95;20579:3;20570:6;20488:95;:::i;:::-;20481:102;;20600:148;20744:3;20600:148;:::i;:::-;20593:155;;20765:95;20856:3;20847:6;20765:95;:::i;:::-;20758:102;;20877:3;20870:10;;19919:967;;;;;:::o;20892:222::-;20985:4;21023:2;21012:9;21008:18;21000:26;;21036:71;21104:1;21093:9;21089:17;21080:6;21036:71;:::i;:::-;20892:222;;;;:::o;21120:210::-;21207:4;21245:2;21234:9;21230:18;21222:26;;21258:65;21320:1;21309:9;21305:17;21296:6;21258:65;:::i;:::-;21120:210;;;;:::o;21336:222::-;21429:4;21467:2;21456:9;21452:18;21444:26;;21480:71;21548:1;21537:9;21533:17;21524:6;21480:71;:::i;:::-;21336:222;;;;:::o;21564:775::-;21797:4;21835:3;21824:9;21820:19;21812:27;;21849:71;21917:1;21906:9;21902:17;21893:6;21849:71;:::i;:::-;21930:72;21998:2;21987:9;21983:18;21974:6;21930:72;:::i;:::-;22012;22080:2;22069:9;22065:18;22056:6;22012:72;:::i;:::-;22094;22162:2;22151:9;22147:18;22138:6;22094:72;:::i;:::-;22176:73;22244:3;22233:9;22229:19;22220:6;22176:73;:::i;:::-;22259;22327:3;22316:9;22312:19;22303:6;22259:73;:::i;:::-;21564:775;;;;;;;;;:::o;22345:553::-;22522:4;22560:3;22549:9;22545:19;22537:27;;22574:71;22642:1;22631:9;22627:17;22618:6;22574:71;:::i;:::-;22655:72;22723:2;22712:9;22708:18;22699:6;22655:72;:::i;:::-;22737;22805:2;22794:9;22790:18;22781:6;22737:72;:::i;:::-;22819;22887:2;22876:9;22872:18;22863:6;22819:72;:::i;:::-;22345:553;;;;;;;:::o;22904:664::-;23109:4;23147:3;23136:9;23132:19;23124:27;;23161:71;23229:1;23218:9;23214:17;23205:6;23161:71;:::i;:::-;23242:72;23310:2;23299:9;23295:18;23286:6;23242:72;:::i;:::-;23324;23392:2;23381:9;23377:18;23368:6;23324:72;:::i;:::-;23406;23474:2;23463:9;23459:18;23450:6;23406:72;:::i;:::-;23488:73;23556:3;23545:9;23541:19;23532:6;23488:73;:::i;:::-;22904:664;;;;;;;;:::o;23574:545::-;23747:4;23785:3;23774:9;23770:19;23762:27;;23799:71;23867:1;23856:9;23852:17;23843:6;23799:71;:::i;:::-;23880:68;23944:2;23933:9;23929:18;23920:6;23880:68;:::i;:::-;23958:72;24026:2;24015:9;24011:18;24002:6;23958:72;:::i;:::-;24040;24108:2;24097:9;24093:18;24084:6;24040:72;:::i;:::-;23574:545;;;;;;;:::o;24125:313::-;24238:4;24276:2;24265:9;24261:18;24253:26;;24325:9;24319:4;24315:20;24311:1;24300:9;24296:17;24289:47;24353:78;24426:4;24417:6;24353:78;:::i;:::-;24345:86;;24125:313;;;;:::o;24444:419::-;24610:4;24648:2;24637:9;24633:18;24625:26;;24697:9;24691:4;24687:20;24683:1;24672:9;24668:17;24661:47;24725:131;24851:4;24725:131;:::i;:::-;24717:139;;24444:419;;;:::o;24869:::-;25035:4;25073:2;25062:9;25058:18;25050:26;;25122:9;25116:4;25112:20;25108:1;25097:9;25093:17;25086:47;25150:131;25276:4;25150:131;:::i;:::-;25142:139;;24869:419;;;:::o;25294:::-;25460:4;25498:2;25487:9;25483:18;25475:26;;25547:9;25541:4;25537:20;25533:1;25522:9;25518:17;25511:47;25575:131;25701:4;25575:131;:::i;:::-;25567:139;;25294:419;;;:::o;25719:::-;25885:4;25923:2;25912:9;25908:18;25900:26;;25972:9;25966:4;25962:20;25958:1;25947:9;25943:17;25936:47;26000:131;26126:4;26000:131;:::i;:::-;25992:139;;25719:419;;;:::o;26144:::-;26310:4;26348:2;26337:9;26333:18;26325:26;;26397:9;26391:4;26387:20;26383:1;26372:9;26368:17;26361:47;26425:131;26551:4;26425:131;:::i;:::-;26417:139;;26144:419;;;:::o;26569:::-;26735:4;26773:2;26762:9;26758:18;26750:26;;26822:9;26816:4;26812:20;26808:1;26797:9;26793:17;26786:47;26850:131;26976:4;26850:131;:::i;:::-;26842:139;;26569:419;;;:::o;26994:::-;27160:4;27198:2;27187:9;27183:18;27175:26;;27247:9;27241:4;27237:20;27233:1;27222:9;27218:17;27211:47;27275:131;27401:4;27275:131;:::i;:::-;27267:139;;26994:419;;;:::o;27419:::-;27585:4;27623:2;27612:9;27608:18;27600:26;;27672:9;27666:4;27662:20;27658:1;27647:9;27643:17;27636:47;27700:131;27826:4;27700:131;:::i;:::-;27692:139;;27419:419;;;:::o;27844:::-;28010:4;28048:2;28037:9;28033:18;28025:26;;28097:9;28091:4;28087:20;28083:1;28072:9;28068:17;28061:47;28125:131;28251:4;28125:131;:::i;:::-;28117:139;;27844:419;;;:::o;28269:::-;28435:4;28473:2;28462:9;28458:18;28450:26;;28522:9;28516:4;28512:20;28508:1;28497:9;28493:17;28486:47;28550:131;28676:4;28550:131;:::i;:::-;28542:139;;28269:419;;;:::o;28694:::-;28860:4;28898:2;28887:9;28883:18;28875:26;;28947:9;28941:4;28937:20;28933:1;28922:9;28918:17;28911:47;28975:131;29101:4;28975:131;:::i;:::-;28967:139;;28694:419;;;:::o;29119:::-;29285:4;29323:2;29312:9;29308:18;29300:26;;29372:9;29366:4;29362:20;29358:1;29347:9;29343:17;29336:47;29400:131;29526:4;29400:131;:::i;:::-;29392:139;;29119:419;;;:::o;29544:::-;29710:4;29748:2;29737:9;29733:18;29725:26;;29797:9;29791:4;29787:20;29783:1;29772:9;29768:17;29761:47;29825:131;29951:4;29825:131;:::i;:::-;29817:139;;29544:419;;;:::o;29969:::-;30135:4;30173:2;30162:9;30158:18;30150:26;;30222:9;30216:4;30212:20;30208:1;30197:9;30193:17;30186:47;30250:131;30376:4;30250:131;:::i;:::-;30242:139;;29969:419;;;:::o;30394:::-;30560:4;30598:2;30587:9;30583:18;30575:26;;30647:9;30641:4;30637:20;30633:1;30622:9;30618:17;30611:47;30675:131;30801:4;30675:131;:::i;:::-;30667:139;;30394:419;;;:::o;30819:::-;30985:4;31023:2;31012:9;31008:18;31000:26;;31072:9;31066:4;31062:20;31058:1;31047:9;31043:17;31036:47;31100:131;31226:4;31100:131;:::i;:::-;31092:139;;30819:419;;;:::o;31244:::-;31410:4;31448:2;31437:9;31433:18;31425:26;;31497:9;31491:4;31487:20;31483:1;31472:9;31468:17;31461:47;31525:131;31651:4;31525:131;:::i;:::-;31517:139;;31244:419;;;:::o;31669:::-;31835:4;31873:2;31862:9;31858:18;31850:26;;31922:9;31916:4;31912:20;31908:1;31897:9;31893:17;31886:47;31950:131;32076:4;31950:131;:::i;:::-;31942:139;;31669:419;;;:::o;32094:::-;32260:4;32298:2;32287:9;32283:18;32275:26;;32347:9;32341:4;32337:20;32333:1;32322:9;32318:17;32311:47;32375:131;32501:4;32375:131;:::i;:::-;32367:139;;32094:419;;;:::o;32519:::-;32685:4;32723:2;32712:9;32708:18;32700:26;;32772:9;32766:4;32762:20;32758:1;32747:9;32743:17;32736:47;32800:131;32926:4;32800:131;:::i;:::-;32792:139;;32519:419;;;:::o;32944:::-;33110:4;33148:2;33137:9;33133:18;33125:26;;33197:9;33191:4;33187:20;33183:1;33172:9;33168:17;33161:47;33225:131;33351:4;33225:131;:::i;:::-;33217:139;;32944:419;;;:::o;33369:::-;33535:4;33573:2;33562:9;33558:18;33550:26;;33622:9;33616:4;33612:20;33608:1;33597:9;33593:17;33586:47;33650:131;33776:4;33650:131;:::i;:::-;33642:139;;33369:419;;;:::o;33794:::-;33960:4;33998:2;33987:9;33983:18;33975:26;;34047:9;34041:4;34037:20;34033:1;34022:9;34018:17;34011:47;34075:131;34201:4;34075:131;:::i;:::-;34067:139;;33794:419;;;:::o;34219:334::-;34368:4;34406:2;34395:9;34391:18;34383:26;;34419:127;34543:1;34532:9;34528:17;34519:6;34419:127;:::i;:::-;34219:334;;;;:::o;34559:222::-;34652:4;34690:2;34679:9;34675:18;34667:26;;34703:71;34771:1;34760:9;34756:17;34747:6;34703:71;:::i;:::-;34559:222;;;;:::o;34787:332::-;34908:4;34946:2;34935:9;34931:18;34923:26;;34959:71;35027:1;35016:9;35012:17;35003:6;34959:71;:::i;:::-;35040:72;35108:2;35097:9;35093:18;35084:6;35040:72;:::i;:::-;34787:332;;;;;:::o;35125:218::-;35216:4;35254:2;35243:9;35239:18;35231:26;;35267:69;35333:1;35322:9;35318:17;35309:6;35267:69;:::i;:::-;35125:218;;;;:::o;35349:214::-;35438:4;35476:2;35465:9;35461:18;35453:26;;35489:67;35553:1;35542:9;35538:17;35529:6;35489:67;:::i;:::-;35349:214;;;;:::o;35650:99::-;35702:6;35736:5;35730:12;35720:22;;35650:99;;;:::o;35755:169::-;35839:11;35873:6;35868:3;35861:19;35913:4;35908:3;35904:14;35889:29;;35755:169;;;;:::o;35930:148::-;36032:11;36069:3;36054:18;;35930:148;;;;:::o;36084:305::-;36124:3;36143:20;36161:1;36143:20;:::i;:::-;36138:25;;36177:20;36195:1;36177:20;:::i;:::-;36172:25;;36331:1;36263:66;36259:74;36256:1;36253:81;36250:107;;;36337:18;;:::i;:::-;36250:107;36381:1;36378;36374:9;36367:16;;36084:305;;;;:::o;36395:185::-;36435:1;36452:20;36470:1;36452:20;:::i;:::-;36447:25;;36486:20;36504:1;36486:20;:::i;:::-;36481:25;;36525:1;36515:35;;36530:18;;:::i;:::-;36515:35;36572:1;36569;36565:9;36560:14;;36395:185;;;;:::o;36586:348::-;36626:7;36649:20;36667:1;36649:20;:::i;:::-;36644:25;;36683:20;36701:1;36683:20;:::i;:::-;36678:25;;36871:1;36803:66;36799:74;36796:1;36793:81;36788:1;36781:9;36774:17;36770:105;36767:131;;;36878:18;;:::i;:::-;36767:131;36926:1;36923;36919:9;36908:20;;36586:348;;;;:::o;36940:191::-;36980:4;37000:20;37018:1;37000:20;:::i;:::-;36995:25;;37034:20;37052:1;37034:20;:::i;:::-;37029:25;;37073:1;37070;37067:8;37064:34;;;37078:18;;:::i;:::-;37064:34;37123:1;37120;37116:9;37108:17;;36940:191;;;;:::o;37137:96::-;37174:7;37203:24;37221:5;37203:24;:::i;:::-;37192:35;;37137:96;;;:::o;37239:90::-;37273:7;37316:5;37309:13;37302:21;37291:32;;37239:90;;;:::o;37335:77::-;37372:7;37401:5;37390:16;;37335:77;;;:::o;37418:149::-;37454:7;37494:66;37487:5;37483:78;37472:89;;37418:149;;;:::o;37573:126::-;37610:7;37650:42;37643:5;37639:54;37628:65;;37573:126;;;:::o;37705:142::-;37742:7;37782:58;37775:5;37771:70;37760:81;;37705:142;;;:::o;37853:77::-;37890:7;37919:5;37908:16;;37853:77;;;:::o;37936:93::-;37972:7;38012:10;38005:5;38001:22;37990:33;;37936:93;;;:::o;38035:86::-;38070:7;38110:4;38103:5;38099:16;38088:27;;38035:86;;;:::o;38127:307::-;38195:1;38205:113;38219:6;38216:1;38213:13;38205:113;;;38304:1;38299:3;38295:11;38289:18;38285:1;38280:3;38276:11;38269:39;38241:2;38238:1;38234:10;38229:15;;38205:113;;;38336:6;38333:1;38330:13;38327:101;;;38416:1;38407:6;38402:3;38398:16;38391:27;38327:101;38176:258;38127:307;;;:::o;38440:171::-;38479:3;38502:24;38520:5;38502:24;:::i;:::-;38493:33;;38548:4;38541:5;38538:15;38535:41;;;38556:18;;:::i;:::-;38535:41;38603:1;38596:5;38592:13;38585:20;;38440:171;;;:::o;38617:320::-;38661:6;38698:1;38692:4;38688:12;38678:22;;38745:1;38739:4;38735:12;38766:18;38756:81;;38822:4;38814:6;38810:17;38800:27;;38756:81;38884:2;38876:6;38873:14;38853:18;38850:38;38847:84;;;38903:18;;:::i;:::-;38847:84;38668:269;38617:320;;;:::o;38943:79::-;38982:7;39011:5;39000:16;;38943:79;;;:::o;39028:180::-;39076:77;39073:1;39066:88;39173:4;39170:1;39163:15;39197:4;39194:1;39187:15;39214:180;39262:77;39259:1;39252:88;39359:4;39356:1;39349:15;39383:4;39380:1;39373:15;39400:180;39448:77;39445:1;39438:88;39545:4;39542:1;39535:15;39569:4;39566:1;39559:15;39586:180;39634:77;39631:1;39624:88;39731:4;39728:1;39721:15;39755:4;39752:1;39745:15;39772:180;39820:77;39817:1;39810:88;39917:4;39914:1;39907:15;39941:4;39938:1;39931:15;39958:180;40006:77;40003:1;39996:88;40103:4;40100:1;40093:15;40127:4;40124:1;40117:15;40267:117;40376:1;40373;40366:12;40390:102;40431:6;40482:2;40478:7;40473:2;40466:5;40462:14;40458:28;40448:38;;40390:102;;;:::o;40498:174::-;40638:26;40634:1;40626:6;40622:14;40615:50;40498:174;:::o;40678:182::-;40818:34;40814:1;40806:6;40802:14;40795:58;40678:182;:::o;40866:222::-;41006:34;41002:1;40994:6;40990:14;40983:58;41075:5;41070:2;41062:6;41058:15;41051:30;40866:222;:::o;41094:181::-;41234:33;41230:1;41222:6;41218:14;41211:57;41094:181;:::o;41281:169::-;41421:21;41417:1;41409:6;41405:14;41398:45;41281:169;:::o;41456:179::-;41596:31;41592:1;41584:6;41580:14;41573:55;41456:179;:::o;41641:181::-;41781:33;41777:1;41769:6;41765:14;41758:57;41641:181;:::o;41828:175::-;41968:27;41964:1;41956:6;41952:14;41945:51;41828:175;:::o;42009:221::-;42149:34;42145:1;42137:6;42133:14;42126:58;42218:4;42213:2;42205:6;42201:15;42194:29;42009:221;:::o;42236:214::-;42376:66;42372:1;42364:6;42360:14;42353:90;42236:214;:::o;42456:179::-;42596:31;42592:1;42584:6;42580:14;42573:55;42456:179;:::o;42641:225::-;42781:34;42777:1;42769:6;42765:14;42758:58;42850:8;42845:2;42837:6;42833:15;42826:33;42641:225;:::o;42872:221::-;43012:34;43008:1;43000:6;42996:14;42989:58;43081:4;43076:2;43068:6;43064:15;43057:29;42872:221;:::o;43099:::-;43239:34;43235:1;43227:6;43223:14;43216:58;43308:4;43303:2;43295:6;43291:15;43284:29;43099:221;:::o;43326:180::-;43466:32;43462:1;43454:6;43450:14;43443:56;43326:180;:::o;43512:227::-;43652:34;43648:1;43640:6;43636:14;43629:58;43721:10;43716:2;43708:6;43704:15;43697:35;43512:227;:::o;43745:235::-;43885:34;43881:1;43873:6;43869:14;43862:58;43954:18;43949:2;43941:6;43937:15;43930:43;43745:235;:::o;43986:226::-;44126:34;44122:1;44114:6;44110:14;44103:58;44195:9;44190:2;44182:6;44178:15;44171:34;43986:226;:::o;44218:224::-;44358:34;44354:1;44346:6;44342:14;44335:58;44427:7;44422:2;44414:6;44410:15;44403:32;44218:224;:::o;44448:225::-;44588:34;44584:1;44576:6;44572:14;44565:58;44657:8;44652:2;44644:6;44640:15;44633:33;44448:225;:::o;44679:223::-;44819:34;44815:1;44807:6;44803:14;44796:58;44888:6;44883:2;44875:6;44871:15;44864:31;44679:223;:::o;44908:173::-;45048:25;45044:1;45036:6;45032:14;45025:49;44908:173;:::o;45087:224::-;45227:34;45223:1;45215:6;45211:14;45204:58;45296:7;45291:2;45283:6;45279:15;45272:32;45087:224;:::o;45317:167::-;45457:19;45453:1;45445:6;45441:14;45434:43;45317:167;:::o;45490:234::-;45630:34;45626:1;45618:6;45614:14;45607:58;45699:17;45694:2;45686:6;45682:15;45675:42;45490:234;:::o;45730:181::-;45870:33;45866:1;45858:6;45854:14;45847:57;45730:181;:::o;45917:122::-;45990:24;46008:5;45990:24;:::i;:::-;45983:5;45980:35;45970:63;;46029:1;46026;46019:12;45970:63;45917:122;:::o;46045:::-;46118:24;46136:5;46118:24;:::i;:::-;46111:5;46108:35;46098:63;;46157:1;46154;46147:12;46098:63;46045:122;:::o;46173:120::-;46245:23;46262:5;46245:23;:::i;:::-;46238:5;46235:34;46225:62;;46283:1;46280;46273:12;46225:62;46173:120;:::o;46299:122::-;46372:24;46390:5;46372:24;:::i;:::-;46365:5;46362:35;46352:63;;46411:1;46408;46401:12;46352:63;46299:122;:::o;46427:120::-;46499:23;46516:5;46499:23;:::i;:::-;46492:5;46489:34;46479:62;;46537:1;46534;46527:12;46479:62;46427:120;:::o;46553:118::-;46624:22;46640:5;46624:22;:::i;:::-;46617:5;46614:33;46604:61;;46661:1;46658;46651:12;46604:61;46553:118;:::o

Swarm Source

ipfs://9c87fc11128436757f8b9f2a6dd8b6446fab15a39659586497c58746ed04390d
Loading