ETH Price: $3,271.12 (-2.63%)

Token

Spellbook (SPELL)
 

Overview

Max Total Supply

8 SPELL

Holders

8

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
jinandtonix.eth
Balance
1 SPELL
0xf376eae57e7a22908b23d27c1a103ab237396e15
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Spellbook

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 2021-09-08
*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = '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] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, 'Strings: hex length insufficient');
        return string(buffer);
    }
}

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{value: amount}('');
        require(success, 'Address: unable to send value, recipient may have reverted');
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), 'Address: static call to non-contract');

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), 'Address: delegate call to non-contract');

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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

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

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), 'Ownable: caller is not the owner');
        _;
    }

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

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

pragma solidity ^0.8.0;

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), 'ERC721: balance query for the zero address');
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), 'ERC721: owner query for nonexistent token');
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), 'ERC721Metadata: URI query for nonexistent token');

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, 'ERC721: approval to current owner');

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            'ERC721: approve caller is not owner nor approved for all'
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), 'ERC721: approved query for nonexistent token');

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), 'ERC721: approve to caller');

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), 'ERC721: transfer caller is not owner nor approved');

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), 'ERC721: transfer caller is not owner nor approved');
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), 'ERC721: transfer to non ERC721Receiver implementer');
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), 'ERC721: operator query for nonexistent token');
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, '');
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            'ERC721: transfer to non ERC721Receiver implementer'
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), 'ERC721: mint to the zero address');
        require(!_exists(tokenId), 'ERC721: token already minted');

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, 'ERC721: transfer of token that is not own');
        require(to != address(0), 'ERC721: transfer to the zero address');

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert('ERC721: transfer to non ERC721Receiver implementer');
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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

pragma solidity ^0.8.0;

/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), 'ERC721Enumerable: owner index out of bounds');
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), 'ERC721Enumerable: global index out of bounds');
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}



pragma solidity ^0.8.0;

contract Spellbook is ERC721Enumerable, Ownable {

    string[] private power = [
        "Noob",
        "Weak",
        "Good",
        "Great",
        "Mighty"
    ];

    string[] private element = [
        "Water",
        "Lightning",
        "Rock",
        "Fire",
        "Poison",
        "Shit",
        "Gas",
        "Etherium",
        "Holy",
        "Unholy",
        "Energy",
        "Ice",
        "Shadow"
    ];
    
    string[] private defensive = [
        "Shield",
        "Aura",
        "Wall",
        "Blades Aura",
        "Block"
    ];
    string[] private attack = [
        "Arrow",
        "Ball",
        "Weakness",
        "Bolt",
        "Explosion",
        "Orb",
        "Blast"
    ];
    string[] private buffs = [
        "Heal",
        "Strength",
        "Aguility",
        "Speed",
        "Cure",
        "Poison"
    ];
    string[] private summon = [
        "Ant",
        "Spider",
        "Elemental",
        "Daemon",
        "Patronus",
        "Skeleton",
        "Fairy"
    ];
    string[] private extra = [
        "Telekinesis",
        "Teleportation",
        "Invisibility",
        "Paralyze",
        "Polymorpth",
        "Earthquake ",
        "Nightsight ",
        "Wisdom",
        "Illusion",
        "Drain Magic",
        "Drain Life",
        "Cast some ETH",
        "Call of Vitalik"
    ];
    
    

    function  random(string memory input) internal pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(input)));
    }

    function getDefensive(uint256 tokenId) public view returns (string memory) {
        return pluck(tokenId, "DEFENSIVE", defensive,1);
    }

    function getAttack(uint256 tokenId) public view returns (string memory) {
        return pluck(tokenId, "ATTACK", attack,2);
    }

    function getBuffs(uint256 tokenId) public view returns (string memory) {
        return pluck(tokenId, "BUFFS", buffs,3);
    }

    function getSummon(uint256 tokenId) public view returns (string memory) {
        return pluck(tokenId, "SUMMON", summon,4);
    }

    function getExtra(uint256 tokenId) public view returns (string memory) {
        return pluck(tokenId, "EXTRA", extra,5);
    }

    
    function pluck(uint256 tokenId, string memory keyPrefix, string[] memory sourceArray,uint256 id) internal view returns (string memory) {
        uint256 rand = random(string(abi.encodePacked(keyPrefix, toString(tokenId))));
        string memory output = sourceArray[rand % sourceArray.length];
        uint256 greatness = rand % 21;
       
        string[2] memory name;
        if(greatness==12){
            name[0]= "Heroic";
        }
        else{
            name[0] = power[rand % power.length];
        }
        name[1] = element[rand % element.length];
        if(id==5){
            output = string(abi.encodePacked('', name[0], ' ', output));
        }
        else{
            output = string(abi.encodePacked('', name[0], ' ', output, ' of ', name[1]));
        }
            
       
        return output;
    }

    function tokenURI(uint256 tokenId) override public view returns (string memory) {
        string[17] memory parts;
        parts[0] = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350"><style>.base { fill: black; font-family: serif; font-size: 14px; }.header{ fill: black; font-family: serif; font-size: 40px; }</style><rect width="100%" height="100%" fill="black" /><path d="M26 55.5L51.5 15.5L308 13L322.5 27L310 50L313.5 85.5H299.5L313.5 94.5L317.5 241H299.5L313.5 244.5V258.5L322.5 286V322.5L94 342L80.5 326L63 331L26 282L31 272.5V263L35.5 258.5L31 251.5L35.5 217H26V160.5L35.5 155L31 131L26 126L23 85.5L26 55.5Z" fill="white"/><text x="96" y="60" class="header" >Spellbook</text><text x="96" y="130" class="base">';

        parts[1] = getDefensive(tokenId);

        parts[2] = '</text><text x="96" y="150" class="base">';

        parts[3] = getAttack(tokenId);

        parts[4] = '</text><text x="96" y="170" class="base">';

        parts[5] = getBuffs(tokenId);

        parts[6] = '</text><text x="96" y="190" class="base">';

        parts[7] = getSummon(tokenId);

        parts[8] = '</text><text x="96" y="210" class="base">';

        parts[9] = getExtra(tokenId);

        parts[16] = '</text></svg>';

        string memory output = string(abi.encodePacked(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8]));
        output = string(abi.encodePacked(output, parts[9], parts[10], parts[11], parts[12], parts[13], parts[14], parts[15], parts[16]));

        string[11] memory attrParts;
        attrParts[0] = '[{ "trait_type": "Defensive", "value": "';
        attrParts[1] = parts[1];
        attrParts[2] = '" }, { "trait_type": "Attack", "value": "';
        attrParts[3] = parts[3];
        attrParts[4] = '" }, { "trait_type": "Buff", "value": "';
        attrParts[5] = parts[5];
        attrParts[6] = '" }, { "trait_type": "Summon", "value": "';
        attrParts[7] = parts[7];
        attrParts[8] = '" }, { "trait_type": "Extra", "value": "';
        attrParts[9] = parts[9];
        attrParts[10] = '" }]';
        
        string memory atrrOutput = string(abi.encodePacked(attrParts[0], attrParts[1], attrParts[2], attrParts[3], attrParts[4], attrParts[5], attrParts[6], attrParts[7]));
        atrrOutput = string(abi.encodePacked(atrrOutput, attrParts[8], attrParts[9], attrParts[10]));

        string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Spellbook #', toString(tokenId), '", "description": "Cast your spells any time you want to.", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '","attributes":', atrrOutput, '}'))));
        output = string(abi.encodePacked('data:application/json;base64,', json));

        return output;
    }
    
    uint256 public constant NFT_PRICE = 50000000000000000; // 0.05 ETH
    uint public constant MAX_NFT_PURCHASE = 20;
    uint256 public MAX_SUPPLY = 10000;
    mapping(address => bool) minted;
    mapping(address => uint256) purchased;
    
    modifier mintOnlyOnce() {
        require(!minted[_msgSender()], 'Can only mint once');
        minted[_msgSender()] = true;
        _;
    }

    function mintFreeOne() public  mintOnlyOnce {
        require(totalSupply()+1 < 10000, "Everything is already minted");
        //require(saleIsActive, 'Sale is not active at the moment');
        _safeMint(_msgSender(), totalSupply());
    }
    
    
    function mintSpells(uint numberOfTokens) public payable {
        require(purchased[msg.sender] +numberOfTokens <= MAX_NFT_PURCHASE, 'Can only mint up to 20 per address');
        //require(saleIsActive, 'Sale is not active at the moment');
        require(numberOfTokens > 0, "Number of tokens can not be less than or equal to 0");
        require(totalSupply() +numberOfTokens <= MAX_SUPPLY, "Purchase would exceed max supply of Spells");
        require(numberOfTokens <= MAX_NFT_PURCHASE,"Can only mint up to 20 per purchase");
        require(NFT_PRICE * numberOfTokens == msg.value, "Sent ether value is incorrect");
        purchased[msg.sender] = purchased[msg.sender] + numberOfTokens;
        for (uint i = 0; i < numberOfTokens; i++) {
            _safeMint(msg.sender, totalSupply());
        }
    }
    
    
    // ADMIN ACTIONS
    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }
    

    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // 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);
    }

    constructor() ERC721("Spellbook", "SPELL") Ownable() {
        
    }
}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_NFT_PURCHASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getAttack","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getBuffs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDefensive","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getExtra","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSummon","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintFreeOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintSpells","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","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":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","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":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060a001604052806040518060400160405280600481526020017f4e6f6f620000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f5765616b0000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f476f6f640000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f477265617400000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f4d69676874790000000000000000000000000000000000000000000000000000815250815250600b9060056200014692919062000f25565b50604051806101a001604052806040518060400160405280600581526020017f576174657200000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600981526020017f4c696768746e696e67000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f526f636b0000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f466972650000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f506f69736f6e000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f536869740000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f476173000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f457468657269756d00000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f486f6c790000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f556e686f6c79000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f456e65726779000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f496365000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f536861646f770000000000000000000000000000000000000000000000000000815250815250600c90600d6200046292919062000f8c565b506040518060a001604052806040518060400160405280600681526020017f536869656c64000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f417572610000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f57616c6c0000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600b81526020017f426c61646573204175726100000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f426c6f636b000000000000000000000000000000000000000000000000000000815250815250600d906005620005a592919062000f25565b506040518060e001604052806040518060400160405280600581526020017f4172726f7700000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f42616c6c0000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f5765616b6e65737300000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f426f6c740000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600981526020017f4578706c6f73696f6e000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f4f7262000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f426c617374000000000000000000000000000000000000000000000000000000815250815250600e9060076200075e92919062000ff3565b506040518060c001604052806040518060400160405280600481526020017f4865616c0000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f537472656e67746800000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f416775696c69747900000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f537065656400000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f437572650000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f506f69736f6e0000000000000000000000000000000000000000000000000000815250815250600f906006620008dc9291906200105a565b506040518060e001604052806040518060400160405280600381526020017f416e74000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f537069646572000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600981526020017f456c656d656e74616c000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f4461656d6f6e000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f506174726f6e757300000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f536b656c65746f6e00000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f4661697279000000000000000000000000000000000000000000000000000000815250815250601090600762000a9592919062000ff3565b50604051806101a001604052806040518060400160405280600b81526020017f54656c656b696e6573697300000000000000000000000000000000000000000081525081526020016040518060400160405280600d81526020017f54656c65706f72746174696f6e0000000000000000000000000000000000000081525081526020016040518060400160405280600c81526020017f496e7669736962696c697479000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f506172616c797a6500000000000000000000000000000000000000000000000081525081526020016040518060400160405280600a81526020017f506f6c796d6f727074680000000000000000000000000000000000000000000081525081526020016040518060400160405280600b81526020017f45617274687175616b652000000000000000000000000000000000000000000081525081526020016040518060400160405280600b81526020017f4e6967687473696768742000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f576973646f6d000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f496c6c7573696f6e00000000000000000000000000000000000000000000000081525081526020016040518060400160405280600b81526020017f447261696e204d6167696300000000000000000000000000000000000000000081525081526020016040518060400160405280600a81526020017f447261696e204c6966650000000000000000000000000000000000000000000081525081526020016040518060400160405280600d81526020017f4361737420736f6d65204554480000000000000000000000000000000000000081525081526020016040518060400160405280600f81526020017f43616c6c206f6620566974616c696b0000000000000000000000000000000000815250815250601190600d62000db192919062000f8c565b5061271060125534801562000dc557600080fd5b506040518060400160405280600981526020017f5370656c6c626f6f6b00000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f5350454c4c000000000000000000000000000000000000000000000000000000815250816000908051906020019062000e4a929190620010c1565b50806001908051906020019062000e63929190620010c1565b505050600062000e7862000f1d60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35062001244565b600033905090565b82805482825590600052602060002090810192821562000f79579160200282015b8281111562000f7857825182908051906020019062000f67929190620010c1565b509160200191906001019062000f46565b5b50905062000f88919062001152565b5090565b82805482825590600052602060002090810192821562000fe0579160200282015b8281111562000fdf57825182908051906020019062000fce929190620010c1565b509160200191906001019062000fad565b5b50905062000fef919062001152565b5090565b82805482825590600052602060002090810192821562001047579160200282015b828111156200104657825182908051906020019062001035929190620010c1565b509160200191906001019062001014565b5b50905062001056919062001152565b5090565b828054828255906000526020600020908101928215620010ae579160200282015b82811115620010ad5782518290805190602001906200109c929190620010c1565b50916020019190600101906200107b565b5b509050620010bd919062001152565b5090565b828054620010cf90620011df565b90600052602060002090601f016020900481019282620010f357600085556200113f565b82601f106200110e57805160ff19168380011785556200113f565b828001600101855582156200113f579182015b828111156200113e57825182559160200191906001019062001121565b5b5090506200114e91906200117a565b5090565b5b808211156200117657600081816200116c919062001199565b5060010162001153565b5090565b5b80821115620011955760008160009055506001016200117b565b5090565b508054620011a790620011df565b6000825580601f10620011bb5750620011dc565b601f016020900490600052602060002090810190620011db91906200117a565b5b50565b60006002820490506001821680620011f857607f821691505b602082108114156200120f576200120e62001215565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b615a6b80620012546000396000f3fe6080604052600436106101cd5760003560e01c8063715018a6116100f7578063b88d4fde11610095578063e0cef59411610064578063e0cef5941461068f578063e985e9c5146106cc578063e9cbb3c914610709578063f2fde38b14610746576101cd565b8063b88d4fde146105d0578063bb95b211146105f9578063c87b56dd14610615578063cff840f014610652576101cd565b80638ea86ab0116100d15780638ea86ab01461052857806395d89b4114610565578063a063f84714610590578063a22cb465146105a7576101cd565b8063715018a6146104a9578063893bb0bf146104c05780638da5cb5b146104fd576101cd565b80632f745c591161016f5780634f6ccce71161013e5780634f6ccce7146103c75780636352211e14610404578063676dd5631461044157806370a082311461046c576101cd565b80632f745c591461031f57806332cb6b0c1461035c5780633ccfd60b1461038757806342842e0e1461039e576101cd565b8063081812fc116101ab578063081812fc14610265578063095ea7b3146102a257806318160ddd146102cb57806323b872dd146102f6576101cd565b806301ffc9a7146101d2578063020b39cc1461020f57806306fdde031461023a575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f49190613d7e565b61076f565b6040516102069190614611565b60405180910390f35b34801561021b57600080fd5b506102246107e9565b604051610231919061494e565b60405180910390f35b34801561024657600080fd5b5061024f6107ee565b60405161025c919061462c565b60405180910390f35b34801561027157600080fd5b5061028c60048036038101906102879190613dd8565b610880565b60405161029991906145aa565b60405180910390f35b3480156102ae57600080fd5b506102c960048036038101906102c49190613d3e565b610905565b005b3480156102d757600080fd5b506102e0610a1d565b6040516102ed919061494e565b60405180910390f35b34801561030257600080fd5b5061031d60048036038101906103189190613c28565b610a2a565b005b34801561032b57600080fd5b5061034660048036038101906103419190613d3e565b610a8a565b604051610353919061494e565b60405180910390f35b34801561036857600080fd5b50610371610b2f565b60405161037e919061494e565b60405180910390f35b34801561039357600080fd5b5061039c610b35565b005b3480156103aa57600080fd5b506103c560048036038101906103c09190613c28565b610c00565b005b3480156103d357600080fd5b506103ee60048036038101906103e99190613dd8565b610c20565b6040516103fb919061494e565b60405180910390f35b34801561041057600080fd5b5061042b60048036038101906104269190613dd8565b610c91565b60405161043891906145aa565b60405180910390f35b34801561044d57600080fd5b50610456610d43565b604051610463919061494e565b60405180910390f35b34801561047857600080fd5b50610493600480360381019061048e9190613bbb565b610d4e565b6040516104a0919061494e565b60405180910390f35b3480156104b557600080fd5b506104be610e06565b005b3480156104cc57600080fd5b506104e760048036038101906104e29190613dd8565b610f43565b6040516104f4919061462c565b60405180910390f35b34801561050957600080fd5b5061051261105f565b60405161051f91906145aa565b60405180910390f35b34801561053457600080fd5b5061054f600480360381019061054a9190613dd8565b611089565b60405161055c919061462c565b60405180910390f35b34801561057157600080fd5b5061057a6111a5565b604051610587919061462c565b60405180910390f35b34801561059c57600080fd5b506105a5611237565b005b3480156105b357600080fd5b506105ce60048036038101906105c99190613cfe565b61139b565b005b3480156105dc57600080fd5b506105f760048036038101906105f29190613c7b565b61151c565b005b610613600480360381019061060e9190613dd8565b61157e565b005b34801561062157600080fd5b5061063c60048036038101906106379190613dd8565b6117ff565b604051610649919061462c565b60405180910390f35b34801561065e57600080fd5b5061067960048036038101906106749190613dd8565b61205b565b604051610686919061462c565b60405180910390f35b34801561069b57600080fd5b506106b660048036038101906106b19190613dd8565b612177565b6040516106c3919061462c565b60405180910390f35b3480156106d857600080fd5b506106f360048036038101906106ee9190613be8565b612293565b6040516107009190614611565b60405180910390f35b34801561071557600080fd5b50610730600480360381019061072b9190613dd8565b612327565b60405161073d919061462c565b60405180910390f35b34801561075257600080fd5b5061076d60048036038101906107689190613bbb565b612443565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107e257506107e1826125ef565b5b9050919050565b601481565b6060600080546107fd90614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461082990614bcd565b80156108765780601f1061084b57610100808354040283529160200191610876565b820191906000526020600020905b81548152906001019060200180831161085957829003601f168201915b5050505050905090565b600061088b826126d1565b6108ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c19061484e565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061091082610c91565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610981576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610978906148ce565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109a061273d565b73ffffffffffffffffffffffffffffffffffffffff1614806109cf57506109ce816109c961273d565b612293565b5b610a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a05906147ae565b60405180910390fd5b610a188383612745565b505050565b6000600880549050905090565b610a3b610a3561273d565b826127fe565b610a7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a719061490e565b60405180910390fd5b610a858383836128dc565b505050565b6000610a9583610d4e565b8210610ad6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd9061468e565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60125481565b610b3d61273d565b73ffffffffffffffffffffffffffffffffffffffff16610b5b61105f565b73ffffffffffffffffffffffffffffffffffffffff1614610bb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba89061486e565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610bfc573d6000803e3d6000fd5b5050565b610c1b8383836040518060200160405280600081525061151c565b505050565b6000610c2a610a1d565b8210610c6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c629061492e565b60405180910390fd5b60088281548110610c7f57610c7e614d66565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d31906147ee565b60405180910390fd5b80915050919050565b66b1a2bc2ec5000081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610dbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db6906147ce565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610e0e61273d565b73ffffffffffffffffffffffffffffffffffffffff16610e2c61105f565b73ffffffffffffffffffffffffffffffffffffffff1614610e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e799061486e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6060611058826040518060400160405280600581526020017f45585452410000000000000000000000000000000000000000000000000000008152506011805480602002602001604051908101604052809291908181526020016000905b8282101561104d578382906000526020600020018054610fc090614bcd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fec90614bcd565b80156110395780601f1061100e57610100808354040283529160200191611039565b820191906000526020600020905b81548152906001019060200180831161101c57829003601f168201915b505050505081526020019060010190610fa1565b505050506005612b38565b9050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606061119e826040518060400160405280600681526020017f53554d4d4f4e00000000000000000000000000000000000000000000000000008152506010805480602002602001604051908101604052809291908181526020016000905b8282101561119357838290600052602060002001805461110690614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461113290614bcd565b801561117f5780601f106111545761010080835404028352916020019161117f565b820191906000526020600020905b81548152906001019060200180831161116257829003601f168201915b5050505050815260200190600101906110e7565b505050506004612b38565b9050919050565b6060600180546111b490614bcd565b80601f01602080910402602001604051908101604052809291908181526020018280546111e090614bcd565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b5050505050905090565b6013600061124361273d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156112cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c2906148ee565b60405180910390fd5b6001601360006112d961273d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506127106001611337610a1d565b6113419190614a02565b10611381576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113789061474e565b60405180910390fd5b61139961138c61273d565b611394610a1d565b612e69565b565b6113a361273d565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611411576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114089061472e565b60405180910390fd5b806005600061141e61273d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166114cb61273d565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115109190614611565b60405180910390a35050565b61152d61152761273d565b836127fe565b61156c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115639061490e565b60405180910390fd5b61157884848484612e87565b50505050565b601481601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115cb9190614a02565b111561160c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116039061464e565b60405180910390fd5b6000811161164f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116469061466e565b60405180910390fd5b6012548161165b610a1d565b6116659190614a02565b11156116a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169d906148ae565b60405180910390fd5b60148111156116ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e19061478e565b60405180910390fd5b348166b1a2bc2ec500006116fe9190614a89565b1461173e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117359061480e565b60405180910390fd5b80601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546117899190614a02565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060005b818110156117fb576117e8336117e3610a1d565b612e69565b80806117f390614c30565b9150506117cf565b5050565b6060611809613a6b565b604051806102a00160405280610277815260200161563961027791398160006011811061183957611838614d66565b5b602002018190525061184a83612177565b8160016011811061185e5761185d614d66565b5b60200201819052506040518060600160405280602981526020016159e4602991398160026011811061189357611892614d66565b5b60200201819052506118a48361205b565b816003601181106118b8576118b7614d66565b5b60200201819052506040518060600160405280602981526020016159bb60299139816004601181106118ed576118ec614d66565b5b60200201819052506118fe83612327565b8160056011811061191257611911614d66565b5b6020020181905250604051806060016040528060298152602001615a0d602991398160066011811061194757611946614d66565b5b602002018190525061195883611089565b8160076011811061196c5761196b614d66565b5b60200201819052506040518060600160405280602981526020016158d860299139816008601181106119a1576119a0614d66565b5b60200201819052506119b283610f43565b816009601181106119c6576119c5614d66565b5b60200201819052506040518060400160405280600d81526020017f3c2f746578743e3c2f7376673e0000000000000000000000000000000000000081525081601060118110611a1857611a17614d66565b5b6020020181905250600081600060118110611a3657611a35614d66565b5b602002015182600160118110611a4f57611a4e614d66565b5b602002015183600260118110611a6857611a67614d66565b5b602002015184600360118110611a8157611a80614d66565b5b602002015185600460118110611a9a57611a99614d66565b5b602002015186600560118110611ab357611ab2614d66565b5b602002015187600660118110611acc57611acb614d66565b5b602002015188600760118110611ae557611ae4614d66565b5b602002015189600860118110611afe57611afd614d66565b5b6020020151604051602001611b1b99989796959493929190614420565b60405160208183030381529060405290508082600960118110611b4157611b40614d66565b5b602002015183600a60118110611b5a57611b59614d66565b5b602002015184600b60118110611b7357611b72614d66565b5b602002015185600c60118110611b8c57611b8b614d66565b5b602002015186600d60118110611ba557611ba4614d66565b5b602002015187600e60118110611bbe57611bbd614d66565b5b602002015188600f60118110611bd757611bd6614d66565b5b602002015189601060118110611bf057611bef614d66565b5b6020020151604051602001611c0d99989796959493929190614420565b6040516020818303038152906040529050611c26613a93565b6040518060600160405280602881526020016158b060289139816000600b8110611c5357611c52614d66565b5b602002018190525082600160118110611c6f57611c6e614d66565b5b6020020151816001600b8110611c8857611c87614d66565b5b602002018190525060405180606001604052806029815260200161590160299139816002600b8110611cbd57611cbc614d66565b5b602002018190525082600360118110611cd957611cd8614d66565b5b6020020151816003600b8110611cf257611cf1614d66565b5b602002018190525060405180606001604052806027815260200161561260279139816004600b8110611d2757611d26614d66565b5b602002018190525082600560118110611d4357611d42614d66565b5b6020020151816005600b8110611d5c57611d5b614d66565b5b602002018190525060405180606001604052806029815260200161596a60299139816006600b8110611d9157611d90614d66565b5b602002018190525082600760118110611dad57611dac614d66565b5b6020020151816007600b8110611dc657611dc5614d66565b5b602002018190525060405180606001604052806028815260200161599360289139816008600b8110611dfb57611dfa614d66565b5b602002018190525082600960118110611e1757611e16614d66565b5b6020020151816009600b8110611e3057611e2f614d66565b5b60200201819052506040518060400160405280600481526020017f22207d5d0000000000000000000000000000000000000000000000000000000081525081600a600b8110611e8257611e81614d66565b5b60200201819052506000816000600b8110611ea057611e9f614d66565b5b6020020151826001600b8110611eb957611eb8614d66565b5b6020020151836002600b8110611ed257611ed1614d66565b5b6020020151846003600b8110611eeb57611eea614d66565b5b6020020151856004600b8110611f0457611f03614d66565b5b6020020151866005600b8110611f1d57611f1c614d66565b5b6020020151876006600b8110611f3657611f35614d66565b5b6020020151886007600b8110611f4f57611f4e614d66565b5b6020020151604051602001611f6b9897969594939291906143ae565b604051602081830303815290604052905080826008600b8110611f9157611f90614d66565b5b6020020151836009600b8110611faa57611fa9614d66565b5b602002015184600a600b8110611fc357611fc2614d66565b5b6020020151604051602001611fdb9493929190614370565b6040516020818303038152906040529050600061202a611ffa88612ee3565b61200386613044565b846040516020016120169392919061454d565b604051602081830303815290604052613044565b90508060405160200161203d919061449f565b60405160208183030381529060405293508395505050505050919050565b6060612170826040518060400160405280600681526020017f41545441434b0000000000000000000000000000000000000000000000000000815250600e805480602002602001604051908101604052809291908181526020016000905b828210156121655783829060005260206000200180546120d890614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461210490614bcd565b80156121515780601f1061212657610100808354040283529160200191612151565b820191906000526020600020905b81548152906001019060200180831161213457829003601f168201915b5050505050815260200190600101906120b9565b505050506002612b38565b9050919050565b606061228c826040518060400160405280600981526020017f444546454e534956450000000000000000000000000000000000000000000000815250600d805480602002602001604051908101604052809291908181526020016000905b828210156122815783829060005260206000200180546121f490614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461222090614bcd565b801561226d5780601f106122425761010080835404028352916020019161226d565b820191906000526020600020905b81548152906001019060200180831161225057829003601f168201915b5050505050815260200190600101906121d5565b505050506001612b38565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606061243c826040518060400160405280600581526020017f4255464653000000000000000000000000000000000000000000000000000000815250600f805480602002602001604051908101604052809291908181526020016000905b828210156124315783829060005260206000200180546123a490614bcd565b80601f01602080910402602001604051908101604052809291908181526020018280546123d090614bcd565b801561241d5780601f106123f25761010080835404028352916020019161241d565b820191906000526020600020905b81548152906001019060200180831161240057829003601f168201915b505050505081526020019060010190612385565b505050506003612b38565b9050919050565b61244b61273d565b73ffffffffffffffffffffffffffffffffffffffff1661246961105f565b73ffffffffffffffffffffffffffffffffffffffff16146124bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b69061486e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561252f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612526906146ce565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806126ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806126ca57506126c9826131dc565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166127b883610c91565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612809826126d1565b612848576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283f9061476e565b60405180910390fd5b600061285383610c91565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806128c257508373ffffffffffffffffffffffffffffffffffffffff166128aa84610880565b73ffffffffffffffffffffffffffffffffffffffff16145b806128d357506128d28185612293565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166128fc82610c91565b73ffffffffffffffffffffffffffffffffffffffff1614612952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129499061488e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156129c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b99061470e565b60405180910390fd5b6129cd838383613246565b6129d8600082612745565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a289190614ae3565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a7f9190614a02565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60606000612b6e85612b4988612ee3565b604051602001612b5a92919061434c565b60405160208183030381529060405261335a565b9050600084855183612b809190614c79565b81518110612b9157612b90614d66565b5b602002602001015190506000601583612baa9190614c79565b9050612bb4613abb565b600c821415612c14576040518060400160405280600681526020017f4865726f6963000000000000000000000000000000000000000000000000000081525081600060028110612c0757612c06614d66565b5b6020020181905250612ce7565b600b808054905085612c269190614c79565b81548110612c3757612c36614d66565b5b906000526020600020018054612c4c90614bcd565b80601f0160208091040260200160405190810160405280929190818152602001828054612c7890614bcd565b8015612cc55780601f10612c9a57610100808354040283529160200191612cc5565b820191906000526020600020905b815481529060010190602001808311612ca857829003601f168201915b505050505081600060028110612cde57612cdd614d66565b5b60200201819052505b600c808054905085612cf99190614c79565b81548110612d0a57612d09614d66565b5b906000526020600020018054612d1f90614bcd565b80601f0160208091040260200160405190810160405280929190818152602001828054612d4b90614bcd565b8015612d985780601f10612d6d57610100808354040283529160200191612d98565b820191906000526020600020905b815481529060010190602001808311612d7b57829003601f168201915b505050505081600160028110612db157612db0614d66565b5b60200201819052506005861415612e035780600060028110612dd657612dd5614d66565b5b602002015183604051602001612ded9291906144c1565b6040516020818303038152906040529250612e5a565b80600060028110612e1757612e16614d66565b5b60200201518382600160028110612e3157612e30614d66565b5b6020020151604051602001612e48939291906144fb565b60405160208183030381529060405292505b82945050505050949350505050565b612e8382826040518060200160405280600081525061338d565b5050565b612e928484846128dc565b612e9e848484846133e8565b612edd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ed4906146ae565b60405180910390fd5b50505050565b60606000821415612f2b576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061303f565b600082905060005b60008214612f5d578080612f4690614c30565b915050600a82612f569190614a58565b9150612f33565b60008167ffffffffffffffff811115612f7957612f78614d95565b5b6040519080825280601f01601f191660200182016040528015612fab5781602001600182028036833780820191505090505b5090505b6000851461303857600182612fc49190614ae3565b9150600a85612fd39190614c79565b6030612fdf9190614a02565b60f81b818381518110612ff557612ff4614d66565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856130319190614a58565b9450612faf565b8093505050505b919050565b6060600082519050600081141561306d57604051806020016040528060008152509150506131d7565b6000600360028361307e9190614a02565b6130889190614a58565b60046130949190614a89565b905060006020826130a59190614a02565b67ffffffffffffffff8111156130be576130bd614d95565b5b6040519080825280601f01601f1916602001820160405280156130f05781602001600182028036833780820191505090505b509050600060405180606001604052806040815260200161592a604091399050600181016020830160005b868110156131945760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b9050808452600484019350505061311b565b5060038606600181146131ae57600281146131be576131c9565b613d3d60f01b60028303526131c9565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61325183838361357f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156132945761328f81613584565b6132d3565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146132d2576132d183826135cd565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613316576133118161373a565b613355565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461335457613353828261380b565b5b5b505050565b60008160405160200161336d9190614335565b6040516020818303038152906040528051906020012060001c9050919050565b613397838361388a565b6133a460008484846133e8565b6133e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133da906146ae565b60405180910390fd5b505050565b60006134098473ffffffffffffffffffffffffffffffffffffffff16613a58565b15613572578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261343261273d565b8786866040518563ffffffff1660e01b815260040161345494939291906145c5565b602060405180830381600087803b15801561346e57600080fd5b505af192505050801561349f57506040513d601f19601f8201168201806040525081019061349c9190613dab565b60015b613522573d80600081146134cf576040519150601f19603f3d011682016040523d82523d6000602084013e6134d4565b606091505b5060008151141561351a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613511906146ae565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613577565b600190505b949350505050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016135da84610d4e565b6135e49190614ae3565b90506000600760008481526020019081526020016000205490508181146136c9576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b6000600160088054905061374e9190614ae3565b905060006009600084815260200190815260200160002054905060006008838154811061377e5761377d614d66565b5b9060005260206000200154905080600883815481106137a05761379f614d66565b5b9060005260206000200181905550816009600083815260200190815260200160002081905550600960008581526020019081526020016000206000905560088054806137ef576137ee614d37565b5b6001900381819060005260206000200160009055905550505050565b600061381683610d4e565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156138fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138f19061482e565b60405180910390fd5b613903816126d1565b15613943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161393a906146ee565b60405180910390fd5b61394f60008383613246565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461399f9190614a02565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6040518061022001604052806011905b6060815260200190600190039081613a7b5790505090565b604051806101600160405280600b905b6060815260200190600190039081613aa35790505090565b60405180604001604052806002905b6060815260200190600190039081613aca5790505090565b6000613af5613af08461498e565b614969565b905082815260208101848484011115613b1157613b10614dc9565b5b613b1c848285614b8b565b509392505050565b600081359050613b33816155b5565b92915050565b600081359050613b48816155cc565b92915050565b600081359050613b5d816155e3565b92915050565b600081519050613b72816155e3565b92915050565b600082601f830112613b8d57613b8c614dc4565b5b8135613b9d848260208601613ae2565b91505092915050565b600081359050613bb5816155fa565b92915050565b600060208284031215613bd157613bd0614dd3565b5b6000613bdf84828501613b24565b91505092915050565b60008060408385031215613bff57613bfe614dd3565b5b6000613c0d85828601613b24565b9250506020613c1e85828601613b24565b9150509250929050565b600080600060608486031215613c4157613c40614dd3565b5b6000613c4f86828701613b24565b9350506020613c6086828701613b24565b9250506040613c7186828701613ba6565b9150509250925092565b60008060008060808587031215613c9557613c94614dd3565b5b6000613ca387828801613b24565b9450506020613cb487828801613b24565b9350506040613cc587828801613ba6565b925050606085013567ffffffffffffffff811115613ce657613ce5614dce565b5b613cf287828801613b78565b91505092959194509250565b60008060408385031215613d1557613d14614dd3565b5b6000613d2385828601613b24565b9250506020613d3485828601613b39565b9150509250929050565b60008060408385031215613d5557613d54614dd3565b5b6000613d6385828601613b24565b9250506020613d7485828601613ba6565b9150509250929050565b600060208284031215613d9457613d93614dd3565b5b6000613da284828501613b4e565b91505092915050565b600060208284031215613dc157613dc0614dd3565b5b6000613dcf84828501613b63565b91505092915050565b600060208284031215613dee57613ded614dd3565b5b6000613dfc84828501613ba6565b91505092915050565b613e0e81614b17565b82525050565b613e1d81614b29565b82525050565b6000613e2e826149bf565b613e3881856149d5565b9350613e48818560208601614b9a565b613e5181614dd8565b840191505092915050565b6000613e67826149ca565b613e7181856149e6565b9350613e81818560208601614b9a565b613e8a81614dd8565b840191505092915050565b6000613ea0826149ca565b613eaa81856149f7565b9350613eba818560208601614b9a565b80840191505092915050565b6000613ed36022836149e6565b9150613ede82614de9565b604082019050919050565b6000613ef66033836149e6565b9150613f0182614e38565b604082019050919050565b6000613f19602b836149e6565b9150613f2482614e87565b604082019050919050565b6000613f3c6032836149e6565b9150613f4782614ed6565b604082019050919050565b6000613f5f6026836149e6565b9150613f6a82614f25565b604082019050919050565b6000613f82601c836149e6565b9150613f8d82614f74565b602082019050919050565b6000613fa5600f836149f7565b9150613fb082614f9d565b600f82019050919050565b6000613fc86060836149f7565b9150613fd382614fc6565b606082019050919050565b6000613feb6024836149e6565b9150613ff68261503b565b604082019050919050565b600061400e6019836149e6565b91506140198261508a565b602082019050919050565b6000614031601c836149e6565b915061403c826150b3565b602082019050919050565b6000614054602c836149e6565b915061405f826150dc565b604082019050919050565b60006140776001836149f7565b91506140828261512b565b600182019050919050565b600061409a6023836149e6565b91506140a582615154565b604082019050919050565b60006140bd6038836149e6565b91506140c8826151a3565b604082019050919050565b60006140e0602a836149e6565b91506140eb826151f2565b604082019050919050565b60006141036029836149e6565b915061410e82615241565b604082019050919050565b6000614126601d836149e6565b915061413182615290565b602082019050919050565b60006141496004836149f7565b9150614154826152b9565b600482019050919050565b600061416c6020836149e6565b9150614177826152e2565b602082019050919050565b600061418f6001836149f7565b915061419a8261530b565b600182019050919050565b60006141b2602c836149e6565b91506141bd82615334565b604082019050919050565b60006141d56020836149e6565b91506141e082615383565b602082019050919050565b60006141f86029836149e6565b9150614203826153ac565b604082019050919050565b600061421b602a836149e6565b9150614226826153fb565b604082019050919050565b600061423e6021836149e6565b91506142498261544a565b604082019050919050565b60006142616012836149e6565b915061426c82615499565b602082019050919050565b6000614284601d836149f7565b915061428f826154c2565b601d82019050919050565b60006142a76000836149f7565b91506142b2826154eb565b600082019050919050565b60006142ca6031836149e6565b91506142d5826154ee565b604082019050919050565b60006142ed602c836149e6565b91506142f88261553d565b604082019050919050565b60006143106015836149f7565b915061431b8261558c565b601582019050919050565b61432f81614b81565b82525050565b60006143418284613e95565b915081905092915050565b60006143588285613e95565b91506143648284613e95565b91508190509392505050565b600061437c8287613e95565b91506143888286613e95565b91506143948285613e95565b91506143a08284613e95565b915081905095945050505050565b60006143ba828b613e95565b91506143c6828a613e95565b91506143d28289613e95565b91506143de8288613e95565b91506143ea8287613e95565b91506143f68286613e95565b91506144028285613e95565b915061440e8284613e95565b91508190509998505050505050505050565b600061442c828c613e95565b9150614438828b613e95565b9150614444828a613e95565b91506144508289613e95565b915061445c8288613e95565b91506144688287613e95565b91506144748286613e95565b91506144808285613e95565b915061448c8284613e95565b91508190509a9950505050505050505050565b60006144aa82614277565b91506144b68284613e95565b915081905092915050565b60006144cc8261429a565b91506144d88285613e95565b91506144e38261406a565b91506144ef8284613e95565b91508190509392505050565b60006145068261429a565b91506145128286613e95565b915061451d8261406a565b91506145298285613e95565b91506145348261413c565b91506145408284613e95565b9150819050949350505050565b600061455882614303565b91506145648286613e95565b915061456f82613fbb565b915061457b8285613e95565b915061458682613f98565b91506145928284613e95565b915061459d82614182565b9150819050949350505050565b60006020820190506145bf6000830184613e05565b92915050565b60006080820190506145da6000830187613e05565b6145e76020830186613e05565b6145f46040830185614326565b81810360608301526146068184613e23565b905095945050505050565b60006020820190506146266000830184613e14565b92915050565b600060208201905081810360008301526146468184613e5c565b905092915050565b6000602082019050818103600083015261466781613ec6565b9050919050565b6000602082019050818103600083015261468781613ee9565b9050919050565b600060208201905081810360008301526146a781613f0c565b9050919050565b600060208201905081810360008301526146c781613f2f565b9050919050565b600060208201905081810360008301526146e781613f52565b9050919050565b6000602082019050818103600083015261470781613f75565b9050919050565b6000602082019050818103600083015261472781613fde565b9050919050565b6000602082019050818103600083015261474781614001565b9050919050565b6000602082019050818103600083015261476781614024565b9050919050565b6000602082019050818103600083015261478781614047565b9050919050565b600060208201905081810360008301526147a78161408d565b9050919050565b600060208201905081810360008301526147c7816140b0565b9050919050565b600060208201905081810360008301526147e7816140d3565b9050919050565b60006020820190508181036000830152614807816140f6565b9050919050565b6000602082019050818103600083015261482781614119565b9050919050565b600060208201905081810360008301526148478161415f565b9050919050565b60006020820190508181036000830152614867816141a5565b9050919050565b60006020820190508181036000830152614887816141c8565b9050919050565b600060208201905081810360008301526148a7816141eb565b9050919050565b600060208201905081810360008301526148c78161420e565b9050919050565b600060208201905081810360008301526148e781614231565b9050919050565b6000602082019050818103600083015261490781614254565b9050919050565b60006020820190508181036000830152614927816142bd565b9050919050565b60006020820190508181036000830152614947816142e0565b9050919050565b60006020820190506149636000830184614326565b92915050565b6000614973614984565b905061497f8282614bff565b919050565b6000604051905090565b600067ffffffffffffffff8211156149a9576149a8614d95565b5b6149b282614dd8565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614a0d82614b81565b9150614a1883614b81565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614a4d57614a4c614caa565b5b828201905092915050565b6000614a6382614b81565b9150614a6e83614b81565b925082614a7e57614a7d614cd9565b5b828204905092915050565b6000614a9482614b81565b9150614a9f83614b81565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ad857614ad7614caa565b5b828202905092915050565b6000614aee82614b81565b9150614af983614b81565b925082821015614b0c57614b0b614caa565b5b828203905092915050565b6000614b2282614b61565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015614bb8578082015181840152602081019050614b9d565b83811115614bc7576000848401525b50505050565b60006002820490506001821680614be557607f821691505b60208210811415614bf957614bf8614d08565b5b50919050565b614c0882614dd8565b810181811067ffffffffffffffff82111715614c2757614c26614d95565b5b80604052505050565b6000614c3b82614b81565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614c6e57614c6d614caa565b5b600182019050919050565b6000614c8482614b81565b9150614c8f83614b81565b925082614c9f57614c9e614cd9565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f43616e206f6e6c79206d696e7420757020746f2032302070657220616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f4e756d626572206f6620746f6b656e732063616e206e6f74206265206c65737360008201527f207468616e206f7220657175616c20746f203000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f222c2261747472696275746573223a0000000000000000000000000000000000600082015250565b7f222c20226465736372697074696f6e223a20224361737420796f75722073706560008201527f6c6c7320616e792074696d6520796f752077616e7420746f2e222c2022696d6160208201527f6765223a2022646174613a696d6167652f7376672b786d6c3b6261736536342c604082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f45766572797468696e6720697320616c7265616479206d696e74656400000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f2000000000000000000000000000000000000000000000000000000000000000600082015250565b7f43616e206f6e6c79206d696e7420757020746f2032302070657220707572636860008201527f6173650000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f53656e742065746865722076616c756520697320696e636f7272656374000000600082015250565b7f206f662000000000000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f507572636861736520776f756c6420657863656564206d617820737570706c7960008201527f206f66205370656c6c7300000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f43616e206f6e6c79206d696e74206f6e63650000000000000000000000000000600082015250565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b50565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f7b226e616d65223a20225370656c6c626f6f6b20230000000000000000000000600082015250565b6155be81614b17565b81146155c957600080fd5b50565b6155d581614b29565b81146155e057600080fd5b50565b6155ec81614b35565b81146155f757600080fd5b50565b61560381614b81565b811461560e57600080fd5b5056fe22207d2c207b202274726169745f74797065223a202242756666222c202276616c7565223a20223c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e2e62617365207b2066696c6c3a20626c61636b3b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20313470783b207d2e6865616465727b2066696c6c3a20626c61636b3b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20343070783b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d22626c61636b22202f3e3c7061746820643d224d32362035352e354c35312e352031352e354c3330382031334c3332322e352032374c3331302035304c3331332e352038352e35483239392e354c3331332e352039342e354c3331372e3520323431483239392e354c3331332e35203234342e35563235382e354c3332322e3520323836563332322e354c3934203334324c38302e35203332364c3633203333314c3236203238324c3331203237322e35563236334c33352e35203235382e354c3331203235312e354c33352e3520323137483236563136302e354c33352e35203135354c3331203133314c3236203132364c32332038352e354c32362035352e355a222066696c6c3d227768697465222f3e3c7465787420783d2239362220793d2236302220636c6173733d2268656164657222203e5370656c6c626f6f6b3c2f746578743e3c7465787420783d2239362220793d223133302220636c6173733d2262617365223e5b7b202274726169745f74797065223a2022446566656e73697665222c202276616c7565223a20223c2f746578743e3c7465787420783d2239362220793d223231302220636c6173733d2262617365223e22207d2c207b202274726169745f74797065223a202241747461636b222c202276616c7565223a20224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f22207d2c207b202274726169745f74797065223a202253756d6d6f6e222c202276616c7565223a202222207d2c207b202274726169745f74797065223a20224578747261222c202276616c7565223a20223c2f746578743e3c7465787420783d2239362220793d223137302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2239362220793d223135302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2239362220793d223139302220636c6173733d2262617365223ea2646970667358221220020f9fcfdb6eddf6967070074220bc7387aadfdd9f0fe267158d74835c5f9c5c64736f6c63430008070033

Deployed Bytecode

0x6080604052600436106101cd5760003560e01c8063715018a6116100f7578063b88d4fde11610095578063e0cef59411610064578063e0cef5941461068f578063e985e9c5146106cc578063e9cbb3c914610709578063f2fde38b14610746576101cd565b8063b88d4fde146105d0578063bb95b211146105f9578063c87b56dd14610615578063cff840f014610652576101cd565b80638ea86ab0116100d15780638ea86ab01461052857806395d89b4114610565578063a063f84714610590578063a22cb465146105a7576101cd565b8063715018a6146104a9578063893bb0bf146104c05780638da5cb5b146104fd576101cd565b80632f745c591161016f5780634f6ccce71161013e5780634f6ccce7146103c75780636352211e14610404578063676dd5631461044157806370a082311461046c576101cd565b80632f745c591461031f57806332cb6b0c1461035c5780633ccfd60b1461038757806342842e0e1461039e576101cd565b8063081812fc116101ab578063081812fc14610265578063095ea7b3146102a257806318160ddd146102cb57806323b872dd146102f6576101cd565b806301ffc9a7146101d2578063020b39cc1461020f57806306fdde031461023a575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f49190613d7e565b61076f565b6040516102069190614611565b60405180910390f35b34801561021b57600080fd5b506102246107e9565b604051610231919061494e565b60405180910390f35b34801561024657600080fd5b5061024f6107ee565b60405161025c919061462c565b60405180910390f35b34801561027157600080fd5b5061028c60048036038101906102879190613dd8565b610880565b60405161029991906145aa565b60405180910390f35b3480156102ae57600080fd5b506102c960048036038101906102c49190613d3e565b610905565b005b3480156102d757600080fd5b506102e0610a1d565b6040516102ed919061494e565b60405180910390f35b34801561030257600080fd5b5061031d60048036038101906103189190613c28565b610a2a565b005b34801561032b57600080fd5b5061034660048036038101906103419190613d3e565b610a8a565b604051610353919061494e565b60405180910390f35b34801561036857600080fd5b50610371610b2f565b60405161037e919061494e565b60405180910390f35b34801561039357600080fd5b5061039c610b35565b005b3480156103aa57600080fd5b506103c560048036038101906103c09190613c28565b610c00565b005b3480156103d357600080fd5b506103ee60048036038101906103e99190613dd8565b610c20565b6040516103fb919061494e565b60405180910390f35b34801561041057600080fd5b5061042b60048036038101906104269190613dd8565b610c91565b60405161043891906145aa565b60405180910390f35b34801561044d57600080fd5b50610456610d43565b604051610463919061494e565b60405180910390f35b34801561047857600080fd5b50610493600480360381019061048e9190613bbb565b610d4e565b6040516104a0919061494e565b60405180910390f35b3480156104b557600080fd5b506104be610e06565b005b3480156104cc57600080fd5b506104e760048036038101906104e29190613dd8565b610f43565b6040516104f4919061462c565b60405180910390f35b34801561050957600080fd5b5061051261105f565b60405161051f91906145aa565b60405180910390f35b34801561053457600080fd5b5061054f600480360381019061054a9190613dd8565b611089565b60405161055c919061462c565b60405180910390f35b34801561057157600080fd5b5061057a6111a5565b604051610587919061462c565b60405180910390f35b34801561059c57600080fd5b506105a5611237565b005b3480156105b357600080fd5b506105ce60048036038101906105c99190613cfe565b61139b565b005b3480156105dc57600080fd5b506105f760048036038101906105f29190613c7b565b61151c565b005b610613600480360381019061060e9190613dd8565b61157e565b005b34801561062157600080fd5b5061063c60048036038101906106379190613dd8565b6117ff565b604051610649919061462c565b60405180910390f35b34801561065e57600080fd5b5061067960048036038101906106749190613dd8565b61205b565b604051610686919061462c565b60405180910390f35b34801561069b57600080fd5b506106b660048036038101906106b19190613dd8565b612177565b6040516106c3919061462c565b60405180910390f35b3480156106d857600080fd5b506106f360048036038101906106ee9190613be8565b612293565b6040516107009190614611565b60405180910390f35b34801561071557600080fd5b50610730600480360381019061072b9190613dd8565b612327565b60405161073d919061462c565b60405180910390f35b34801561075257600080fd5b5061076d60048036038101906107689190613bbb565b612443565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107e257506107e1826125ef565b5b9050919050565b601481565b6060600080546107fd90614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461082990614bcd565b80156108765780601f1061084b57610100808354040283529160200191610876565b820191906000526020600020905b81548152906001019060200180831161085957829003601f168201915b5050505050905090565b600061088b826126d1565b6108ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c19061484e565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061091082610c91565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610981576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610978906148ce565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109a061273d565b73ffffffffffffffffffffffffffffffffffffffff1614806109cf57506109ce816109c961273d565b612293565b5b610a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a05906147ae565b60405180910390fd5b610a188383612745565b505050565b6000600880549050905090565b610a3b610a3561273d565b826127fe565b610a7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a719061490e565b60405180910390fd5b610a858383836128dc565b505050565b6000610a9583610d4e565b8210610ad6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd9061468e565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60125481565b610b3d61273d565b73ffffffffffffffffffffffffffffffffffffffff16610b5b61105f565b73ffffffffffffffffffffffffffffffffffffffff1614610bb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba89061486e565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610bfc573d6000803e3d6000fd5b5050565b610c1b8383836040518060200160405280600081525061151c565b505050565b6000610c2a610a1d565b8210610c6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c629061492e565b60405180910390fd5b60088281548110610c7f57610c7e614d66565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d31906147ee565b60405180910390fd5b80915050919050565b66b1a2bc2ec5000081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610dbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db6906147ce565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610e0e61273d565b73ffffffffffffffffffffffffffffffffffffffff16610e2c61105f565b73ffffffffffffffffffffffffffffffffffffffff1614610e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e799061486e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6060611058826040518060400160405280600581526020017f45585452410000000000000000000000000000000000000000000000000000008152506011805480602002602001604051908101604052809291908181526020016000905b8282101561104d578382906000526020600020018054610fc090614bcd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fec90614bcd565b80156110395780601f1061100e57610100808354040283529160200191611039565b820191906000526020600020905b81548152906001019060200180831161101c57829003601f168201915b505050505081526020019060010190610fa1565b505050506005612b38565b9050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606061119e826040518060400160405280600681526020017f53554d4d4f4e00000000000000000000000000000000000000000000000000008152506010805480602002602001604051908101604052809291908181526020016000905b8282101561119357838290600052602060002001805461110690614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461113290614bcd565b801561117f5780601f106111545761010080835404028352916020019161117f565b820191906000526020600020905b81548152906001019060200180831161116257829003601f168201915b5050505050815260200190600101906110e7565b505050506004612b38565b9050919050565b6060600180546111b490614bcd565b80601f01602080910402602001604051908101604052809291908181526020018280546111e090614bcd565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b5050505050905090565b6013600061124361273d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156112cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c2906148ee565b60405180910390fd5b6001601360006112d961273d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506127106001611337610a1d565b6113419190614a02565b10611381576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113789061474e565b60405180910390fd5b61139961138c61273d565b611394610a1d565b612e69565b565b6113a361273d565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611411576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114089061472e565b60405180910390fd5b806005600061141e61273d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166114cb61273d565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115109190614611565b60405180910390a35050565b61152d61152761273d565b836127fe565b61156c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115639061490e565b60405180910390fd5b61157884848484612e87565b50505050565b601481601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115cb9190614a02565b111561160c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116039061464e565b60405180910390fd5b6000811161164f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116469061466e565b60405180910390fd5b6012548161165b610a1d565b6116659190614a02565b11156116a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169d906148ae565b60405180910390fd5b60148111156116ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e19061478e565b60405180910390fd5b348166b1a2bc2ec500006116fe9190614a89565b1461173e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117359061480e565b60405180910390fd5b80601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546117899190614a02565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060005b818110156117fb576117e8336117e3610a1d565b612e69565b80806117f390614c30565b9150506117cf565b5050565b6060611809613a6b565b604051806102a00160405280610277815260200161563961027791398160006011811061183957611838614d66565b5b602002018190525061184a83612177565b8160016011811061185e5761185d614d66565b5b60200201819052506040518060600160405280602981526020016159e4602991398160026011811061189357611892614d66565b5b60200201819052506118a48361205b565b816003601181106118b8576118b7614d66565b5b60200201819052506040518060600160405280602981526020016159bb60299139816004601181106118ed576118ec614d66565b5b60200201819052506118fe83612327565b8160056011811061191257611911614d66565b5b6020020181905250604051806060016040528060298152602001615a0d602991398160066011811061194757611946614d66565b5b602002018190525061195883611089565b8160076011811061196c5761196b614d66565b5b60200201819052506040518060600160405280602981526020016158d860299139816008601181106119a1576119a0614d66565b5b60200201819052506119b283610f43565b816009601181106119c6576119c5614d66565b5b60200201819052506040518060400160405280600d81526020017f3c2f746578743e3c2f7376673e0000000000000000000000000000000000000081525081601060118110611a1857611a17614d66565b5b6020020181905250600081600060118110611a3657611a35614d66565b5b602002015182600160118110611a4f57611a4e614d66565b5b602002015183600260118110611a6857611a67614d66565b5b602002015184600360118110611a8157611a80614d66565b5b602002015185600460118110611a9a57611a99614d66565b5b602002015186600560118110611ab357611ab2614d66565b5b602002015187600660118110611acc57611acb614d66565b5b602002015188600760118110611ae557611ae4614d66565b5b602002015189600860118110611afe57611afd614d66565b5b6020020151604051602001611b1b99989796959493929190614420565b60405160208183030381529060405290508082600960118110611b4157611b40614d66565b5b602002015183600a60118110611b5a57611b59614d66565b5b602002015184600b60118110611b7357611b72614d66565b5b602002015185600c60118110611b8c57611b8b614d66565b5b602002015186600d60118110611ba557611ba4614d66565b5b602002015187600e60118110611bbe57611bbd614d66565b5b602002015188600f60118110611bd757611bd6614d66565b5b602002015189601060118110611bf057611bef614d66565b5b6020020151604051602001611c0d99989796959493929190614420565b6040516020818303038152906040529050611c26613a93565b6040518060600160405280602881526020016158b060289139816000600b8110611c5357611c52614d66565b5b602002018190525082600160118110611c6f57611c6e614d66565b5b6020020151816001600b8110611c8857611c87614d66565b5b602002018190525060405180606001604052806029815260200161590160299139816002600b8110611cbd57611cbc614d66565b5b602002018190525082600360118110611cd957611cd8614d66565b5b6020020151816003600b8110611cf257611cf1614d66565b5b602002018190525060405180606001604052806027815260200161561260279139816004600b8110611d2757611d26614d66565b5b602002018190525082600560118110611d4357611d42614d66565b5b6020020151816005600b8110611d5c57611d5b614d66565b5b602002018190525060405180606001604052806029815260200161596a60299139816006600b8110611d9157611d90614d66565b5b602002018190525082600760118110611dad57611dac614d66565b5b6020020151816007600b8110611dc657611dc5614d66565b5b602002018190525060405180606001604052806028815260200161599360289139816008600b8110611dfb57611dfa614d66565b5b602002018190525082600960118110611e1757611e16614d66565b5b6020020151816009600b8110611e3057611e2f614d66565b5b60200201819052506040518060400160405280600481526020017f22207d5d0000000000000000000000000000000000000000000000000000000081525081600a600b8110611e8257611e81614d66565b5b60200201819052506000816000600b8110611ea057611e9f614d66565b5b6020020151826001600b8110611eb957611eb8614d66565b5b6020020151836002600b8110611ed257611ed1614d66565b5b6020020151846003600b8110611eeb57611eea614d66565b5b6020020151856004600b8110611f0457611f03614d66565b5b6020020151866005600b8110611f1d57611f1c614d66565b5b6020020151876006600b8110611f3657611f35614d66565b5b6020020151886007600b8110611f4f57611f4e614d66565b5b6020020151604051602001611f6b9897969594939291906143ae565b604051602081830303815290604052905080826008600b8110611f9157611f90614d66565b5b6020020151836009600b8110611faa57611fa9614d66565b5b602002015184600a600b8110611fc357611fc2614d66565b5b6020020151604051602001611fdb9493929190614370565b6040516020818303038152906040529050600061202a611ffa88612ee3565b61200386613044565b846040516020016120169392919061454d565b604051602081830303815290604052613044565b90508060405160200161203d919061449f565b60405160208183030381529060405293508395505050505050919050565b6060612170826040518060400160405280600681526020017f41545441434b0000000000000000000000000000000000000000000000000000815250600e805480602002602001604051908101604052809291908181526020016000905b828210156121655783829060005260206000200180546120d890614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461210490614bcd565b80156121515780601f1061212657610100808354040283529160200191612151565b820191906000526020600020905b81548152906001019060200180831161213457829003601f168201915b5050505050815260200190600101906120b9565b505050506002612b38565b9050919050565b606061228c826040518060400160405280600981526020017f444546454e534956450000000000000000000000000000000000000000000000815250600d805480602002602001604051908101604052809291908181526020016000905b828210156122815783829060005260206000200180546121f490614bcd565b80601f016020809104026020016040519081016040528092919081815260200182805461222090614bcd565b801561226d5780601f106122425761010080835404028352916020019161226d565b820191906000526020600020905b81548152906001019060200180831161225057829003601f168201915b5050505050815260200190600101906121d5565b505050506001612b38565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606061243c826040518060400160405280600581526020017f4255464653000000000000000000000000000000000000000000000000000000815250600f805480602002602001604051908101604052809291908181526020016000905b828210156124315783829060005260206000200180546123a490614bcd565b80601f01602080910402602001604051908101604052809291908181526020018280546123d090614bcd565b801561241d5780601f106123f25761010080835404028352916020019161241d565b820191906000526020600020905b81548152906001019060200180831161240057829003601f168201915b505050505081526020019060010190612385565b505050506003612b38565b9050919050565b61244b61273d565b73ffffffffffffffffffffffffffffffffffffffff1661246961105f565b73ffffffffffffffffffffffffffffffffffffffff16146124bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b69061486e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561252f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612526906146ce565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806126ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806126ca57506126c9826131dc565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166127b883610c91565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612809826126d1565b612848576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283f9061476e565b60405180910390fd5b600061285383610c91565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806128c257508373ffffffffffffffffffffffffffffffffffffffff166128aa84610880565b73ffffffffffffffffffffffffffffffffffffffff16145b806128d357506128d28185612293565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166128fc82610c91565b73ffffffffffffffffffffffffffffffffffffffff1614612952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129499061488e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156129c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b99061470e565b60405180910390fd5b6129cd838383613246565b6129d8600082612745565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a289190614ae3565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a7f9190614a02565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60606000612b6e85612b4988612ee3565b604051602001612b5a92919061434c565b60405160208183030381529060405261335a565b9050600084855183612b809190614c79565b81518110612b9157612b90614d66565b5b602002602001015190506000601583612baa9190614c79565b9050612bb4613abb565b600c821415612c14576040518060400160405280600681526020017f4865726f6963000000000000000000000000000000000000000000000000000081525081600060028110612c0757612c06614d66565b5b6020020181905250612ce7565b600b808054905085612c269190614c79565b81548110612c3757612c36614d66565b5b906000526020600020018054612c4c90614bcd565b80601f0160208091040260200160405190810160405280929190818152602001828054612c7890614bcd565b8015612cc55780601f10612c9a57610100808354040283529160200191612cc5565b820191906000526020600020905b815481529060010190602001808311612ca857829003601f168201915b505050505081600060028110612cde57612cdd614d66565b5b60200201819052505b600c808054905085612cf99190614c79565b81548110612d0a57612d09614d66565b5b906000526020600020018054612d1f90614bcd565b80601f0160208091040260200160405190810160405280929190818152602001828054612d4b90614bcd565b8015612d985780601f10612d6d57610100808354040283529160200191612d98565b820191906000526020600020905b815481529060010190602001808311612d7b57829003601f168201915b505050505081600160028110612db157612db0614d66565b5b60200201819052506005861415612e035780600060028110612dd657612dd5614d66565b5b602002015183604051602001612ded9291906144c1565b6040516020818303038152906040529250612e5a565b80600060028110612e1757612e16614d66565b5b60200201518382600160028110612e3157612e30614d66565b5b6020020151604051602001612e48939291906144fb565b60405160208183030381529060405292505b82945050505050949350505050565b612e8382826040518060200160405280600081525061338d565b5050565b612e928484846128dc565b612e9e848484846133e8565b612edd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ed4906146ae565b60405180910390fd5b50505050565b60606000821415612f2b576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061303f565b600082905060005b60008214612f5d578080612f4690614c30565b915050600a82612f569190614a58565b9150612f33565b60008167ffffffffffffffff811115612f7957612f78614d95565b5b6040519080825280601f01601f191660200182016040528015612fab5781602001600182028036833780820191505090505b5090505b6000851461303857600182612fc49190614ae3565b9150600a85612fd39190614c79565b6030612fdf9190614a02565b60f81b818381518110612ff557612ff4614d66565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856130319190614a58565b9450612faf565b8093505050505b919050565b6060600082519050600081141561306d57604051806020016040528060008152509150506131d7565b6000600360028361307e9190614a02565b6130889190614a58565b60046130949190614a89565b905060006020826130a59190614a02565b67ffffffffffffffff8111156130be576130bd614d95565b5b6040519080825280601f01601f1916602001820160405280156130f05781602001600182028036833780820191505090505b509050600060405180606001604052806040815260200161592a604091399050600181016020830160005b868110156131945760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b9050808452600484019350505061311b565b5060038606600181146131ae57600281146131be576131c9565b613d3d60f01b60028303526131c9565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61325183838361357f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156132945761328f81613584565b6132d3565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146132d2576132d183826135cd565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613316576133118161373a565b613355565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461335457613353828261380b565b5b5b505050565b60008160405160200161336d9190614335565b6040516020818303038152906040528051906020012060001c9050919050565b613397838361388a565b6133a460008484846133e8565b6133e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133da906146ae565b60405180910390fd5b505050565b60006134098473ffffffffffffffffffffffffffffffffffffffff16613a58565b15613572578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261343261273d565b8786866040518563ffffffff1660e01b815260040161345494939291906145c5565b602060405180830381600087803b15801561346e57600080fd5b505af192505050801561349f57506040513d601f19601f8201168201806040525081019061349c9190613dab565b60015b613522573d80600081146134cf576040519150601f19603f3d011682016040523d82523d6000602084013e6134d4565b606091505b5060008151141561351a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613511906146ae565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613577565b600190505b949350505050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016135da84610d4e565b6135e49190614ae3565b90506000600760008481526020019081526020016000205490508181146136c9576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b6000600160088054905061374e9190614ae3565b905060006009600084815260200190815260200160002054905060006008838154811061377e5761377d614d66565b5b9060005260206000200154905080600883815481106137a05761379f614d66565b5b9060005260206000200181905550816009600083815260200190815260200160002081905550600960008581526020019081526020016000206000905560088054806137ef576137ee614d37565b5b6001900381819060005260206000200160009055905550505050565b600061381683610d4e565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156138fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138f19061482e565b60405180910390fd5b613903816126d1565b15613943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161393a906146ee565b60405180910390fd5b61394f60008383613246565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461399f9190614a02565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6040518061022001604052806011905b6060815260200190600190039081613a7b5790505090565b604051806101600160405280600b905b6060815260200190600190039081613aa35790505090565b60405180604001604052806002905b6060815260200190600190039081613aca5790505090565b6000613af5613af08461498e565b614969565b905082815260208101848484011115613b1157613b10614dc9565b5b613b1c848285614b8b565b509392505050565b600081359050613b33816155b5565b92915050565b600081359050613b48816155cc565b92915050565b600081359050613b5d816155e3565b92915050565b600081519050613b72816155e3565b92915050565b600082601f830112613b8d57613b8c614dc4565b5b8135613b9d848260208601613ae2565b91505092915050565b600081359050613bb5816155fa565b92915050565b600060208284031215613bd157613bd0614dd3565b5b6000613bdf84828501613b24565b91505092915050565b60008060408385031215613bff57613bfe614dd3565b5b6000613c0d85828601613b24565b9250506020613c1e85828601613b24565b9150509250929050565b600080600060608486031215613c4157613c40614dd3565b5b6000613c4f86828701613b24565b9350506020613c6086828701613b24565b9250506040613c7186828701613ba6565b9150509250925092565b60008060008060808587031215613c9557613c94614dd3565b5b6000613ca387828801613b24565b9450506020613cb487828801613b24565b9350506040613cc587828801613ba6565b925050606085013567ffffffffffffffff811115613ce657613ce5614dce565b5b613cf287828801613b78565b91505092959194509250565b60008060408385031215613d1557613d14614dd3565b5b6000613d2385828601613b24565b9250506020613d3485828601613b39565b9150509250929050565b60008060408385031215613d5557613d54614dd3565b5b6000613d6385828601613b24565b9250506020613d7485828601613ba6565b9150509250929050565b600060208284031215613d9457613d93614dd3565b5b6000613da284828501613b4e565b91505092915050565b600060208284031215613dc157613dc0614dd3565b5b6000613dcf84828501613b63565b91505092915050565b600060208284031215613dee57613ded614dd3565b5b6000613dfc84828501613ba6565b91505092915050565b613e0e81614b17565b82525050565b613e1d81614b29565b82525050565b6000613e2e826149bf565b613e3881856149d5565b9350613e48818560208601614b9a565b613e5181614dd8565b840191505092915050565b6000613e67826149ca565b613e7181856149e6565b9350613e81818560208601614b9a565b613e8a81614dd8565b840191505092915050565b6000613ea0826149ca565b613eaa81856149f7565b9350613eba818560208601614b9a565b80840191505092915050565b6000613ed36022836149e6565b9150613ede82614de9565b604082019050919050565b6000613ef66033836149e6565b9150613f0182614e38565b604082019050919050565b6000613f19602b836149e6565b9150613f2482614e87565b604082019050919050565b6000613f3c6032836149e6565b9150613f4782614ed6565b604082019050919050565b6000613f5f6026836149e6565b9150613f6a82614f25565b604082019050919050565b6000613f82601c836149e6565b9150613f8d82614f74565b602082019050919050565b6000613fa5600f836149f7565b9150613fb082614f9d565b600f82019050919050565b6000613fc86060836149f7565b9150613fd382614fc6565b606082019050919050565b6000613feb6024836149e6565b9150613ff68261503b565b604082019050919050565b600061400e6019836149e6565b91506140198261508a565b602082019050919050565b6000614031601c836149e6565b915061403c826150b3565b602082019050919050565b6000614054602c836149e6565b915061405f826150dc565b604082019050919050565b60006140776001836149f7565b91506140828261512b565b600182019050919050565b600061409a6023836149e6565b91506140a582615154565b604082019050919050565b60006140bd6038836149e6565b91506140c8826151a3565b604082019050919050565b60006140e0602a836149e6565b91506140eb826151f2565b604082019050919050565b60006141036029836149e6565b915061410e82615241565b604082019050919050565b6000614126601d836149e6565b915061413182615290565b602082019050919050565b60006141496004836149f7565b9150614154826152b9565b600482019050919050565b600061416c6020836149e6565b9150614177826152e2565b602082019050919050565b600061418f6001836149f7565b915061419a8261530b565b600182019050919050565b60006141b2602c836149e6565b91506141bd82615334565b604082019050919050565b60006141d56020836149e6565b91506141e082615383565b602082019050919050565b60006141f86029836149e6565b9150614203826153ac565b604082019050919050565b600061421b602a836149e6565b9150614226826153fb565b604082019050919050565b600061423e6021836149e6565b91506142498261544a565b604082019050919050565b60006142616012836149e6565b915061426c82615499565b602082019050919050565b6000614284601d836149f7565b915061428f826154c2565b601d82019050919050565b60006142a76000836149f7565b91506142b2826154eb565b600082019050919050565b60006142ca6031836149e6565b91506142d5826154ee565b604082019050919050565b60006142ed602c836149e6565b91506142f88261553d565b604082019050919050565b60006143106015836149f7565b915061431b8261558c565b601582019050919050565b61432f81614b81565b82525050565b60006143418284613e95565b915081905092915050565b60006143588285613e95565b91506143648284613e95565b91508190509392505050565b600061437c8287613e95565b91506143888286613e95565b91506143948285613e95565b91506143a08284613e95565b915081905095945050505050565b60006143ba828b613e95565b91506143c6828a613e95565b91506143d28289613e95565b91506143de8288613e95565b91506143ea8287613e95565b91506143f68286613e95565b91506144028285613e95565b915061440e8284613e95565b91508190509998505050505050505050565b600061442c828c613e95565b9150614438828b613e95565b9150614444828a613e95565b91506144508289613e95565b915061445c8288613e95565b91506144688287613e95565b91506144748286613e95565b91506144808285613e95565b915061448c8284613e95565b91508190509a9950505050505050505050565b60006144aa82614277565b91506144b68284613e95565b915081905092915050565b60006144cc8261429a565b91506144d88285613e95565b91506144e38261406a565b91506144ef8284613e95565b91508190509392505050565b60006145068261429a565b91506145128286613e95565b915061451d8261406a565b91506145298285613e95565b91506145348261413c565b91506145408284613e95565b9150819050949350505050565b600061455882614303565b91506145648286613e95565b915061456f82613fbb565b915061457b8285613e95565b915061458682613f98565b91506145928284613e95565b915061459d82614182565b9150819050949350505050565b60006020820190506145bf6000830184613e05565b92915050565b60006080820190506145da6000830187613e05565b6145e76020830186613e05565b6145f46040830185614326565b81810360608301526146068184613e23565b905095945050505050565b60006020820190506146266000830184613e14565b92915050565b600060208201905081810360008301526146468184613e5c565b905092915050565b6000602082019050818103600083015261466781613ec6565b9050919050565b6000602082019050818103600083015261468781613ee9565b9050919050565b600060208201905081810360008301526146a781613f0c565b9050919050565b600060208201905081810360008301526146c781613f2f565b9050919050565b600060208201905081810360008301526146e781613f52565b9050919050565b6000602082019050818103600083015261470781613f75565b9050919050565b6000602082019050818103600083015261472781613fde565b9050919050565b6000602082019050818103600083015261474781614001565b9050919050565b6000602082019050818103600083015261476781614024565b9050919050565b6000602082019050818103600083015261478781614047565b9050919050565b600060208201905081810360008301526147a78161408d565b9050919050565b600060208201905081810360008301526147c7816140b0565b9050919050565b600060208201905081810360008301526147e7816140d3565b9050919050565b60006020820190508181036000830152614807816140f6565b9050919050565b6000602082019050818103600083015261482781614119565b9050919050565b600060208201905081810360008301526148478161415f565b9050919050565b60006020820190508181036000830152614867816141a5565b9050919050565b60006020820190508181036000830152614887816141c8565b9050919050565b600060208201905081810360008301526148a7816141eb565b9050919050565b600060208201905081810360008301526148c78161420e565b9050919050565b600060208201905081810360008301526148e781614231565b9050919050565b6000602082019050818103600083015261490781614254565b9050919050565b60006020820190508181036000830152614927816142bd565b9050919050565b60006020820190508181036000830152614947816142e0565b9050919050565b60006020820190506149636000830184614326565b92915050565b6000614973614984565b905061497f8282614bff565b919050565b6000604051905090565b600067ffffffffffffffff8211156149a9576149a8614d95565b5b6149b282614dd8565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614a0d82614b81565b9150614a1883614b81565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614a4d57614a4c614caa565b5b828201905092915050565b6000614a6382614b81565b9150614a6e83614b81565b925082614a7e57614a7d614cd9565b5b828204905092915050565b6000614a9482614b81565b9150614a9f83614b81565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ad857614ad7614caa565b5b828202905092915050565b6000614aee82614b81565b9150614af983614b81565b925082821015614b0c57614b0b614caa565b5b828203905092915050565b6000614b2282614b61565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015614bb8578082015181840152602081019050614b9d565b83811115614bc7576000848401525b50505050565b60006002820490506001821680614be557607f821691505b60208210811415614bf957614bf8614d08565b5b50919050565b614c0882614dd8565b810181811067ffffffffffffffff82111715614c2757614c26614d95565b5b80604052505050565b6000614c3b82614b81565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614c6e57614c6d614caa565b5b600182019050919050565b6000614c8482614b81565b9150614c8f83614b81565b925082614c9f57614c9e614cd9565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f43616e206f6e6c79206d696e7420757020746f2032302070657220616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f4e756d626572206f6620746f6b656e732063616e206e6f74206265206c65737360008201527f207468616e206f7220657175616c20746f203000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f222c2261747472696275746573223a0000000000000000000000000000000000600082015250565b7f222c20226465736372697074696f6e223a20224361737420796f75722073706560008201527f6c6c7320616e792074696d6520796f752077616e7420746f2e222c2022696d6160208201527f6765223a2022646174613a696d6167652f7376672b786d6c3b6261736536342c604082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f45766572797468696e6720697320616c7265616479206d696e74656400000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f2000000000000000000000000000000000000000000000000000000000000000600082015250565b7f43616e206f6e6c79206d696e7420757020746f2032302070657220707572636860008201527f6173650000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f53656e742065746865722076616c756520697320696e636f7272656374000000600082015250565b7f206f662000000000000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f507572636861736520776f756c6420657863656564206d617820737570706c7960008201527f206f66205370656c6c7300000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f43616e206f6e6c79206d696e74206f6e63650000000000000000000000000000600082015250565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b50565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f7b226e616d65223a20225370656c6c626f6f6b20230000000000000000000000600082015250565b6155be81614b17565b81146155c957600080fd5b50565b6155d581614b29565b81146155e057600080fd5b50565b6155ec81614b35565b81146155f757600080fd5b50565b61560381614b81565b811461560e57600080fd5b5056fe22207d2c207b202274726169745f74797065223a202242756666222c202276616c7565223a20223c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e2e62617365207b2066696c6c3a20626c61636b3b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20313470783b207d2e6865616465727b2066696c6c3a20626c61636b3b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20343070783b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d22626c61636b22202f3e3c7061746820643d224d32362035352e354c35312e352031352e354c3330382031334c3332322e352032374c3331302035304c3331332e352038352e35483239392e354c3331332e352039342e354c3331372e3520323431483239392e354c3331332e35203234342e35563235382e354c3332322e3520323836563332322e354c3934203334324c38302e35203332364c3633203333314c3236203238324c3331203237322e35563236334c33352e35203235382e354c3331203235312e354c33352e3520323137483236563136302e354c33352e35203135354c3331203133314c3236203132364c32332038352e354c32362035352e355a222066696c6c3d227768697465222f3e3c7465787420783d2239362220793d2236302220636c6173733d2268656164657222203e5370656c6c626f6f6b3c2f746578743e3c7465787420783d2239362220793d223133302220636c6173733d2262617365223e5b7b202274726169745f74797065223a2022446566656e73697665222c202276616c7565223a20223c2f746578743e3c7465787420783d2239362220793d223231302220636c6173733d2262617365223e22207d2c207b202274726169745f74797065223a202241747461636b222c202276616c7565223a20224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f22207d2c207b202274726169745f74797065223a202253756d6d6f6e222c202276616c7565223a202222207d2c207b202274726169745f74797065223a20224578747261222c202276616c7565223a20223c2f746578743e3c7465787420783d2239362220793d223137302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2239362220793d223135302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2239362220793d223139302220636c6173733d2262617365223ea2646970667358221220020f9fcfdb6eddf6967070074220bc7387aadfdd9f0fe267158d74835c5f9c5c64736f6c63430008070033

Deployed Bytecode Sourcemap

49752:8532:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43573:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55873:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31551:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32999:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32522:411;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44213:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33889:339;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43881:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55922:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57330:143;;;;;;;;;;;;;:::i;:::-;;34299:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44403:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31245:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55801:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30975:208;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28798:148;;;;;;;;;;;;;:::i;:::-;;51931:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28147:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51791:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31720:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56203:246;;;;;;;;;;;;;:::i;:::-;;33292:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34555:328;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56467:823;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52934:2855;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51514:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51365:141;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33658:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51654:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29101:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43573:224;43675:4;43714:35;43699:50;;;:11;:50;;;;:90;;;;43753:36;43777:11;43753:23;:36::i;:::-;43699:90;43692:97;;43573:224;;;:::o;55873:42::-;55913:2;55873:42;:::o;31551:100::-;31605:13;31638:5;31631:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31551:100;:::o;32999:221::-;33075:7;33103:16;33111:7;33103;:16::i;:::-;33095:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;33188:15;:24;33204:7;33188:24;;;;;;;;;;;;;;;;;;;;;33181:31;;32999:221;;;:::o;32522:411::-;32603:13;32619:23;32634:7;32619:14;:23::i;:::-;32603:39;;32667:5;32661:11;;:2;:11;;;;32653:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;32761:5;32745:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;32770:37;32787:5;32794:12;:10;:12::i;:::-;32770:16;:37::i;:::-;32745:62;32723:168;;;;;;;;;;;;:::i;:::-;;;;;;;;;32904:21;32913:2;32917:7;32904:8;:21::i;:::-;32592:341;32522:411;;:::o;44213:113::-;44274:7;44301:10;:17;;;;44294:24;;44213:113;:::o;33889:339::-;34084:41;34103:12;:10;:12::i;:::-;34117:7;34084:18;:41::i;:::-;34076:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;34192:28;34202:4;34208:2;34212:7;34192:9;:28::i;:::-;33889:339;;;:::o;43881:256::-;43978:7;44014:23;44031:5;44014:16;:23::i;:::-;44006:5;:31;43998:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;44103:12;:19;44116:5;44103:19;;;;;;;;;;;;;;;:26;44123:5;44103:26;;;;;;;;;;;;44096:33;;43881:256;;;;:::o;55922:33::-;;;;:::o;57330:143::-;28378:12;:10;:12::i;:::-;28367:23;;:7;:5;:7::i;:::-;:23;;;28359:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;57378:15:::1;57396:21;57378:39;;57436:10;57428:28;;:37;57457:7;57428:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;57367:106;57330:143::o:0;34299:185::-;34437:39;34454:4;34460:2;34464:7;34437:39;;;;;;;;;;;;:16;:39::i;:::-;34299:185;;;:::o;44403:233::-;44478:7;44514:30;:28;:30::i;:::-;44506:5;:38;44498:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;44611:10;44622:5;44611:17;;;;;;;;:::i;:::-;;;;;;;;;;44604:24;;44403:233;;;:::o;31245:239::-;31317:7;31337:13;31353:7;:16;31361:7;31353:16;;;;;;;;;;;;;;;;;;;;;31337:32;;31405:1;31388:19;;:5;:19;;;;31380:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;31471:5;31464:12;;;31245:239;;;:::o;55801:53::-;55837:17;55801:53;:::o;30975:208::-;31047:7;31092:1;31075:19;;:5;:19;;;;31067:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;31159:9;:16;31169:5;31159:16;;;;;;;;;;;;;;;;31152:23;;30975:208;;;:::o;28798:148::-;28378:12;:10;:12::i;:::-;28367:23;;:7;:5;:7::i;:::-;:23;;;28359:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;28905:1:::1;28868:40;;28889:6;;;;;;;;;;;28868:40;;;;;;;;;;;;28936:1;28919:6;;:19;;;;;;;;;;;;;;;;;;28798:148::o:0;51931:129::-;51987:13;52020:32;52026:7;52020:32;;;;;;;;;;;;;;;;;52044:5;52020:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52050:1;52020:5;:32::i;:::-;52013:39;;51931:129;;;:::o;28147:87::-;28193:7;28220:6;;;;;;;;;;;28213:13;;28147:87;:::o;51791:132::-;51848:13;51881:34;51887:7;51881:34;;;;;;;;;;;;;;;;;51906:6;51881:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51913:1;51881:5;:34::i;:::-;51874:41;;51791:132;;;:::o;31720:104::-;31776:13;31809:7;31802:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31720:104;:::o;56203:246::-;56094:6;:20;56101:12;:10;:12::i;:::-;56094:20;;;;;;;;;;;;;;;;;;;;;;;;;56093:21;56085:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;56171:4;56148:6;:20;56155:12;:10;:12::i;:::-;56148:20;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;56284:5:::1;56280:1;56266:13;:11;:13::i;:::-;:15;;;;:::i;:::-;:23;56258:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;56403:38;56413:12;:10;:12::i;:::-;56427:13;:11;:13::i;:::-;56403:9;:38::i;:::-;56203:246::o:0;33292:295::-;33407:12;:10;:12::i;:::-;33395:24;;:8;:24;;;;33387:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;33507:8;33462:18;:32;33481:12;:10;:12::i;:::-;33462:32;;;;;;;;;;;;;;;:42;33495:8;33462:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;33560:8;33531:48;;33546:12;:10;:12::i;:::-;33531:48;;;33570:8;33531:48;;;;;;:::i;:::-;;;;;;;;33292:295;;:::o;34555:328::-;34730:41;34749:12;:10;:12::i;:::-;34763:7;34730:18;:41::i;:::-;34722:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;34836:39;34850:4;34856:2;34860:7;34869:5;34836:13;:39::i;:::-;34555:328;;;;:::o;56467:823::-;55913:2;56565:14;56542:9;:21;56552:10;56542:21;;;;;;;;;;;;;;;;:37;;;;:::i;:::-;:57;;56534:104;;;;;;;;;;;;:::i;:::-;;;;;;;;;56744:1;56727:14;:18;56719:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;56853:10;;56835:14;56820:13;:11;:13::i;:::-;:29;;;;:::i;:::-;:43;;56812:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;55913:2;56929:14;:34;;56921:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;57051:9;57033:14;55837:17;57021:26;;;;:::i;:::-;:39;57013:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;57153:14;57129:9;:21;57139:10;57129:21;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;57105:9;:21;57115:10;57105:21;;;;;;;;;;;;;;;:62;;;;57183:6;57178:105;57199:14;57195:1;:18;57178:105;;;57235:36;57245:10;57257:13;:11;:13::i;:::-;57235:9;:36::i;:::-;57215:3;;;;;:::i;:::-;;;;57178:105;;;;56467:823;:::o;52934:2855::-;52999:13;53025:23;;:::i;:::-;53059:644;;;;;;;;;;;;;;;;;:5;53065:1;53059:8;;;;;;;:::i;:::-;;;;;:644;;;;53727:21;53740:7;53727:12;:21::i;:::-;53716:5;53722:1;53716:8;;;;;;;:::i;:::-;;;;;:32;;;;53761:54;;;;;;;;;;;;;;;;;:5;53767:1;53761:8;;;;;;;:::i;:::-;;;;;:54;;;;53839:18;53849:7;53839:9;:18::i;:::-;53828:5;53834:1;53828:8;;;;;;;:::i;:::-;;;;;:29;;;;53870:54;;;;;;;;;;;;;;;;;:5;53876:1;53870:8;;;;;;;:::i;:::-;;;;;:54;;;;53948:17;53957:7;53948:8;:17::i;:::-;53937:5;53943:1;53937:8;;;;;;;:::i;:::-;;;;;:28;;;;53978:54;;;;;;;;;;;;;;;;;:5;53984:1;53978:8;;;;;;;:::i;:::-;;;;;:54;;;;54056:18;54066:7;54056:9;:18::i;:::-;54045:5;54051:1;54045:8;;;;;;;:::i;:::-;;;;;:29;;;;54087:54;;;;;;;;;;;;;;;;;:5;54093:1;54087:8;;;;;;;:::i;:::-;;;;;:54;;;;54165:17;54174:7;54165:8;:17::i;:::-;54154:5;54160:1;54154:8;;;;;;;:::i;:::-;;;;;:28;;;;54195:27;;;;;;;;;;;;;;;;;:5;54201:2;54195:9;;;;;;;:::i;:::-;;;;;:27;;;;54235:20;54282:5;54288:1;54282:8;;;;;;;:::i;:::-;;;;;;54292:5;54298:1;54292:8;;;;;;;:::i;:::-;;;;;;54302:5;54308:1;54302:8;;;;;;;:::i;:::-;;;;;;54312:5;54318:1;54312:8;;;;;;;:::i;:::-;;;;;;54322:5;54328:1;54322:8;;;;;;;:::i;:::-;;;;;;54332:5;54338:1;54332:8;;;;;;;:::i;:::-;;;;;;54342:5;54348:1;54342:8;;;;;;;:::i;:::-;;;;;;54352:5;54358:1;54352:8;;;;;;;:::i;:::-;;;;;;54362:5;54368:1;54362:8;;;;;;;:::i;:::-;;;;;;54265:106;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;54235:137;;54416:6;54424:5;54430:1;54424:8;;;;;;;:::i;:::-;;;;;;54434:5;54440:2;54434:9;;;;;;;:::i;:::-;;;;;;54445:5;54451:2;54445:9;;;;;;;:::i;:::-;;;;;;54456:5;54462:2;54456:9;;;;;;;:::i;:::-;;;;;;54467:5;54473:2;54467:9;;;;;;;:::i;:::-;;;;;;54478:5;54484:2;54478:9;;;;;;;:::i;:::-;;;;;;54489:5;54495:2;54489:9;;;;;;;:::i;:::-;;;;;;54500:5;54506:2;54500:9;;;;;;;:::i;:::-;;;;;;54399:111;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;54383:128;;54524:27;;:::i;:::-;54562:57;;;;;;;;;;;;;;;;;:9;54572:1;54562:12;;;;;;;:::i;:::-;;;;;:57;;;;54645:5;54651:1;54645:8;;;;;;;:::i;:::-;;;;;;54630:9;54640:1;54630:12;;;;;;;:::i;:::-;;;;;:23;;;;54664:58;;;;;;;;;;;;;;;;;:9;54674:1;54664:12;;;;;;;:::i;:::-;;;;;:58;;;;54748:5;54754:1;54748:8;;;;;;;:::i;:::-;;;;;;54733:9;54743:1;54733:12;;;;;;;:::i;:::-;;;;;:23;;;;54767:56;;;;;;;;;;;;;;;;;:9;54777:1;54767:12;;;;;;;:::i;:::-;;;;;:56;;;;54849:5;54855:1;54849:8;;;;;;;:::i;:::-;;;;;;54834:9;54844:1;54834:12;;;;;;;:::i;:::-;;;;;:23;;;;54868:58;;;;;;;;;;;;;;;;;:9;54878:1;54868:12;;;;;;;:::i;:::-;;;;;:58;;;;54952:5;54958:1;54952:8;;;;;;;:::i;:::-;;;;;;54937:9;54947:1;54937:12;;;;;;;:::i;:::-;;;;;:23;;;;54971:57;;;;;;;;;;;;;;;;;:9;54981:1;54971:12;;;;;;;:::i;:::-;;;;;:57;;;;55054:5;55060:1;55054:8;;;;;;;:::i;:::-;;;;;;55039:9;55049:1;55039:12;;;;;;;:::i;:::-;;;;;:23;;;;55073:22;;;;;;;;;;;;;;;;;:9;55083:2;55073:13;;;;;;;:::i;:::-;;;;;:22;;;;55116:24;55167:9;55177:1;55167:12;;;;;;;:::i;:::-;;;;;;55181:9;55191:1;55181:12;;;;;;;:::i;:::-;;;;;;55195:9;55205:1;55195:12;;;;;;;:::i;:::-;;;;;;55209:9;55219:1;55209:12;;;;;;;:::i;:::-;;;;;;55223:9;55233:1;55223:12;;;;;;;:::i;:::-;;;;;;55237:9;55247:1;55237:12;;;;;;;:::i;:::-;;;;;;55251:9;55261:1;55251:12;;;;;;;:::i;:::-;;;;;;55265:9;55275:1;55265:12;;;;;;;:::i;:::-;;;;;;55150:128;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55116:163;;55327:10;55339:9;55349:1;55339:12;;;;;;;:::i;:::-;;;;;;55353:9;55363:1;55353:12;;;;;;;:::i;:::-;;;;;;55367:9;55377:2;55367:13;;;;;;;:::i;:::-;;;;;;55310:71;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55290:92;;55395:18;55416:256;55485:17;55494:7;55485:8;:17::i;:::-;55604:28;55624:6;55604:13;:28::i;:::-;55653:10;55443:226;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55416:13;:256::i;:::-;55395:277;;55749:4;55699:55;;;;;;;;:::i;:::-;;;;;;;;;;;;;55683:72;;55775:6;55768:13;;;;;;;52934:2855;;;:::o;51514:132::-;51571:13;51604:34;51610:7;51604:34;;;;;;;;;;;;;;;;;51629:6;51604:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51636:1;51604:5;:34::i;:::-;51597:41;;51514:132;;;:::o;51365:141::-;51425:13;51458:40;51464:7;51458:40;;;;;;;;;;;;;;;;;51486:9;51458:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51496:1;51458:5;:40::i;:::-;51451:47;;51365:141;;;:::o;33658:164::-;33755:4;33779:18;:25;33798:5;33779:25;;;;;;;;;;;;;;;:35;33805:8;33779:35;;;;;;;;;;;;;;;;;;;;;;;;;33772:42;;33658:164;;;;:::o;51654:129::-;51710:13;51743:32;51749:7;51743:32;;;;;;;;;;;;;;;;;51767:5;51743:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51773:1;51743:5;:32::i;:::-;51736:39;;51654:129;;;:::o;29101:244::-;28378:12;:10;:12::i;:::-;28367:23;;:7;:5;:7::i;:::-;:23;;;28359:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;29210:1:::1;29190:22;;:8;:22;;;;29182:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;29300:8;29271:38;;29292:6;;;;;;;;;;;29271:38;;;;;;;;;;;;29329:8;29320:6;;:17;;;;;;;;;;;;;;;;;;29101:244:::0;:::o;30606:305::-;30708:4;30760:25;30745:40;;;:11;:40;;;;:105;;;;30817:33;30802:48;;;:11;:48;;;;30745:105;:158;;;;30867:36;30891:11;30867:23;:36::i;:::-;30745:158;30725:178;;30606:305;;;:::o;36393:127::-;36458:4;36510:1;36482:30;;:7;:16;36490:7;36482:16;;;;;;;;;;;;;;;;;;;;;:30;;;;36475:37;;36393:127;;;:::o;26765:98::-;26818:7;26845:10;26838:17;;26765:98;:::o;40375:174::-;40477:2;40450:15;:24;40466:7;40450:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;40533:7;40529:2;40495:46;;40504:23;40519:7;40504:14;:23::i;:::-;40495:46;;;;;;;;;;;;40375:174;;:::o;36687:348::-;36780:4;36805:16;36813:7;36805;:16::i;:::-;36797:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;36881:13;36897:23;36912:7;36897:14;:23::i;:::-;36881:39;;36950:5;36939:16;;:7;:16;;;:51;;;;36983:7;36959:31;;:20;36971:7;36959:11;:20::i;:::-;:31;;;36939:51;:87;;;;36994:32;37011:5;37018:7;36994:16;:32::i;:::-;36939:87;36931:96;;;36687:348;;;;:::o;39679:578::-;39838:4;39811:31;;:23;39826:7;39811:14;:23::i;:::-;:31;;;39803:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;39921:1;39907:16;;:2;:16;;;;39899:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;39977:39;39998:4;40004:2;40008:7;39977:20;:39::i;:::-;40081:29;40098:1;40102:7;40081:8;:29::i;:::-;40142:1;40123:9;:15;40133:4;40123:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;40171:1;40154:9;:13;40164:2;40154:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;40202:2;40183:7;:16;40191:7;40183:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;40241:7;40237:2;40222:27;;40231:4;40222:27;;;;;;;;;;;;39679:578;;;:::o;52074:852::-;52194:13;52220:12;52235:62;52266:9;52277:17;52286:7;52277:8;:17::i;:::-;52249:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52235:6;:62::i;:::-;52220:77;;52308:20;52331:11;52350;:18;52343:4;:25;;;;:::i;:::-;52331:38;;;;;;;;:::i;:::-;;;;;;;;52308:61;;52380:17;52407:2;52400:4;:9;;;;:::i;:::-;52380:29;;52429:21;;:::i;:::-;52475:2;52464:9;:13;52461:138;;;52493:17;;;;;;;;;;;;;;;;;:4;52498:1;52493:7;;;;;;;:::i;:::-;;;;;:17;;;;52461:138;;;52561:5;52574;:12;;;;52567:4;:19;;;;:::i;:::-;52561:26;;;;;;;;:::i;:::-;;;;;;;;;52551:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:4;52556:1;52551:7;;;;;;;:::i;:::-;;;;;:36;;;;52461:138;52619:7;52634;:14;;;;52627:4;:21;;;;:::i;:::-;52619:30;;;;;;;;:::i;:::-;;;;;;;;;52609:40;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:4;52614:1;52609:7;;;;;;;:::i;:::-;;;;;:40;;;;52667:1;52663:2;:5;52660:212;;;52721:4;52726:1;52721:7;;;;;;;:::i;:::-;;;;;;52735:6;52700:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52684:59;;52660:212;;;52821:4;52826:1;52821:7;;;;;;;:::i;:::-;;;;;;52835:6;52851:4;52856:1;52851:7;;;;;;;:::i;:::-;;;;;;52800:59;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52784:76;;52660:212;52912:6;52905:13;;;;;;52074:852;;;;;;:::o;37377:110::-;37453:26;37463:2;37467:7;37453:26;;;;;;;;;;;;:9;:26::i;:::-;37377:110;;:::o;35765:315::-;35922:28;35932:4;35938:2;35942:7;35922:9;:28::i;:::-;35969:48;35992:4;35998:2;36002:7;36011:5;35969:22;:48::i;:::-;35961:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;35765:315;;;;:::o;57487:715::-;57543:13;57765:1;57756:5;:10;57752:53;;;57783:10;;;;;;;;;;;;;;;;;;;;;57752:53;57815:12;57830:5;57815:20;;57846:14;57871:78;57886:1;57878:4;:9;57871:78;;57904:8;;;;;:::i;:::-;;;;57935:2;57927:10;;;;;:::i;:::-;;;57871:78;;;57959:19;57991:6;57981:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57959:39;;58009:154;58025:1;58016:5;:10;58009:154;;58053:1;58043:11;;;;;:::i;:::-;;;58120:2;58112:5;:10;;;;:::i;:::-;58099:2;:24;;;;:::i;:::-;58086:39;;58069:6;58076;58069:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;58149:2;58140:11;;;;;:::i;:::-;;;58009:154;;;58187:6;58173:21;;;;;57487:715;;;;:::o;58635:1607::-;58693:13;58719:11;58733:4;:11;58719:25;;58766:1;58759:3;:8;58755:23;;;58769:9;;;;;;;;;;;;;;;;;58755:23;58830:18;58868:1;58863;58857:3;:7;;;;:::i;:::-;58856:13;;;;:::i;:::-;58851:1;:19;;;;:::i;:::-;58830:40;;58928:19;58973:2;58960:10;:15;;;;:::i;:::-;58950:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58928:48;;58989:18;59010:5;;;;;;;;;;;;;;;;;58989:26;;59079:1;59072:5;59068:13;59124:2;59116:6;59112:15;59175:1;59143:777;59198:3;59195:1;59192:10;59143:777;;;59253:1;59250;59246:9;59241:14;;59311:8;59306:1;59300:4;59296:12;59290:19;59286:34;59391:4;59383:5;59379:2;59375:14;59371:25;59361:8;59357:40;59351:47;59430:3;59427:1;59423:11;59416:18;;59521:4;59512;59504:5;59500:2;59496:14;59492:25;59482:8;59478:40;59472:47;59468:58;59463:3;59459:68;59452:75;;59559:3;59556:1;59552:11;59545:18;;59649:4;59640;59632:5;59629:1;59625:13;59621:24;59611:8;59607:39;59601:46;59597:57;59592:3;59588:67;59581:74;;59687:3;59684:1;59680:11;59673:18;;59769:4;59760;59753:5;59749:16;59739:8;59735:31;59729:38;59725:49;59720:3;59716:59;59709:66;;59809:3;59804;59800:13;59793:20;;59851:3;59840:9;59833:22;59903:1;59892:9;59888:17;59875:30;;59222:698;;59143:777;;;59147:44;59952:1;59947:3;59943:11;59973:1;59968:84;;;;60071:1;60066:82;;;;59936:212;;59968:84;60029:6;60024:3;60020:16;60016:1;60005:9;60001:17;59994:43;59968:84;;60066:82;60127:4;60122:3;60118:14;60114:1;60103:9;60099:17;60092:41;59936:212;;60179:10;60171:6;60164:26;59037:1164;;60227:6;60213:21;;;;;;58635:1607;;;;:::o;19751:157::-;19836:4;19875:25;19860:40;;;:11;:40;;;;19853:47;;19751:157;;;:::o;45249:589::-;45393:45;45420:4;45426:2;45430:7;45393:26;:45::i;:::-;45471:1;45455:18;;:4;:18;;;45451:187;;;45490:40;45522:7;45490:31;:40::i;:::-;45451:187;;;45560:2;45552:10;;:4;:10;;;45548:90;;45579:47;45612:4;45618:7;45579:32;:47::i;:::-;45548:90;45451:187;45666:1;45652:16;;:2;:16;;;45648:183;;;45685:45;45722:7;45685:36;:45::i;:::-;45648:183;;;45758:4;45752:10;;:2;:10;;;45748:83;;45779:40;45807:2;45811:7;45779:27;:40::i;:::-;45748:83;45648:183;45249:589;;;:::o;51218:139::-;51279:7;51341:5;51324:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;51314:34;;;;;;51306:43;;51299:50;;51218:139;;;:::o;37714:321::-;37844:18;37850:2;37854:7;37844:5;:18::i;:::-;37895:54;37926:1;37930:2;37934:7;37943:5;37895:22;:54::i;:::-;37873:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;37714:321;;;:::o;41114:872::-;41269:4;41290:15;:2;:13;;;:15::i;:::-;41286:693;;;41342:2;41326:36;;;41363:12;:10;:12::i;:::-;41377:4;41383:7;41392:5;41326:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41322:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41589:1;41572:6;:13;:18;41568:341;;;41615:60;;;;;;;;;;:::i;:::-;;;;;;;;41568:341;41859:6;41853:13;41844:6;41840:2;41836:15;41829:38;41322:602;41459:45;;;41449:55;;;:6;:55;;;;41442:62;;;;;41286:693;41963:4;41956:11;;41114:872;;;;;;;:::o;42599:126::-;;;;:::o;46561:164::-;46665:10;:17;;;;46638:15;:24;46654:7;46638:24;;;;;;;;;;;:44;;;;46693:10;46709:7;46693:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46561:164;:::o;47352:988::-;47618:22;47668:1;47643:22;47660:4;47643:16;:22::i;:::-;:26;;;;:::i;:::-;47618:51;;47680:18;47701:17;:26;47719:7;47701:26;;;;;;;;;;;;47680:47;;47848:14;47834:10;:28;47830:328;;47879:19;47901:12;:18;47914:4;47901:18;;;;;;;;;;;;;;;:34;47920:14;47901:34;;;;;;;;;;;;47879:56;;47985:11;47952:12;:18;47965:4;47952:18;;;;;;;;;;;;;;;:30;47971:10;47952:30;;;;;;;;;;;:44;;;;48102:10;48069:17;:30;48087:11;48069:30;;;;;;;;;;;:43;;;;47864:294;47830:328;48254:17;:26;48272:7;48254:26;;;;;;;;;;;48247:33;;;48298:12;:18;48311:4;48298:18;;;;;;;;;;;;;;;:34;48317:14;48298:34;;;;;;;;;;;48291:41;;;47433:907;;47352:988;;:::o;48635:1079::-;48888:22;48933:1;48913:10;:17;;;;:21;;;;:::i;:::-;48888:46;;48945:18;48966:15;:24;48982:7;48966:24;;;;;;;;;;;;48945:45;;49317:19;49339:10;49350:14;49339:26;;;;;;;;:::i;:::-;;;;;;;;;;49317:48;;49403:11;49378:10;49389;49378:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;49514:10;49483:15;:28;49499:11;49483:28;;;;;;;;;;;:41;;;;49655:15;:24;49671:7;49655:24;;;;;;;;;;;49648:31;;;49690:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;48706:1008;;;48635:1079;:::o;46139:221::-;46224:14;46241:20;46258:2;46241:16;:20::i;:::-;46224:37;;46299:7;46272:12;:16;46285:2;46272:16;;;;;;;;;;;;;;;:24;46289:6;46272:24;;;;;;;;;;;:34;;;;46346:6;46317:17;:26;46335:7;46317:26;;;;;;;;;;;:35;;;;46213:147;46139:221;;:::o;38371:382::-;38465:1;38451:16;;:2;:16;;;;38443:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;38524:16;38532:7;38524;:16::i;:::-;38523:17;38515:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;38586:45;38615:1;38619:2;38623:7;38586:20;:45::i;:::-;38661:1;38644:9;:13;38654:2;38644:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;38692:2;38673:7;:16;38681:7;38673:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;38737:7;38733:2;38712:33;;38729:1;38712:33;;;;;;;;;;;;38371:382;;:::o;9867:444::-;9927:4;10135:12;10259:7;10247:20;10239:28;;10302:1;10295:4;:8;10288:15;;;9867:444;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:139::-;469:5;507:6;494:20;485:29;;523:33;550:5;523:33;:::i;:::-;423:139;;;;:::o;568:133::-;611:5;649:6;636:20;627:29;;665:30;689:5;665:30;:::i;:::-;568:133;;;;:::o;707:137::-;752:5;790:6;777:20;768:29;;806:32;832:5;806:32;:::i;:::-;707:137;;;;:::o;850:141::-;906:5;937:6;931:13;922:22;;953:32;979:5;953:32;:::i;:::-;850:141;;;;:::o;1010:338::-;1065:5;1114:3;1107:4;1099:6;1095:17;1091:27;1081:122;;1122:79;;:::i;:::-;1081:122;1239:6;1226:20;1264:78;1338:3;1330:6;1323:4;1315:6;1311:17;1264:78;:::i;:::-;1255:87;;1071:277;1010:338;;;;:::o;1354:139::-;1400:5;1438:6;1425:20;1416:29;;1454:33;1481:5;1454:33;:::i;:::-;1354:139;;;;:::o;1499:329::-;1558:6;1607:2;1595:9;1586:7;1582:23;1578:32;1575:119;;;1613:79;;:::i;:::-;1575:119;1733:1;1758:53;1803:7;1794:6;1783:9;1779:22;1758:53;:::i;:::-;1748:63;;1704:117;1499:329;;;;:::o;1834:474::-;1902:6;1910;1959:2;1947:9;1938:7;1934:23;1930:32;1927:119;;;1965:79;;:::i;:::-;1927:119;2085:1;2110:53;2155:7;2146:6;2135:9;2131:22;2110:53;:::i;:::-;2100:63;;2056:117;2212:2;2238:53;2283:7;2274:6;2263:9;2259:22;2238:53;:::i;:::-;2228:63;;2183:118;1834:474;;;;;:::o;2314:619::-;2391:6;2399;2407;2456:2;2444:9;2435:7;2431:23;2427:32;2424:119;;;2462:79;;:::i;:::-;2424:119;2582:1;2607:53;2652:7;2643:6;2632:9;2628:22;2607:53;:::i;:::-;2597:63;;2553:117;2709:2;2735:53;2780:7;2771:6;2760:9;2756:22;2735:53;:::i;:::-;2725:63;;2680:118;2837:2;2863:53;2908:7;2899:6;2888:9;2884:22;2863:53;:::i;:::-;2853:63;;2808:118;2314:619;;;;;:::o;2939:943::-;3034:6;3042;3050;3058;3107:3;3095:9;3086:7;3082:23;3078:33;3075:120;;;3114:79;;:::i;:::-;3075:120;3234:1;3259:53;3304:7;3295:6;3284:9;3280:22;3259:53;:::i;:::-;3249:63;;3205:117;3361:2;3387:53;3432:7;3423:6;3412:9;3408:22;3387:53;:::i;:::-;3377:63;;3332:118;3489:2;3515:53;3560:7;3551:6;3540:9;3536:22;3515:53;:::i;:::-;3505:63;;3460:118;3645:2;3634:9;3630:18;3617:32;3676:18;3668:6;3665:30;3662:117;;;3698:79;;:::i;:::-;3662:117;3803:62;3857:7;3848:6;3837:9;3833:22;3803:62;:::i;:::-;3793:72;;3588:287;2939:943;;;;;;;:::o;3888:468::-;3953:6;3961;4010:2;3998:9;3989:7;3985:23;3981:32;3978:119;;;4016:79;;:::i;:::-;3978:119;4136:1;4161:53;4206:7;4197:6;4186:9;4182:22;4161:53;:::i;:::-;4151:63;;4107:117;4263:2;4289:50;4331:7;4322:6;4311:9;4307:22;4289:50;:::i;:::-;4279:60;;4234:115;3888:468;;;;;:::o;4362:474::-;4430:6;4438;4487:2;4475:9;4466:7;4462:23;4458:32;4455:119;;;4493:79;;:::i;:::-;4455:119;4613:1;4638:53;4683:7;4674:6;4663:9;4659:22;4638:53;:::i;:::-;4628:63;;4584:117;4740:2;4766:53;4811:7;4802:6;4791:9;4787:22;4766:53;:::i;:::-;4756:63;;4711:118;4362:474;;;;;:::o;4842:327::-;4900:6;4949:2;4937:9;4928:7;4924:23;4920:32;4917:119;;;4955:79;;:::i;:::-;4917:119;5075:1;5100:52;5144:7;5135:6;5124:9;5120:22;5100:52;:::i;:::-;5090:62;;5046:116;4842:327;;;;:::o;5175:349::-;5244:6;5293:2;5281:9;5272:7;5268:23;5264:32;5261:119;;;5299:79;;:::i;:::-;5261:119;5419:1;5444:63;5499:7;5490:6;5479:9;5475:22;5444:63;:::i;:::-;5434:73;;5390:127;5175:349;;;;:::o;5530:329::-;5589:6;5638:2;5626:9;5617:7;5613:23;5609:32;5606:119;;;5644:79;;:::i;:::-;5606:119;5764:1;5789:53;5834:7;5825:6;5814:9;5810:22;5789:53;:::i;:::-;5779:63;;5735:117;5530:329;;;;:::o;5865:118::-;5952:24;5970:5;5952:24;:::i;:::-;5947:3;5940:37;5865:118;;:::o;5989:109::-;6070:21;6085:5;6070:21;:::i;:::-;6065:3;6058:34;5989:109;;:::o;6104:360::-;6190:3;6218:38;6250:5;6218:38;:::i;:::-;6272:70;6335:6;6330:3;6272:70;:::i;:::-;6265:77;;6351:52;6396:6;6391:3;6384:4;6377:5;6373:16;6351:52;:::i;:::-;6428:29;6450:6;6428:29;:::i;:::-;6423:3;6419:39;6412:46;;6194:270;6104:360;;;;:::o;6470:364::-;6558:3;6586:39;6619:5;6586:39;:::i;:::-;6641:71;6705:6;6700:3;6641:71;:::i;:::-;6634:78;;6721:52;6766:6;6761:3;6754:4;6747:5;6743:16;6721:52;:::i;:::-;6798:29;6820:6;6798:29;:::i;:::-;6793:3;6789:39;6782:46;;6562:272;6470:364;;;;:::o;6840:377::-;6946:3;6974:39;7007:5;6974:39;:::i;:::-;7029:89;7111:6;7106:3;7029:89;:::i;:::-;7022:96;;7127:52;7172:6;7167:3;7160:4;7153:5;7149:16;7127:52;:::i;:::-;7204:6;7199:3;7195:16;7188:23;;6950:267;6840:377;;;;:::o;7223:366::-;7365:3;7386:67;7450:2;7445:3;7386:67;:::i;:::-;7379:74;;7462:93;7551:3;7462:93;:::i;:::-;7580:2;7575:3;7571:12;7564:19;;7223:366;;;:::o;7595:::-;7737:3;7758:67;7822:2;7817:3;7758:67;:::i;:::-;7751:74;;7834:93;7923:3;7834:93;:::i;:::-;7952:2;7947:3;7943:12;7936:19;;7595:366;;;:::o;7967:::-;8109:3;8130:67;8194:2;8189:3;8130:67;:::i;:::-;8123:74;;8206:93;8295:3;8206:93;:::i;:::-;8324:2;8319:3;8315:12;8308:19;;7967:366;;;:::o;8339:::-;8481:3;8502:67;8566:2;8561:3;8502:67;:::i;:::-;8495:74;;8578:93;8667:3;8578:93;:::i;:::-;8696:2;8691:3;8687:12;8680:19;;8339:366;;;:::o;8711:::-;8853:3;8874:67;8938:2;8933:3;8874:67;:::i;:::-;8867:74;;8950:93;9039:3;8950:93;:::i;:::-;9068:2;9063:3;9059:12;9052:19;;8711:366;;;:::o;9083:::-;9225:3;9246:67;9310:2;9305:3;9246:67;:::i;:::-;9239:74;;9322:93;9411:3;9322:93;:::i;:::-;9440:2;9435:3;9431:12;9424:19;;9083:366;;;:::o;9455:402::-;9615:3;9636:85;9718:2;9713:3;9636:85;:::i;:::-;9629:92;;9730:93;9819:3;9730:93;:::i;:::-;9848:2;9843:3;9839:12;9832:19;;9455:402;;;:::o;9863:::-;10023:3;10044:85;10126:2;10121:3;10044:85;:::i;:::-;10037:92;;10138:93;10227:3;10138:93;:::i;:::-;10256:2;10251:3;10247:12;10240:19;;9863:402;;;:::o;10271:366::-;10413:3;10434:67;10498:2;10493:3;10434:67;:::i;:::-;10427:74;;10510:93;10599:3;10510:93;:::i;:::-;10628:2;10623:3;10619:12;10612:19;;10271:366;;;:::o;10643:::-;10785:3;10806:67;10870:2;10865:3;10806:67;:::i;:::-;10799:74;;10882:93;10971:3;10882:93;:::i;:::-;11000:2;10995:3;10991:12;10984:19;;10643:366;;;:::o;11015:::-;11157:3;11178:67;11242:2;11237:3;11178:67;:::i;:::-;11171:74;;11254:93;11343:3;11254:93;:::i;:::-;11372:2;11367:3;11363:12;11356:19;;11015:366;;;:::o;11387:::-;11529:3;11550:67;11614:2;11609:3;11550:67;:::i;:::-;11543:74;;11626:93;11715:3;11626:93;:::i;:::-;11744:2;11739:3;11735:12;11728:19;;11387:366;;;:::o;11759:400::-;11919:3;11940:84;12022:1;12017:3;11940:84;:::i;:::-;11933:91;;12033:93;12122:3;12033:93;:::i;:::-;12151:1;12146:3;12142:11;12135:18;;11759:400;;;:::o;12165:366::-;12307:3;12328:67;12392:2;12387:3;12328:67;:::i;:::-;12321:74;;12404:93;12493:3;12404:93;:::i;:::-;12522:2;12517:3;12513:12;12506:19;;12165:366;;;:::o;12537:::-;12679:3;12700:67;12764:2;12759:3;12700:67;:::i;:::-;12693:74;;12776:93;12865:3;12776:93;:::i;:::-;12894:2;12889:3;12885:12;12878:19;;12537:366;;;:::o;12909:::-;13051:3;13072:67;13136:2;13131:3;13072:67;:::i;:::-;13065:74;;13148:93;13237:3;13148:93;:::i;:::-;13266:2;13261:3;13257:12;13250:19;;12909:366;;;:::o;13281:::-;13423:3;13444:67;13508:2;13503:3;13444:67;:::i;:::-;13437:74;;13520:93;13609:3;13520:93;:::i;:::-;13638:2;13633:3;13629:12;13622:19;;13281:366;;;:::o;13653:::-;13795:3;13816:67;13880:2;13875:3;13816:67;:::i;:::-;13809:74;;13892:93;13981:3;13892:93;:::i;:::-;14010:2;14005:3;14001:12;13994:19;;13653:366;;;:::o;14025:400::-;14185:3;14206:84;14288:1;14283:3;14206:84;:::i;:::-;14199:91;;14299:93;14388:3;14299:93;:::i;:::-;14417:1;14412:3;14408:11;14401:18;;14025:400;;;:::o;14431:366::-;14573:3;14594:67;14658:2;14653:3;14594:67;:::i;:::-;14587:74;;14670:93;14759:3;14670:93;:::i;:::-;14788:2;14783:3;14779:12;14772:19;;14431:366;;;:::o;14803:400::-;14963:3;14984:84;15066:1;15061:3;14984:84;:::i;:::-;14977:91;;15077:93;15166:3;15077:93;:::i;:::-;15195:1;15190:3;15186:11;15179:18;;14803:400;;;:::o;15209:366::-;15351:3;15372:67;15436:2;15431:3;15372:67;:::i;:::-;15365:74;;15448:93;15537:3;15448:93;:::i;:::-;15566:2;15561:3;15557:12;15550:19;;15209:366;;;:::o;15581:::-;15723:3;15744:67;15808:2;15803:3;15744:67;:::i;:::-;15737:74;;15820:93;15909:3;15820:93;:::i;:::-;15938:2;15933:3;15929:12;15922:19;;15581:366;;;:::o;15953:::-;16095:3;16116:67;16180:2;16175:3;16116:67;:::i;:::-;16109:74;;16192:93;16281:3;16192:93;:::i;:::-;16310:2;16305:3;16301:12;16294:19;;15953:366;;;:::o;16325:::-;16467:3;16488:67;16552:2;16547:3;16488:67;:::i;:::-;16481:74;;16564:93;16653:3;16564:93;:::i;:::-;16682:2;16677:3;16673:12;16666:19;;16325:366;;;:::o;16697:::-;16839:3;16860:67;16924:2;16919:3;16860:67;:::i;:::-;16853:74;;16936:93;17025:3;16936:93;:::i;:::-;17054:2;17049:3;17045:12;17038:19;;16697:366;;;:::o;17069:::-;17211:3;17232:67;17296:2;17291:3;17232:67;:::i;:::-;17225:74;;17308:93;17397:3;17308:93;:::i;:::-;17426:2;17421:3;17417:12;17410:19;;17069:366;;;:::o;17441:402::-;17601:3;17622:85;17704:2;17699:3;17622:85;:::i;:::-;17615:92;;17716:93;17805:3;17716:93;:::i;:::-;17834:2;17829:3;17825:12;17818:19;;17441:402;;;:::o;17849:400::-;18009:3;18030:84;18112:1;18107:3;18030:84;:::i;:::-;18023:91;;18123:93;18212:3;18123:93;:::i;:::-;18241:1;18236:3;18232:11;18225:18;;17849:400;;;:::o;18255:366::-;18397:3;18418:67;18482:2;18477:3;18418:67;:::i;:::-;18411:74;;18494:93;18583:3;18494:93;:::i;:::-;18612:2;18607:3;18603:12;18596:19;;18255:366;;;:::o;18627:::-;18769:3;18790:67;18854:2;18849:3;18790:67;:::i;:::-;18783:74;;18866:93;18955:3;18866:93;:::i;:::-;18984:2;18979:3;18975:12;18968:19;;18627:366;;;:::o;18999:402::-;19159:3;19180:85;19262:2;19257:3;19180:85;:::i;:::-;19173:92;;19274:93;19363:3;19274:93;:::i;:::-;19392:2;19387:3;19383:12;19376:19;;18999:402;;;:::o;19407:118::-;19494:24;19512:5;19494:24;:::i;:::-;19489:3;19482:37;19407:118;;:::o;19531:275::-;19663:3;19685:95;19776:3;19767:6;19685:95;:::i;:::-;19678:102;;19797:3;19790:10;;19531:275;;;;:::o;19812:435::-;19992:3;20014:95;20105:3;20096:6;20014:95;:::i;:::-;20007:102;;20126:95;20217:3;20208:6;20126:95;:::i;:::-;20119:102;;20238:3;20231:10;;19812:435;;;;;:::o;20253:755::-;20529:3;20551:95;20642:3;20633:6;20551:95;:::i;:::-;20544:102;;20663:95;20754:3;20745:6;20663:95;:::i;:::-;20656:102;;20775:95;20866:3;20857:6;20775:95;:::i;:::-;20768:102;;20887:95;20978:3;20969:6;20887:95;:::i;:::-;20880:102;;20999:3;20992:10;;20253:755;;;;;;;:::o;21014:1395::-;21482:3;21504:95;21595:3;21586:6;21504:95;:::i;:::-;21497:102;;21616:95;21707:3;21698:6;21616:95;:::i;:::-;21609:102;;21728:95;21819:3;21810:6;21728:95;:::i;:::-;21721:102;;21840:95;21931:3;21922:6;21840:95;:::i;:::-;21833:102;;21952:95;22043:3;22034:6;21952:95;:::i;:::-;21945:102;;22064:95;22155:3;22146:6;22064:95;:::i;:::-;22057:102;;22176:95;22267:3;22258:6;22176:95;:::i;:::-;22169:102;;22288:95;22379:3;22370:6;22288:95;:::i;:::-;22281:102;;22400:3;22393:10;;21014:1395;;;;;;;;;;;:::o;22415:1555::-;22931:3;22953:95;23044:3;23035:6;22953:95;:::i;:::-;22946:102;;23065:95;23156:3;23147:6;23065:95;:::i;:::-;23058:102;;23177:95;23268:3;23259:6;23177:95;:::i;:::-;23170:102;;23289:95;23380:3;23371:6;23289:95;:::i;:::-;23282:102;;23401:95;23492:3;23483:6;23401:95;:::i;:::-;23394:102;;23513:95;23604:3;23595:6;23513:95;:::i;:::-;23506:102;;23625:95;23716:3;23707:6;23625:95;:::i;:::-;23618:102;;23737:95;23828:3;23819:6;23737:95;:::i;:::-;23730:102;;23849:95;23940:3;23931:6;23849:95;:::i;:::-;23842:102;;23961:3;23954:10;;22415:1555;;;;;;;;;;;;:::o;23976:541::-;24209:3;24231:148;24375:3;24231:148;:::i;:::-;24224:155;;24396:95;24487:3;24478:6;24396:95;:::i;:::-;24389:102;;24508:3;24501:10;;23976:541;;;;:::o;24523:967::-;24905:3;24927:148;25071:3;24927:148;:::i;:::-;24920:155;;25092:95;25183:3;25174:6;25092:95;:::i;:::-;25085:102;;25204:148;25348:3;25204:148;:::i;:::-;25197:155;;25369:95;25460:3;25451:6;25369:95;:::i;:::-;25362:102;;25481:3;25474:10;;24523:967;;;;;:::o;25496:1393::-;26027:3;26049:148;26193:3;26049:148;:::i;:::-;26042:155;;26214:95;26305:3;26296:6;26214:95;:::i;:::-;26207:102;;26326:148;26470:3;26326:148;:::i;:::-;26319:155;;26491:95;26582:3;26573:6;26491:95;:::i;:::-;26484:102;;26603:148;26747:3;26603:148;:::i;:::-;26596:155;;26768:95;26859:3;26850:6;26768:95;:::i;:::-;26761:102;;26880:3;26873:10;;25496:1393;;;;;;:::o;26895:1659::-;27527:3;27549:148;27693:3;27549:148;:::i;:::-;27542:155;;27714:95;27805:3;27796:6;27714:95;:::i;:::-;27707:102;;27826:148;27970:3;27826:148;:::i;:::-;27819:155;;27991:95;28082:3;28073:6;27991:95;:::i;:::-;27984:102;;28103:148;28247:3;28103:148;:::i;:::-;28096:155;;28268:95;28359:3;28350:6;28268:95;:::i;:::-;28261:102;;28380:148;28524:3;28380:148;:::i;:::-;28373:155;;28545:3;28538:10;;26895:1659;;;;;;:::o;28560:222::-;28653:4;28691:2;28680:9;28676:18;28668:26;;28704:71;28772:1;28761:9;28757:17;28748:6;28704:71;:::i;:::-;28560:222;;;;:::o;28788:640::-;28983:4;29021:3;29010:9;29006:19;28998:27;;29035:71;29103:1;29092:9;29088:17;29079:6;29035:71;:::i;:::-;29116:72;29184:2;29173:9;29169:18;29160:6;29116:72;:::i;:::-;29198;29266:2;29255:9;29251:18;29242:6;29198:72;:::i;:::-;29317:9;29311:4;29307:20;29302:2;29291:9;29287:18;29280:48;29345:76;29416:4;29407:6;29345:76;:::i;:::-;29337:84;;28788:640;;;;;;;:::o;29434:210::-;29521:4;29559:2;29548:9;29544:18;29536:26;;29572:65;29634:1;29623:9;29619:17;29610:6;29572:65;:::i;:::-;29434:210;;;;:::o;29650:313::-;29763:4;29801:2;29790:9;29786:18;29778:26;;29850:9;29844:4;29840:20;29836:1;29825:9;29821:17;29814:47;29878:78;29951:4;29942:6;29878:78;:::i;:::-;29870:86;;29650:313;;;;:::o;29969:419::-;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:::-;34385:4;34423:2;34412:9;34408:18;34400:26;;34472:9;34466:4;34462:20;34458:1;34447:9;34443:17;34436:47;34500:131;34626:4;34500:131;:::i;:::-;34492:139;;34219:419;;;:::o;34644:::-;34810:4;34848:2;34837:9;34833:18;34825:26;;34897:9;34891:4;34887:20;34883:1;34872:9;34868:17;34861:47;34925:131;35051:4;34925:131;:::i;:::-;34917:139;;34644:419;;;:::o;35069:::-;35235:4;35273:2;35262:9;35258:18;35250:26;;35322:9;35316:4;35312:20;35308:1;35297:9;35293:17;35286:47;35350:131;35476:4;35350:131;:::i;:::-;35342:139;;35069:419;;;:::o;35494:::-;35660:4;35698:2;35687:9;35683:18;35675:26;;35747:9;35741:4;35737:20;35733:1;35722:9;35718:17;35711:47;35775:131;35901:4;35775:131;:::i;:::-;35767:139;;35494:419;;;:::o;35919:::-;36085:4;36123:2;36112:9;36108:18;36100:26;;36172:9;36166:4;36162:20;36158:1;36147:9;36143:17;36136:47;36200:131;36326:4;36200:131;:::i;:::-;36192:139;;35919:419;;;:::o;36344:::-;36510:4;36548:2;36537:9;36533:18;36525:26;;36597:9;36591:4;36587:20;36583:1;36572:9;36568:17;36561:47;36625:131;36751:4;36625:131;:::i;:::-;36617:139;;36344:419;;;:::o;36769:::-;36935:4;36973:2;36962:9;36958:18;36950:26;;37022:9;37016:4;37012:20;37008:1;36997:9;36993:17;36986:47;37050:131;37176:4;37050:131;:::i;:::-;37042:139;;36769:419;;;:::o;37194:::-;37360:4;37398:2;37387:9;37383:18;37375:26;;37447:9;37441:4;37437:20;37433:1;37422:9;37418:17;37411:47;37475:131;37601:4;37475:131;:::i;:::-;37467:139;;37194:419;;;:::o;37619:::-;37785:4;37823:2;37812:9;37808:18;37800:26;;37872:9;37866:4;37862:20;37858:1;37847:9;37843:17;37836:47;37900:131;38026:4;37900:131;:::i;:::-;37892:139;;37619:419;;;:::o;38044:::-;38210:4;38248:2;38237:9;38233:18;38225:26;;38297:9;38291:4;38287:20;38283:1;38272:9;38268:17;38261:47;38325:131;38451:4;38325:131;:::i;:::-;38317:139;;38044:419;;;:::o;38469:::-;38635:4;38673:2;38662:9;38658:18;38650:26;;38722:9;38716:4;38712:20;38708:1;38697:9;38693:17;38686:47;38750:131;38876:4;38750:131;:::i;:::-;38742:139;;38469:419;;;:::o;38894:::-;39060:4;39098:2;39087:9;39083:18;39075:26;;39147:9;39141:4;39137:20;39133:1;39122:9;39118:17;39111:47;39175:131;39301:4;39175:131;:::i;:::-;39167:139;;38894:419;;;:::o;39319:::-;39485:4;39523:2;39512:9;39508:18;39500:26;;39572:9;39566:4;39562:20;39558:1;39547:9;39543:17;39536:47;39600:131;39726:4;39600:131;:::i;:::-;39592:139;;39319:419;;;:::o;39744:::-;39910:4;39948:2;39937:9;39933:18;39925:26;;39997:9;39991:4;39987:20;39983:1;39972:9;39968:17;39961:47;40025:131;40151:4;40025:131;:::i;:::-;40017:139;;39744:419;;;:::o;40169:222::-;40262:4;40300:2;40289:9;40285:18;40277:26;;40313:71;40381:1;40370:9;40366:17;40357:6;40313:71;:::i;:::-;40169:222;;;;:::o;40397:129::-;40431:6;40458:20;;:::i;:::-;40448:30;;40487:33;40515:4;40507:6;40487:33;:::i;:::-;40397:129;;;:::o;40532:75::-;40565:6;40598:2;40592:9;40582:19;;40532:75;:::o;40613:307::-;40674:4;40764:18;40756:6;40753:30;40750:56;;;40786:18;;:::i;:::-;40750:56;40824:29;40846:6;40824:29;:::i;:::-;40816:37;;40908:4;40902;40898:15;40890:23;;40613:307;;;:::o;40926:98::-;40977:6;41011:5;41005:12;40995:22;;40926:98;;;:::o;41030:99::-;41082:6;41116:5;41110:12;41100:22;;41030:99;;;:::o;41135:168::-;41218:11;41252:6;41247:3;41240:19;41292:4;41287:3;41283:14;41268:29;;41135:168;;;;:::o;41309:169::-;41393:11;41427:6;41422:3;41415:19;41467:4;41462:3;41458:14;41443:29;;41309:169;;;;:::o;41484:148::-;41586:11;41623:3;41608:18;;41484:148;;;;:::o;41638:305::-;41678:3;41697:20;41715:1;41697:20;:::i;:::-;41692:25;;41731:20;41749:1;41731:20;:::i;:::-;41726:25;;41885:1;41817:66;41813:74;41810:1;41807:81;41804:107;;;41891:18;;:::i;:::-;41804:107;41935:1;41932;41928:9;41921:16;;41638:305;;;;:::o;41949:185::-;41989:1;42006:20;42024:1;42006:20;:::i;:::-;42001:25;;42040:20;42058:1;42040:20;:::i;:::-;42035:25;;42079:1;42069:35;;42084:18;;:::i;:::-;42069:35;42126:1;42123;42119:9;42114:14;;41949:185;;;;:::o;42140:348::-;42180:7;42203:20;42221:1;42203:20;:::i;:::-;42198:25;;42237:20;42255:1;42237:20;:::i;:::-;42232:25;;42425:1;42357:66;42353:74;42350:1;42347:81;42342:1;42335:9;42328:17;42324:105;42321:131;;;42432:18;;:::i;:::-;42321:131;42480:1;42477;42473:9;42462:20;;42140:348;;;;:::o;42494:191::-;42534:4;42554:20;42572:1;42554:20;:::i;:::-;42549:25;;42588:20;42606:1;42588:20;:::i;:::-;42583:25;;42627:1;42624;42621:8;42618:34;;;42632:18;;:::i;:::-;42618:34;42677:1;42674;42670:9;42662:17;;42494:191;;;;:::o;42691:96::-;42728:7;42757:24;42775:5;42757:24;:::i;:::-;42746:35;;42691:96;;;:::o;42793:90::-;42827:7;42870:5;42863:13;42856:21;42845:32;;42793:90;;;:::o;42889:149::-;42925:7;42965:66;42958:5;42954:78;42943:89;;42889:149;;;:::o;43044:126::-;43081:7;43121:42;43114:5;43110:54;43099:65;;43044:126;;;:::o;43176:77::-;43213:7;43242:5;43231:16;;43176:77;;;:::o;43259:154::-;43343:6;43338:3;43333;43320:30;43405:1;43396:6;43391:3;43387:16;43380:27;43259:154;;;:::o;43419:307::-;43487:1;43497:113;43511:6;43508:1;43505:13;43497:113;;;43596:1;43591:3;43587:11;43581:18;43577:1;43572:3;43568:11;43561:39;43533:2;43530:1;43526:10;43521:15;;43497:113;;;43628:6;43625:1;43622:13;43619:101;;;43708:1;43699:6;43694:3;43690:16;43683:27;43619:101;43468:258;43419:307;;;:::o;43732:320::-;43776:6;43813:1;43807:4;43803:12;43793:22;;43860:1;43854:4;43850:12;43881:18;43871:81;;43937:4;43929:6;43925:17;43915:27;;43871:81;43999:2;43991:6;43988:14;43968:18;43965:38;43962:84;;;44018:18;;:::i;:::-;43962:84;43783:269;43732:320;;;:::o;44058:281::-;44141:27;44163:4;44141:27;:::i;:::-;44133:6;44129:40;44271:6;44259:10;44256:22;44235:18;44223:10;44220:34;44217:62;44214:88;;;44282:18;;:::i;:::-;44214:88;44322:10;44318:2;44311:22;44101:238;44058:281;;:::o;44345:233::-;44384:3;44407:24;44425:5;44407:24;:::i;:::-;44398:33;;44453:66;44446:5;44443:77;44440:103;;;44523:18;;:::i;:::-;44440:103;44570:1;44563:5;44559:13;44552:20;;44345:233;;;:::o;44584:176::-;44616:1;44633:20;44651:1;44633:20;:::i;:::-;44628:25;;44667:20;44685:1;44667:20;:::i;:::-;44662:25;;44706:1;44696:35;;44711:18;;:::i;:::-;44696:35;44752:1;44749;44745:9;44740:14;;44584:176;;;;:::o;44766:180::-;44814:77;44811:1;44804:88;44911:4;44908:1;44901:15;44935:4;44932:1;44925:15;44952:180;45000:77;44997:1;44990:88;45097:4;45094:1;45087:15;45121:4;45118:1;45111:15;45138:180;45186:77;45183:1;45176:88;45283:4;45280:1;45273:15;45307:4;45304:1;45297:15;45324:180;45372:77;45369:1;45362:88;45469:4;45466:1;45459:15;45493:4;45490:1;45483:15;45510:180;45558:77;45555:1;45548:88;45655:4;45652:1;45645:15;45679:4;45676:1;45669:15;45696:180;45744:77;45741:1;45734:88;45841:4;45838:1;45831:15;45865:4;45862:1;45855:15;45882:117;45991:1;45988;45981:12;46005:117;46114:1;46111;46104:12;46128:117;46237:1;46234;46227:12;46251:117;46360:1;46357;46350:12;46374:102;46415:6;46466:2;46462:7;46457:2;46450:5;46446:14;46442:28;46432:38;;46374:102;;;:::o;46482:221::-;46622:34;46618:1;46610:6;46606:14;46599:58;46691:4;46686:2;46678:6;46674:15;46667:29;46482:221;:::o;46709:238::-;46849:34;46845:1;46837:6;46833:14;46826:58;46918:21;46913:2;46905:6;46901:15;46894:46;46709:238;:::o;46953:230::-;47093:34;47089:1;47081:6;47077:14;47070:58;47162:13;47157:2;47149:6;47145:15;47138:38;46953:230;:::o;47189:237::-;47329:34;47325:1;47317:6;47313:14;47306:58;47398:20;47393:2;47385:6;47381:15;47374:45;47189:237;:::o;47432:225::-;47572:34;47568:1;47560:6;47556:14;47549:58;47641:8;47636:2;47628:6;47624:15;47617:33;47432:225;:::o;47663:178::-;47803:30;47799:1;47791:6;47787:14;47780:54;47663:178;:::o;47847:214::-;47987:66;47983:1;47975:6;47971:14;47964:90;47847:214;:::o;48067:416::-;48207:66;48203:1;48195:6;48191:14;48184:90;48308:66;48303:2;48295:6;48291:15;48284:91;48409:66;48404:2;48396:6;48392:15;48385:91;48067:416;:::o;48489:223::-;48629:34;48625:1;48617:6;48613:14;48606:58;48698:6;48693:2;48685:6;48681:15;48674:31;48489:223;:::o;48718:175::-;48858:27;48854:1;48846:6;48842:14;48835:51;48718:175;:::o;48899:178::-;49039:30;49035:1;49027:6;49023:14;49016:54;48899:178;:::o;49083:231::-;49223:34;49219:1;49211:6;49207:14;49200:58;49292:14;49287:2;49279:6;49275:15;49268:39;49083:231;:::o;49320:151::-;49460:3;49456:1;49448:6;49444:14;49437:27;49320:151;:::o;49477:222::-;49617:34;49613:1;49605:6;49601:14;49594:58;49686:5;49681:2;49673:6;49669:15;49662:30;49477:222;:::o;49705:243::-;49845:34;49841:1;49833:6;49829:14;49822:58;49914:26;49909:2;49901:6;49897:15;49890:51;49705:243;:::o;49954:229::-;50094:34;50090:1;50082:6;50078:14;50071:58;50163:12;50158:2;50150:6;50146:15;50139:37;49954:229;:::o;50189:228::-;50329:34;50325:1;50317:6;50313:14;50306:58;50398:11;50393:2;50385:6;50381:15;50374:36;50189:228;:::o;50423:179::-;50563:31;50559:1;50551:6;50547:14;50540:55;50423:179;:::o;50608:154::-;50748:6;50744:1;50736:6;50732:14;50725:30;50608:154;:::o;50768:182::-;50908:34;50904:1;50896:6;50892:14;50885:58;50768:182;:::o;50956:143::-;51092:3;51088:1;51080:6;51076:14;51069:27;50956:143;:::o;51101:219::-;51237:34;51233:1;51225:6;51221:14;51214:58;51302:14;51297:2;51289:6;51285:15;51278:39;51101:219;:::o;51322:174::-;51458:34;51454:1;51446:6;51442:14;51435:58;51322:174;:::o;51498:216::-;51634:34;51630:1;51622:6;51618:14;51611:58;51699:11;51694:2;51686:6;51682:15;51675:36;51498:216;:::o;51716:217::-;51852:34;51848:1;51840:6;51836:14;51829:58;51917:12;51912:2;51904:6;51900:15;51893:37;51716:217;:::o;51935:208::-;52071:34;52067:1;52059:6;52055:14;52048:58;52136:3;52131:2;52123:6;52119:15;52112:28;51935:208;:::o;52145:160::-;52281:20;52277:1;52269:6;52265:14;52258:44;52145:160;:::o;52307:171::-;52443:31;52439:1;52431:6;52427:14;52420:55;52307:171;:::o;52480:110::-;;:::o;52592:224::-;52728:34;52724:1;52716:6;52712:14;52705:58;52793:19;52788:2;52780:6;52776:15;52769:44;52592:224;:::o;52818:219::-;52954:34;52950:1;52942:6;52938:14;52931:58;53019:14;53014:2;53006:6;53002:15;52995:39;52818:219;:::o;53039:206::-;53175:66;53171:1;53163:6;53159:14;53152:90;53039:206;:::o;53247:114::-;53316:24;53334:5;53316:24;:::i;:::-;53309:5;53306:35;53296:63;;53355:1;53352;53345:12;53296:63;53247:114;:::o;53363:108::-;53429:21;53444:5;53429:21;:::i;:::-;53422:5;53419:32;53409:60;;53465:1;53462;53455:12;53409:60;53363:108;:::o;53473:112::-;53541:23;53558:5;53541:23;:::i;:::-;53534:5;53531:34;53521:62;;53579:1;53576;53569:12;53521:62;53473:112;:::o;53587:114::-;53656:24;53674:5;53656:24;:::i;:::-;53649:5;53646:35;53636:63;;53695:1;53692;53685:12;53636:63;53587:114;:::o

Swarm Source

ipfs://020f9fcfdb6eddf6967070074220bc7387aadfdd9f0fe267158d74835c5f9c5c
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.