ETH Price: $2,604.21 (+0.54%)
Gas: 4.78 Gwei

Token

Crypto stamp Edition 3.1 (CS3.1)
 

Overview

Max Total Supply

140,000 CS3.1

Holders

48

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 CS3.1
0x1Cd00e043275Fa3D6d4F29b6a5e426f967eAb307
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:
Cryptostamp3_1L1

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-10-12
*/

/*
 * Crypto stamp 3.1 (Layer 1)
 * digital-physical collectible postage stamp
 *
 * Developed by Capacity Blockchain Solutions GmbH <capacity.at>
 * for Österreichische Post AG <post.at>
 *
 * Any usage of or interaction with this set of contracts is subject to the
 * Terms & Conditions available at https://crypto.post.at/
 */

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol

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

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

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

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

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol

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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol

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

// File: @openzeppelin/contracts/utils/Address.sol

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

        (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");

        (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");

        (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");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/utils/Context.sol

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

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

// File: @openzeppelin/contracts/utils/Strings.sol

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

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

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

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

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol

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

// File: contracts/ERC721NME.sol

/*
 * This is a strict copy of OpenZeppelin 4.0.0 ERC721.sol,
 * with ONE major modification: No event is emitted for minting.
 * In addition, some adjustments are made which versions of ownerOf() and
 * _exists() are called in the mint and approval processes.
 * This "No Mint Event" (NME) version is used for a special case where
 * the event for minting is emitted in a different place
 */

/**
 * @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 ERC721NME 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 = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || ERC721NME.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 = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || ERC721NME.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(!ERC721NME._exists(tokenId), "ERC721: token already minted");

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

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

        //emit Transfer(address(0), to, tokenId); NOTE: Needs to be emitted elsewhere!
    }

    /**
     * @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 = ERC721NME.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(ERC721NME.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(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 { }
}

// File: contracts/ERC721NME_EnumerableSimple.sol

/*
 * This is a simplified (and cheaper) version of OpenZeppelin's ERC721Enumerable.
 * NOTE: Instead of standard ERC721, this bases on the "NME" version.
 * ERC721Enumerable's allTokens array and allTokensIndex mapping are eliminated.
 * Side effects: _burn cannot be used any more with this, and creation needs to be
 * in ascending order, starting with 0, and have no holes in the sequence of IDs.
 */

/**
 * @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 ERC721NME_EnumerableSimple is ERC721NME, 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;

    uint256 internal totalSupply_;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721NME) 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 < ERC721NME.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 totalSupply_;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < totalSupply(), "Index is out of bounds.");
        return 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 = ERC721NME.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 {
        totalSupply_++;
    }

    /**
     * @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 = ERC721NME.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 is not possible with this variant.
     * param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 /*tokenId*/) private pure {
        revert("This token cannot be burned.");
    }
}

// File: contracts/ERC721MintableI.sol

/*
 * Interfaces for mintable ERC721 compliant contracts.
 */

/**
 * @dev ERC721 compliant contract with a safeMint() function.
 */
interface ERC721MintableI is IERC721 {

    /**
     * @dev Function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function safeMint(address to, uint256 tokenId) external;

}

/**
 * @dev ERC721 compliant contract with a safeMintWithData() function.
 */
interface ERC721DataMintableI is IERC721 {

    /**
     * @dev Function to safely mint a new token with data.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     * @param propdata bytes data to be used for token proerties
     */
    function safeMintWithData(address to, uint256 tokenId, bytes memory propdata) external;

}

/**
 * @dev ERC721 compliant contract with a setPropertiesFromData() function.
 */
interface ERC721SettablePropertiesI is IERC721 {

    /**
     * @dev Function to set properties from data for a token.
     * Reverts if the given token ID does not exist.
     * @param tokenId uint256 ID of the token to be set properties for
     * @param propdata bytes data to be used for token proerties
     */
    function setPropertiesFromData(uint256 tokenId, bytes memory propdata) external;

}

// File: contracts/ENSReverseRegistrarI.sol

/*
 * Interfaces for ENS Reverse Registrar
 * See https://github.com/ensdomains/ens/blob/master/contracts/ReverseRegistrar.sol for full impl
 * Also see https://github.com/wealdtech/wealdtech-solidity/blob/master/contracts/ens/ENSReverseRegister.sol
 *
 * Use this as follows (registryAddress is the address of the ENS registry to use):
 * -----
 * // This hex value is caclulated by namehash('addr.reverse')
 * bytes32 public constant ENS_ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
 * function registerReverseENS(address registryAddress, string memory calldata) external {
 *     require(registryAddress != address(0), "need a valid registry");
 *     address reverseRegistrarAddress = ENSRegistryOwnerI(registryAddress).owner(ENS_ADDR_REVERSE_NODE)
 *     require(reverseRegistrarAddress != address(0), "need a valid reverse registrar");
 *     ENSReverseRegistrarI(reverseRegistrarAddress).setName(name);
 * }
 * -----
 * or
 * -----
 * function registerReverseENS(address reverseRegistrarAddress, string memory calldata) external {
 *    require(reverseRegistrarAddress != address(0), "need a valid reverse registrar");
 *     ENSReverseRegistrarI(reverseRegistrarAddress).setName(name);
 * }
 * -----
 * ENS deployments can be found at https://docs.ens.domains/ens-deployments
 * E.g. Etherscan can be used to look up that owner on those contracts.
 * namehash.hash("addr.reverse") == "0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2"
 * Ropsten: ens.owner(namehash.hash("addr.reverse")) == "0x6F628b68b30Dc3c17f345c9dbBb1E483c2b7aE5c"
 * Mainnet: ens.owner(namehash.hash("addr.reverse")) == "0x084b1c3C81545d370f3634392De611CaaBFf8148"
 */

interface ENSRegistryOwnerI {
    function owner(bytes32 node) external view returns (address);
}

interface ENSReverseRegistrarI {
    event NameChanged(bytes32 indexed node, string name);
    /**
     * @dev Sets the `name()` record for the reverse ENS record associated with
     * the calling account.
     * @param name The name to set for this address.
     * @return The ENS node hash of the reverse record.
     */
    function setName(string calldata name) external returns (bytes32);
}

// File: contracts/BridgeDataI.sol

/*
 * Interface for data storage of the bridge.
 */

interface BridgeDataI {

    event AddressChanged(string name, address previousAddress, address newAddress);
    event ConnectedChainChanged(string previousConnectedChainName, string newConnectedChainName);
    event TokenURIBaseChanged(string previousTokenURIBase, string newTokenURIBase);
    event TokenSunsetAnnounced(uint256 indexed timestamp);

    /**
     * @dev The name of the chain connected to / on the other side of this bridge head.
     */
    function connectedChainName() external view returns (string memory);

    /**
     * @dev The name of our own chain, used in token URIs handed to deployed tokens.
     */
    function ownChainName() external view returns (string memory);

    /**
     * @dev The base of ALL token URIs, e.g. https://example.com/
     */
    function tokenURIBase() external view returns (string memory);

    /**
     * @dev The sunset timestamp for all deployed tokens.
     * If 0, no sunset is in place. Otherwise, if older than block timestamp,
     * all transfers of the tokens are frozen.
     */
    function tokenSunsetTimestamp() external view returns (uint256);

    /**
     * @dev Set a token sunset timestamp.
     */
    function setTokenSunsetTimestamp(uint256 _timestamp) external;

    /**
     * @dev Set an address for a name.
     */
    function setAddress(string memory name, address newAddress) external;

    /**
     * @dev Get an address for a name.
     */
    function getAddress(string memory name) external view returns (address);
}

// File: contracts/CS3_1PropertiesI.sol

/*
 * Interface for CS3.1 properties.
 */

interface CS3_1PropertiesI {

    enum AssetType {
        Rhino,
        Kitty
    }

    enum SColors {
        Sleeping,
        Black,
        Green,
        Blue,
        Yellow,
        Red
    }

    function getType(uint256 tokenId) external view returns (AssetType);
    function getSColor(uint256 tokenId) external view returns (SColors);

}

// File: contracts/Cryptostamp3_1L1.sol

/*
 * Implements ERC 721 NFT standard: https://github.com/ethereum/EIPs/issues/721.
 */

contract Cryptostamp3_1L1 is ERC721NME_EnumerableSimple, CS3_1PropertiesI, ERC721SettablePropertiesI {

    BridgeDataI public bridgeData;

    uint256 immutable finalSupply;
    uint256 immutable type1Supply;
    uint256 immutable type2Supply;
    uint256 constant maxSupportedSupply = 2 ** 24;
    uint256 public nextToVirtuallyMint;
    uint8[maxSupportedSupply] private properties;

    mapping(address => uint256) public signedTransferNonce;

    event BridgeDataChanged(address indexed previousBridgeData, address indexed newBridgeData);
    event SignedTransfer(address operator, address indexed from, address indexed to, uint256 indexed tokenId, uint256 signedTransferNonce);

    constructor(address _bridgeDataAddress, uint256 _finalSupply, uint256[2] memory _typeSupplies)
    ERC721NME("Crypto stamp Edition 3.1", "CS3.1")
    {
        bridgeData = BridgeDataI(_bridgeDataAddress);
        require(address(bridgeData) != address(0x0), "You need to provide an actual bridge data contract.");
        require(_finalSupply <= maxSupportedSupply, "The final supply is too high.");
        finalSupply = _finalSupply;
        require(_finalSupply == _typeSupplies[0] + _typeSupplies[1], "Final supply needs to match the type supplies.");
        type1Supply = _typeSupplies[0];
        type2Supply = _typeSupplies[1];
    }

    modifier onlyCreateControl() {
        require(msg.sender == bridgeData.getAddress("createControl"), "createControl key required for this function.");
        _;
    }

    modifier onlyCreateControlOrBridgeHead() {
        require(msg.sender == bridgeData.getAddress("createControl") || msg.sender == bridgeData.getAddress("bridgeHead"), "createControl key or bridge head required for this function.");
        _;
    }

    modifier onlyBridgeControl() {
        require(msg.sender == bridgeData.getAddress("bridgeControl"), "bridgeControl key required for this function.");
        _;
    }

    modifier onlyTokenAssignmentControl() {
        require(msg.sender == bridgeData.getAddress("tokenAssignmentControl"), "tokenAssignmentControl key required for this function.");
        _;
    }

    modifier requireTransferEnabled() {
        require(transferEnabled() == true, "This call only works when transfers are enabled.");
        _;
    }

    /*** Enable adjusting variables after deployment ***/

    function setBridgeData(BridgeDataI _newBridgeData)
    external
    onlyBridgeControl
    {
        require(address(_newBridgeData) != address(0x0), "You need to provide an actual bridge data contract.");
        emit BridgeDataChanged(address(bridgeData), address(_newBridgeData));
        bridgeData = _newBridgeData;
    }

    // Return true if transfers are possible.
    // This can have additional conditions to just the sunset variable.
    function transferEnabled()
    public view
    returns (bool)
    {
        uint256 tokenSunsetTimestamp = bridgeData.tokenSunsetTimestamp();
        // solhint-disable-next-line not-rely-on-time
        return (tokenSunsetTimestamp == 0 || tokenSunsetTimestamp > block.timestamp);
    }

    /*** Base functionality: minting, URI, property getters, etc. ***/

    // This just emits the events for minting a series of NFTs.
    function virtualMintSeries(uint256 _startId, uint256 _count, bool checkForExisting)
    public
    onlyCreateControl
    {
        require(_startId >= nextToVirtuallyMint, "Starting ID is already minted.");
        address tokenHolder = bridgeData.getAddress("tokenHolder");
        uint256 endId = _startId + _count;
        require(endId <= finalSupply, "Cannot send mint events for non-existing token IDs.");
        for (uint256 i = _startId; i < endId; i++) {
            // If this has not been actually transferred yet, we emit the mint event.
            if (!checkForExisting || !ERC721NME._exists(i)) {
                emit Transfer(address(0), tokenHolder, i);
            }
        }
        nextToVirtuallyMint = endId;
    }

    function setPropertiesFromData(uint256 _tokenId, bytes calldata _propdata)
    public override
    onlyCreateControlOrBridgeHead
    {
        require(ownerOf(_tokenId) == bridgeData.getAddress("tokenHolder"), "Only can set properties for tokens owned by the tokenHolder");
        properties[_tokenId] = uint8(_propdata[0]);
    }

    // Get type of the given token.
    function getType(uint256 _tokenId)
    public view override
    returns (AssetType)
    {
        require(_exists(_tokenId), "Token ID needs to exist.");
        if (_tokenId < type1Supply) {
            return AssetType.Rhino;
        }
        return AssetType.Kitty;
    }

    // Get color of the given token.
    function getSColor(uint256 _tokenId)
    public view override
    returns (SColors) {
        require(_exists(_tokenId), "Token ID needs to exist.");
        return SColors(properties[_tokenId]);
    }

    function baseURI() public view returns (string memory) {
        return _baseURI();
    }
    function _baseURI() internal view override returns (string memory) {
        return string(abi.encodePacked(bridgeData.tokenURIBase(), symbol(), "/meta/"));
    }

    // Returns whether the specified token exists
    function exists(uint256 _tokenId)
    public view
    returns (bool)
    {
        return _exists(_tokenId);
    }
    function _exists(uint256 _tokenId)
    internal view override
    returns (bool)
    {
        return _tokenId < finalSupply;
    }

    /*** Override internal functionality for special rules on approvals and transfers ***/

    // When the bridge is sunset, all token actions will be blocked.
    function _beforeTokenTransfer(address _from, address _to, uint256 _tokenId)
    internal override
    requireTransferEnabled
    {
        super._beforeTokenTransfer(_from, _to, _tokenId);
    }

    // If the token was only virtually minted, we need to "magically" mint instead of transfer.
    function _transfer(address _from, address _to, uint256 _tokenId)
    internal override
    {
        if (!ERC721NME._exists(_tokenId) && _from == bridgeData.getAddress("tokenHolder") && _isApprovedOrOwner(msg.sender, _tokenId)) {
            // Clear approvals from the previous owner
            _approve(address(0), _tokenId);
            // The _mint() function does NOT emit an event in the "MNE" implementation!
            // We then emit the event for an actual transfer, the mint event
            // either has been sent via virtualMintSeries() beforehand, or
            // otherwise, we manually emit it here.
            _mint(_to, _tokenId);
            if (_tokenId >= nextToVirtuallyMint) {
                emit Transfer(address(0), _from, _tokenId);
            }
            emit Transfer(_from, _to, _tokenId);
        }
        else {
            super._transfer(_from, _to, _tokenId);
        }
    }

    function balanceOf(address _owner)
    public view override(ERC721NME, IERC721)
    returns (uint256)
    {
        if (_owner == bridgeData.getAddress("tokenHolder")) {
            // All "virtually minted" tokens plus all actually owned tokens
            return finalSupply - super.totalSupply() + super.balanceOf(_owner);
        }
        return super.balanceOf(_owner);
    }

    function ownerOf(uint256 _tokenId)
    public view override(ERC721NME, IERC721)
    returns (address)
    {
        if (_exists(_tokenId) && !ERC721NME._exists(_tokenId)) {
            // valid token ID but not actually minted
            return bridgeData.getAddress("tokenHolder");
        }
        return super.ownerOf(_tokenId);
    }

    // Override totalSupply() so it reports the target final supply.
    /**
     * @dev Gets the total amount of tokens stored by the contract.
     * @return uint256 representing the total amount of tokens
     */
    function totalSupply()
    public view override
    returns (uint256) {
        return finalSupply;
    }

    function tokenOfOwnerByIndex(address _owner, uint256 _index)
    public view virtual override
    returns (uint256)
    {
        if (_index >= ERC721NME.balanceOf(_owner) && _owner == bridgeData.getAddress("tokenHolder")) {
            // We only get here if the requested token is not minted in storage.
            // As we have no records of such tokens, we need to loop through
            // all tokens from zero, until we have found enough tokens not
            // minted in storage to match the index, and take the non-minted
            // one at that position.
            require(_index < balanceOf(_owner), "ERC721Enumerable: owner index out of bounds");
            uint256 testIndex = ERC721NME.balanceOf(_owner);
            uint256 tokenId = 0;
            do {
                if (!ERC721NME._exists(tokenId)) {
                    if (testIndex >= _index) {
                        // We have found a non-minted token at the right index!
                        break;
                    }
                    testIndex++;
                }
                tokenId++;
            } while (tokenId < finalSupply); // Condition is never actually met.
            return tokenId;
        }
        return super.tokenOfOwnerByIndex(_owner, _index);
    }

    /*** Allows any user to initiate a transfer with the signature of the current stamp owner  ***/

    // Outward-facing function for signed transfer: assembles the expected data and then calls the internal function to do the rest.
    // Can called by anyone knowing about the right signature, but can only transfer to the given specific target.
    function signedTransfer(uint256 _tokenId, address _to, bytes memory _signature)
    public
    requireTransferEnabled
    {
        address currentOwner = ownerOf(_tokenId);
        // The signed data contains the token ID, the transfer target and a nonce.
        bytes32 data = keccak256(abi.encodePacked(address(this), this.signedTransfer.selector, currentOwner, _to, _tokenId, signedTransferNonce[currentOwner]));
        _signedTransferInternal(currentOwner, data, _tokenId, _to, _signature);
    }

    // Outward-facing function for operator-driven signed transfer: assembles the expected data and then calls the internal function to do the rest.
    // Can transfer to any target, but only be called by the trusted operator contained in the signature.
    function signedTransferWithOperator(uint256 _tokenId, address _to, bytes memory _signature)
    public
    requireTransferEnabled
    {
        address currentOwner = ownerOf(_tokenId);
        // The signed data contains the operator, the token ID, and a nonce. Note that we use the selector of the external function here!
        bytes32 data = keccak256(abi.encodePacked(address(this), this.signedTransferWithOperator.selector, msg.sender, currentOwner, _tokenId, signedTransferNonce[currentOwner]));
        _signedTransferInternal(currentOwner, data, _tokenId, _to, _signature);
    }

    // Actually check the signature and perform a signed transfer.
    function _signedTransferInternal(address _currentOwner, bytes32 _data, uint256 _tokenId, address _to, bytes memory _signature)
    internal
    {
        bytes32 hash = ECDSA.toEthSignedMessageHash(_data);
        address signer = ECDSA.recover(hash, _signature);
        require(signer == _currentOwner, "Signature needs to match parameters, nonce, and current owner.");
        // Now that we checked that the signature is correct, do the actual transfer and increase the nonce.
        emit SignedTransfer(msg.sender, _currentOwner, _to, _tokenId, signedTransferNonce[_currentOwner]);
        signedTransferNonce[_currentOwner]++;
        _safeTransfer(_currentOwner, _to, _tokenId, "");
    }

    /*** Enable reverse ENS registration ***/

    // Call this with the address of the reverse registrar for the respective network and the ENS name to register.
    // The reverse registrar can be found as the owner of 'addr.reverse' in the ENS system.
    // For Mainnet, the address needed is 0x9062c0a6dbd6108336bcbe4593a3d1ce05512069
    function registerReverseENS(address _reverseRegistrarAddress, string calldata _name)
    external
    onlyTokenAssignmentControl
    {
        require(_reverseRegistrarAddress != address(0), "need a valid reverse registrar");
        ENSReverseRegistrarI(_reverseRegistrarAddress).setName(_name);
    }

    /*** Make sure currency or NFT doesn't get stranded in this contract ***/

    // If this contract gets a balance in some ERC20 contract after it's finished, then we can rescue it.
    function rescueToken(IERC20 _foreignToken, address _to)
    external
    onlyTokenAssignmentControl
    {
        _foreignToken.transfer(_to, _foreignToken.balanceOf(address(this)));
    }

    // If this contract gets a balance in some ERC721 contract after it's finished, then we can rescue it.
    function approveNFTrescue(IERC721 _foreignNFT, address _to)
    external
    onlyTokenAssignmentControl
    {
        _foreignNFT.setApprovalForAll(_to, true);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_bridgeDataAddress","type":"address"},{"internalType":"uint256","name":"_finalSupply","type":"uint256"},{"internalType":"uint256[2]","name":"_typeSupplies","type":"uint256[2]"}],"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":"previousBridgeData","type":"address"},{"indexed":true,"internalType":"address","name":"newBridgeData","type":"address"}],"name":"BridgeDataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"signedTransferNonce","type":"uint256"}],"name":"SignedTransfer","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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"_foreignNFT","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"approveNFTrescue","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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgeData","outputs":[{"internalType":"contract BridgeDataI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"getSColor","outputs":[{"internalType":"enum CS3_1PropertiesI.SColors","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getType","outputs":[{"internalType":"enum CS3_1PropertiesI.AssetType","name":"","type":"uint8"}],"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":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextToVirtuallyMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reverseRegistrarAddress","type":"address"},{"internalType":"string","name":"_name","type":"string"}],"name":"registerReverseENS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_foreignToken","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"rescueToken","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":"contract BridgeDataI","name":"_newBridgeData","type":"address"}],"name":"setBridgeData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_propdata","type":"bytes"}],"name":"setPropertiesFromData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"signedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"signedTransferNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"signedTransferWithOperator","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":[],"name":"transferEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256","name":"_startId","type":"uint256"},{"internalType":"uint256","name":"_count","type":"uint256"},{"internalType":"bool","name":"checkForExisting","type":"bool"}],"name":"virtualMintSeries","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e06040523480156200001157600080fd5b5060405162003c0938038062003c098339810160408190526200003491620002ee565b604080518082018252601881527f43727970746f207374616d702045646974696f6e20332e3100000000000000006020808301918252835180850190945260058452644353332e3160d81b908401528151919291620000969160009162000232565b508051620000ac90600190602084019062000232565b5050600980546001600160a01b0319166001600160a01b03861690811790915515159050620001485760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527f69646765206461746120636f6e74726163742e0000000000000000000000000060648201526084015b60405180910390fd5b63010000008211156200019e5760405162461bcd60e51b815260206004820152601d60248201527f5468652066696e616c20737570706c7920697320746f6f20686967682e00000060448201526064016200013f565b608082905260208101518151620001b69190620003a0565b82146200021d5760405162461bcd60e51b815260206004820152602e60248201527f46696e616c20737570706c79206e6565647320746f206d61746368207468652060448201526d3a3cb8329039bab8383634b2b99760911b60648201526084016200013f565b805160a0526020015160c05250620004049050565b8280546200024090620003c7565b90600052602060002090601f016020900481019282620002645760008555620002af565b82601f106200027f57805160ff1916838001178555620002af565b82800160010185558215620002af579182015b82811115620002af57825182559160200191906001019062000292565b50620002bd929150620002c1565b5090565b5b80821115620002bd5760008155600101620002c2565b634e487b7160e01b600052604160045260246000fd5b6000806000608084860312156200030457600080fd5b83516001600160a01b03811681146200031c57600080fd5b80935050602080850151925085605f8601126200033857600080fd5b604080519081016001600160401b03811182821017156200035d576200035d620002d8565b6040528060808701888111156200037357600080fd5b604088015b8181101562000391578051835291840191840162000378565b50505080925050509250925092565b60008219821115620003c257634e487b7160e01b600052601160045260246000fd5b500190565b600181811c90821680620003dc57607f821691505b60208210811415620003fe57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05161378b6200047e600039600050506000610aa70152600081816102870152818161058f015281816109440152818161098c01528181610a3b01528181610d4a01528181610d7101528181610fc701528181611150015281816117c701528181611baf0152611f0c015261378b6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806353a1397c1161010f5780638f22332f116100a2578063c87b56dd11610071578063c87b56dd14610455578063dd48f77414610468578063e985e9c51461047b578063f800809f146104b757600080fd5b80638f22332f1461041457806395d89b4114610427578063a22cb4651461042f578063b88d4fde1461044257600080fd5b806370a08231116100de57806370a08231146103d257806371f03793146103e55780637d695d5e146103f85780638e8fa11f1461040157600080fd5b806353a1397c1461038257806353cdef02146103a45780636352211e146103b75780636c0360eb146103ca57600080fd5b80632f745c59116101875780634707d000116101565780634707d000146103415780634cd412d5146103545780634f558e791461035c5780634f6ccce71461036f57600080fd5b80632f745c59146102db57806333c186fd146102ee5780634036ab781461030e57806342842e0e1461032e57600080fd5b80630f574625116101c35780630f5746251461027257806318160ddd1461028557806323b872dd146102b55780632481bb5c146102c857600080fd5b806301ffc9a7146101f557806306fdde031461021d578063081812fc14610232578063095ea7b31461025d575b600080fd5b610208610203366004612dc5565b6104ca565b60405190151581526020015b60405180910390f35b6102256104f5565b6040516102149190612e3a565b610245610240366004612e4d565b610587565b6040516001600160a01b039091168152602001610214565b61027061026b366004612e7b565b610634565b005b610270610280366004612f6c565b61074a565b7f00000000000000000000000000000000000000000000000000000000000000005b604051908152602001610214565b6102706102c3366004612fc5565b6107ea565b600954610245906001600160a01b031681565b6102a76102e9366004612e7b565b61081b565b6103016102fc366004612e4d565b610984565b604051610214919061301c565b61032161031c366004612e4d565b610a33565b6040516102149190613036565b61027061033c366004612fc5565b610add565b61027061034f36600461304a565b610af8565b610208610ca5565b61020861036a366004612e4d565b610d42565b6102a761037d366004612e4d565b610d6d565b6102a7610390366004613083565b6208000b6020526000908152604090205481565b6102706103b2366004613083565b610de2565b6102456103c5366004612e4d565b610fbf565b610225611097565b6102a76103e0366004613083565b6110a6565b6102706103f3366004612f6c565b611187565b6102a7600a5481565b61027061040f3660046130e2565b6111fb565b610270610422366004613137565b611385565b6102256116b9565b61027061043d366004613178565b6116c8565b6102706104503660046131a6565b61178d565b610225610463366004612e4d565b6117bf565b61027061047636600461304a565b6118a9565b61020861048936600461304a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6102706104c5366004613212565b6119bd565b60006001600160e01b0319821663780e9d6360e01b14806104ef57506104ef82611cad565b92915050565b6060600080546105049061324b565b80601f01602080910402602001604051908101604052809291908181526020018280546105309061324b565b801561057d5780601f106105525761010080835404028352916020019161057d565b820191906000526020600020905b81548152906001019060200180831161056057829003601f168201915b5050505050905090565b60006105b2827f00000000000000000000000000000000000000000000000000000000000000001190565b6106185760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061063f82610fbf565b9050806001600160a01b0316836001600160a01b031614156106ad5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161060f565b336001600160a01b03821614806106c957506106c98133610489565b61073b5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161060f565b6107458383611cfd565b505050565b610752610ca5565b15156001146107735760405162461bcd60e51b815260040161060f90613286565b600061077e84610fbf565b6001600160a01b03811660009081526208000b6020908152604080832054905193945091926107be923092630f57462560e01b92339288928c92016132d6565b6040516020818303038152906040528051906020012090506107e38282878787611d6b565b5050505050565b6107f43382611f04565b6108105760405162461bcd60e51b815260040161060f90613326565b61074583838361200e565b60006108268361215b565b82101580156108c3575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061085e90600401613377565b60206040518083038186803b15801561087657600080fd5b505afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae919061339c565b6001600160a01b0316836001600160a01b0316145b15610973576108d1836110a6565b82106108ef5760405162461bcd60e51b815260040161060f906133b9565b60006108fa8461215b565b905060005b6000818152600260205260409020546001600160a01b0316610935578382106109275761096a565b816109318161341a565b9250505b8061093f8161341a565b9150507f000000000000000000000000000000000000000000000000000000000000000081106108ff575b91506104ef9050565b61097d83836121e2565b9392505050565b60006109af827f00000000000000000000000000000000000000000000000000000000000000001190565b6109f65760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b604482015260640161060f565b600b8263010000008110610a0c57610a0c613435565b602081049091015460ff601f9092166101000a90041660058111156104ef576104ef613006565b6000610a5e827f00000000000000000000000000000000000000000000000000000000000000001190565b610aa55760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b604482015260640161060f565b7f0000000000000000000000000000000000000000000000000000000000000000821015610ad557506000919050565b506001919050565b6107458383836040518060200160405280600081525061178d565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610b269060040161344b565b60206040518083038186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b76919061339c565b6001600160a01b0316336001600160a01b031614610ba65760405162461bcd60e51b815260040161060f9061347b565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610bef57600080fd5b505afa158015610c03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2791906134d1565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610c6d57600080fd5b505af1158015610c81573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074591906134ea565b600080600960009054906101000a90046001600160a01b03166001600160a01b031663a564a2e06040518163ffffffff1660e01b815260040160206040518083038186803b158015610cf657600080fd5b505afa158015610d0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2e91906134d1565b9050801580610d3c57504281115b91505090565b60006104ef827f00000000000000000000000000000000000000000000000000000000000000001190565b60007f00000000000000000000000000000000000000000000000000000000000000008210610dde5760405162461bcd60e51b815260206004820152601760248201527f496e646578206973206f7574206f6620626f756e64732e000000000000000000604482015260640161060f565b5090565b60095460405163bf40fac160e01b815260206004820152600d60248201526c189c9a5919d950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b158015610e4357600080fd5b505afa158015610e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7b919061339c565b6001600160a01b0316336001600160a01b031614610ef15760405162461bcd60e51b815260206004820152602d60248201527f627269646765436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b606482015260840161060f565b6001600160a01b038116610f635760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527234b233b2903230ba309031b7b73a3930b1ba1760691b606482015260840161060f565b6009546040516001600160a01b038084169216907f6a6e057f21cc834cf349d8150e92867f52cb34d54375f174c09c431538c3dfb990600090a3600980546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fea827f00000000000000000000000000000000000000000000000000000000000000001190565b801561100b57506000828152600260205260409020546001600160a01b0316155b1561108e5760095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061103e90600401613377565b60206040518083038186803b15801561105657600080fd5b505afa15801561106a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ef919061339c565b6104ef82612234565b60606110a16122ab565b905090565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac1906110d590600401613377565b60206040518083038186803b1580156110ed57600080fd5b505afa158015611101573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611125919061339c565b6001600160a01b0316826001600160a01b0316141561117e576111478261215b565b600854611174907f0000000000000000000000000000000000000000000000000000000000000000613507565b6104ef919061351e565b6104ef8261215b565b61118f610ca5565b15156001146111b05760405162461bcd60e51b815260040161060f90613286565b60006111bb84610fbf565b6001600160a01b03811660009081526208000b6020908152604080832054905193945091926107be9230926371f0379360e01b9287928a928c92016132d6565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906112299060040161344b565b60206040518083038186803b15801561124157600080fd5b505afa158015611255573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611279919061339c565b6001600160a01b0316336001600160a01b0316146112a95760405162461bcd60e51b815260040161060f9061347b565b6001600160a01b0383166112ff5760405162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c69642072657665727365207265676973747261720000604482015260640161060f565b60405163c47f002760e01b81526001600160a01b0384169063c47f00279061132d9085908590600401613536565b602060405180830381600087803b15801561134757600080fd5b505af115801561135b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137f91906134d1565b50505050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b1580156113e657600080fd5b505afa1580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e919061339c565b6001600160a01b0316336001600160a01b031614806114e3575060095460405163bf40fac160e01b815260206004820152600a602482015269189c9a5919d95219585960b21b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b15801561149657600080fd5b505afa1580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce919061339c565b6001600160a01b0316336001600160a01b0316145b6115555760405162461bcd60e51b815260206004820152603c60248201527f637265617465436f6e74726f6c206b6579206f7220627269646765206865616460448201527f20726571756972656420666f7220746869732066756e6374696f6e2e00000000606482015260840161060f565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061158390600401613377565b60206040518083038186803b15801561159b57600080fd5b505afa1580156115af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d3919061339c565b6001600160a01b03166115e584610fbf565b6001600160a01b0316146116615760405162461bcd60e51b815260206004820152603b60248201527f4f6e6c792063616e207365742070726f7065727469657320666f7220746f6b6560448201527f6e73206f776e65642062792074686520746f6b656e486f6c6465720000000000606482015260840161060f565b8181600081811061167457611674613435565b919091013560f81c9050600b846301000000811061169457611694613435565b602091828204019190066101000a81548160ff021916908360ff160217905550505050565b6060600180546105049061324b565b6001600160a01b0382163314156117215760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161060f565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6117973383611f04565b6117b35760405162461bcd60e51b815260040161060f90613326565b61137f84848484612359565b60606117ea827f00000000000000000000000000000000000000000000000000000000000000001190565b61184e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161060f565b60006118586122ab565b90506000815111611878576040518060200160405280600081525061097d565b806118828461238c565b604051602001611893929190613565565b6040516020818303038152906040529392505050565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906118d79060040161344b565b60206040518083038186803b1580156118ef57600080fd5b505afa158015611903573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611927919061339c565b6001600160a01b0316336001600160a01b0316146119575760405162461bcd60e51b815260040161060f9061347b565b60405163a22cb46560e01b81526001600160a01b0382811660048301526001602483015283169063a22cb46590604401600060405180830381600087803b1580156119a157600080fd5b505af11580156119b5573d6000803e3d6000fd5b505050505050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b158015611a1e57600080fd5b505afa158015611a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a56919061339c565b6001600160a01b0316336001600160a01b031614611acc5760405162461bcd60e51b815260206004820152602d60248201527f637265617465436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b606482015260840161060f565b600a54831015611b1e5760405162461bcd60e51b815260206004820152601e60248201527f5374617274696e6720494420697320616c7265616479206d696e7465642e0000604482015260640161060f565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac190611b4d90600401613377565b60206040518083038186803b158015611b6557600080fd5b505afa158015611b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9d919061339c565b90506000611bab848661351e565b90507f0000000000000000000000000000000000000000000000000000000000000000811115611c395760405162461bcd60e51b815260206004820152603360248201527f43616e6e6f742073656e64206d696e74206576656e747320666f72206e6f6e2d60448201527232bc34b9ba34b733903a37b5b2b71024a2399760691b606482015260840161060f565b845b81811015611ca357831580611c6557506000818152600260205260409020546001600160a01b0316155b15611c915760405181906001600160a01b03851690600090600080516020613736833981519152908290a45b80611c9b8161341a565b915050611c3b565b50600a5550505050565b60006001600160e01b031982166380ac58cd60e01b1480611cde57506001600160e01b03198216635b5e139f60e01b145b806104ef57506301ffc9a760e01b6001600160e01b03198316146104ef565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d3282610fbf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611dc4856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000611dd2828461248a565b9050866001600160a01b0316816001600160a01b031614611e5b5760405162461bcd60e51b815260206004820152603e60248201527f5369676e6174757265206e6565647320746f206d6174636820706172616d657460448201527f6572732c206e6f6e63652c20616e642063757272656e74206f776e65722e0000606482015260840161060f565b6001600160a01b0387811660008181526208000b6020908152604091829020548251338152918201528893881692917fba05f551fcc429cba611372aa0055e3573f26273f66d1a48bdb5b4f7896bf022910160405180910390a46001600160a01b03871660009081526208000b60205260408120805491611edb8361341a565b9190505550611efb87858760405180602001604052806000815250612359565b50505050505050565b6000611f2f827f00000000000000000000000000000000000000000000000000000000000000001190565b611f905760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161060f565b6000611f9b83610fbf565b9050806001600160a01b0316846001600160a01b03161480611fd65750836001600160a01b0316611fcb84610587565b6001600160a01b0316145b8061200657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b6000818152600260205260409020546001600160a01b03161580156120c1575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061205c90600401613377565b60206040518083038186803b15801561207457600080fd5b505afa158015612088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ac919061339c565b6001600160a01b0316836001600160a01b0316145b80156120d257506120d23382611f04565b15612150576120e2600082611cfd565b6120ec82826124ae565b600a54811061211c5760405181906001600160a01b03851690600090600080516020613736833981519152908290a45b80826001600160a01b0316846001600160a01b031660008051602061373683398151915260405160405180910390a4505050565b6107458383836125d1565b60006001600160a01b0382166121c65760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161060f565b506001600160a01b031660009081526003602052604090205490565b60006121ed8361215b565b821061220b5760405162461bcd60e51b815260040161060f906133b9565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6000818152600260205260408120546001600160a01b0316806104ef5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161060f565b6009546040805163261220a360e01b815290516060926001600160a01b03169163261220a3916004808301926000929190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261232c9190810190613594565b6123346116b9565b60405160200161234592919061360b565b604051602081830303815290604052905090565b61236484848461200e565b6123708484848461276a565b61137f5760405162461bcd60e51b815260040161060f9061364b565b6060816123b05750506040805180820190915260018152600360fc1b602082015290565b8160005b81156123da57806123c48161341a565b91506123d39050600a836136b3565b91506123b4565b60008167ffffffffffffffff8111156123f5576123f5612ea7565b6040519080825280601f01601f19166020018201604052801561241f576020820181803683370190505b5090505b841561200657612434600183613507565b9150612441600a866136c7565b61244c90603061351e565b60f81b81838151811061246157612461613435565b60200101906001600160f81b031916908160001a905350612483600a866136b3565b9450612423565b60008060006124998585612877565b915091506124a6816128e7565b509392505050565b6001600160a01b0382166125045760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161060f565b6000818152600260205260409020546001600160a01b0316156125695760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161060f565b61257560008383612aa5565b6001600160a01b038216600090815260036020526040812080546001929061259e90849061351e565b9091555050600090815260026020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b826001600160a01b03166125e482612234565b6001600160a01b03161461264c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161060f565b6001600160a01b0382166126ae5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161060f565b6126b9838383612aa5565b6126c4600082611cfd565b6001600160a01b03831660009081526003602052604081208054600192906126ed908490613507565b90915550506001600160a01b038216600090815260036020526040812080546001929061271b90849061351e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03868116918217909255915184939187169160008051602061373683398151915291a4505050565b60006001600160a01b0384163b1561286c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906127ae9033908990889088906004016136db565b602060405180830381600087803b1580156127c857600080fd5b505af19250505080156127f8575060408051601f3d908101601f191682019092526127f591810190613718565b60015b612852573d808015612826576040519150601f19603f3d011682016040523d82523d6000602084013e61282b565b606091505b50805161284a5760405162461bcd60e51b815260040161060f9061364b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612006565b506001949350505050565b6000808251604114156128ae5760208301516040840151606085015160001a6128a287828585612ad9565b945094505050506128e0565b8251604014156128d857602083015160408401516128cd868383612bc6565b9350935050506128e0565b506000905060025b9250929050565b60008160048111156128fb576128fb613006565b14156129045750565b600181600481111561291857612918613006565b14156129665760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161060f565b600281600481111561297a5761297a613006565b14156129c85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161060f565b60038160048111156129dc576129dc613006565b1415612a355760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161060f565b6004816004811115612a4957612a49613006565b1415612aa25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161060f565b50565b612aad610ca5565b1515600114612ace5760405162461bcd60e51b815260040161060f90613286565b610745838383612bf5565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b105750600090506003612bbd565b8460ff16601b14158015612b2857508460ff16601c14155b15612b395750600090506004612bbd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612b8d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612bb657600060019250925050612bbd565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01612be787828885612ad9565b935093505050935093915050565b6001600160a01b038316612c1157612c0c81612c6e565b612c34565b816001600160a01b0316836001600160a01b031614612c3457612c348382612c86565b6001600160a01b038216612c4b5761074581612d23565b826001600160a01b0316826001600160a01b031614610745576107458282612d6b565b60088054906000612c7e8361341a565b919050555050565b60006001612c938461215b565b612c9d9190613507565b600083815260076020526040902054909150808214612cf0576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60405162461bcd60e51b815260206004820152601c60248201527f5468697320746f6b656e2063616e6e6f74206265206275726e65642e00000000604482015260640161060f565b6000612d768361215b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b031981168114612aa257600080fd5b600060208284031215612dd757600080fd5b813561097d81612daf565b60005b83811015612dfd578181015183820152602001612de5565b8381111561137f5750506000910152565b60008151808452612e26816020860160208601612de2565b601f01601f19169290920160200192915050565b60208152600061097d6020830184612e0e565b600060208284031215612e5f57600080fd5b5035919050565b6001600160a01b0381168114612aa257600080fd5b60008060408385031215612e8e57600080fd5b8235612e9981612e66565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612ee657612ee6612ea7565b604052919050565b600067ffffffffffffffff821115612f0857612f08612ea7565b50601f01601f191660200190565b600082601f830112612f2757600080fd5b8135612f3a612f3582612eee565b612ebd565b818152846020838601011115612f4f57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600060608486031215612f8157600080fd5b833592506020840135612f9381612e66565b9150604084013567ffffffffffffffff811115612faf57600080fd5b612fbb86828701612f16565b9150509250925092565b600080600060608486031215612fda57600080fd5b8335612fe581612e66565b92506020840135612ff581612e66565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b602081016006831061303057613030613006565b91905290565b602081016002831061303057613030613006565b6000806040838503121561305d57600080fd5b823561306881612e66565b9150602083013561307881612e66565b809150509250929050565b60006020828403121561309557600080fd5b813561097d81612e66565b60008083601f8401126130b257600080fd5b50813567ffffffffffffffff8111156130ca57600080fd5b6020830191508360208285010111156128e057600080fd5b6000806000604084860312156130f757600080fd5b833561310281612e66565b9250602084013567ffffffffffffffff81111561311e57600080fd5b61312a868287016130a0565b9497909650939450505050565b60008060006040848603121561314c57600080fd5b83359250602084013567ffffffffffffffff81111561311e57600080fd5b8015158114612aa257600080fd5b6000806040838503121561318b57600080fd5b823561319681612e66565b915060208301356130788161316a565b600080600080608085870312156131bc57600080fd5b84356131c781612e66565b935060208501356131d781612e66565b925060408501359150606085013567ffffffffffffffff8111156131fa57600080fd5b61320687828801612f16565b91505092959194509250565b60008060006060848603121561322757600080fd5b833592506020840135915060408401356132408161316a565b809150509250925092565b600181811c9082168061325f57607f821691505b6020821081141561328057634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526030908201527f546869732063616c6c206f6e6c7920776f726b73207768656e207472616e736660408201526f32b9399030b9329032b730b13632b21760811b606082015260800190565b6bffffffffffffffffffffffff19606097881b811682526001600160e01b031996909616601482015293861b8516601885015291851b909316602c83015260408201929092529182015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252600b908201526a3a37b5b2b72437b63232b960a91b604082015260600190565b6000602082840312156133ae57600080fd5b815161097d81612e66565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060001982141561342e5761342e613404565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252601690820152751d1bdad95b905cdcda59db9b595b9d10dbdb9d1c9bdb60521b604082015260600190565b60208082526036908201527f746f6b656e41737369676e6d656e74436f6e74726f6c206b65792072657175696040820152753932b2103337b9103a3434b990333ab731ba34b7b71760511b606082015260800190565b6000602082840312156134e357600080fd5b5051919050565b6000602082840312156134fc57600080fd5b815161097d8161316a565b60008282101561351957613519613404565b500390565b6000821982111561353157613531613404565b500190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60008351613577818460208801612de2565b83519083019061358b818360208801612de2565b01949350505050565b6000602082840312156135a657600080fd5b815167ffffffffffffffff8111156135bd57600080fd5b8201601f810184136135ce57600080fd5b80516135dc612f3582612eee565b8181528560208385010111156135f157600080fd5b613602826020830160208601612de2565b95945050505050565b6000835161361d818460208801612de2565b835190830190613631818360208801612de2565b652f6d6574612f60d01b9101908152600601949350505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826136c2576136c261369d565b500490565b6000826136d6576136d661369d565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061370e90830184612e0e565b9695505050505050565b60006020828403121561372a57600080fd5b815161097d81612daf56feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212208c2fd9a319703610b04fbe47ca2159e76c0a429ecacb56498aba3fe139c0c07c64736f6c634300080900330000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c500000000000000000000000000000000000000000000000000000000000222e000000000000000000000000000000000000000000000000000000000000111700000000000000000000000000000000000000000000000000000000000011170

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806353a1397c1161010f5780638f22332f116100a2578063c87b56dd11610071578063c87b56dd14610455578063dd48f77414610468578063e985e9c51461047b578063f800809f146104b757600080fd5b80638f22332f1461041457806395d89b4114610427578063a22cb4651461042f578063b88d4fde1461044257600080fd5b806370a08231116100de57806370a08231146103d257806371f03793146103e55780637d695d5e146103f85780638e8fa11f1461040157600080fd5b806353a1397c1461038257806353cdef02146103a45780636352211e146103b75780636c0360eb146103ca57600080fd5b80632f745c59116101875780634707d000116101565780634707d000146103415780634cd412d5146103545780634f558e791461035c5780634f6ccce71461036f57600080fd5b80632f745c59146102db57806333c186fd146102ee5780634036ab781461030e57806342842e0e1461032e57600080fd5b80630f574625116101c35780630f5746251461027257806318160ddd1461028557806323b872dd146102b55780632481bb5c146102c857600080fd5b806301ffc9a7146101f557806306fdde031461021d578063081812fc14610232578063095ea7b31461025d575b600080fd5b610208610203366004612dc5565b6104ca565b60405190151581526020015b60405180910390f35b6102256104f5565b6040516102149190612e3a565b610245610240366004612e4d565b610587565b6040516001600160a01b039091168152602001610214565b61027061026b366004612e7b565b610634565b005b610270610280366004612f6c565b61074a565b7f00000000000000000000000000000000000000000000000000000000000222e05b604051908152602001610214565b6102706102c3366004612fc5565b6107ea565b600954610245906001600160a01b031681565b6102a76102e9366004612e7b565b61081b565b6103016102fc366004612e4d565b610984565b604051610214919061301c565b61032161031c366004612e4d565b610a33565b6040516102149190613036565b61027061033c366004612fc5565b610add565b61027061034f36600461304a565b610af8565b610208610ca5565b61020861036a366004612e4d565b610d42565b6102a761037d366004612e4d565b610d6d565b6102a7610390366004613083565b6208000b6020526000908152604090205481565b6102706103b2366004613083565b610de2565b6102456103c5366004612e4d565b610fbf565b610225611097565b6102a76103e0366004613083565b6110a6565b6102706103f3366004612f6c565b611187565b6102a7600a5481565b61027061040f3660046130e2565b6111fb565b610270610422366004613137565b611385565b6102256116b9565b61027061043d366004613178565b6116c8565b6102706104503660046131a6565b61178d565b610225610463366004612e4d565b6117bf565b61027061047636600461304a565b6118a9565b61020861048936600461304a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6102706104c5366004613212565b6119bd565b60006001600160e01b0319821663780e9d6360e01b14806104ef57506104ef82611cad565b92915050565b6060600080546105049061324b565b80601f01602080910402602001604051908101604052809291908181526020018280546105309061324b565b801561057d5780601f106105525761010080835404028352916020019161057d565b820191906000526020600020905b81548152906001019060200180831161056057829003601f168201915b5050505050905090565b60006105b2827f00000000000000000000000000000000000000000000000000000000000222e01190565b6106185760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061063f82610fbf565b9050806001600160a01b0316836001600160a01b031614156106ad5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161060f565b336001600160a01b03821614806106c957506106c98133610489565b61073b5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161060f565b6107458383611cfd565b505050565b610752610ca5565b15156001146107735760405162461bcd60e51b815260040161060f90613286565b600061077e84610fbf565b6001600160a01b03811660009081526208000b6020908152604080832054905193945091926107be923092630f57462560e01b92339288928c92016132d6565b6040516020818303038152906040528051906020012090506107e38282878787611d6b565b5050505050565b6107f43382611f04565b6108105760405162461bcd60e51b815260040161060f90613326565b61074583838361200e565b60006108268361215b565b82101580156108c3575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061085e90600401613377565b60206040518083038186803b15801561087657600080fd5b505afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae919061339c565b6001600160a01b0316836001600160a01b0316145b15610973576108d1836110a6565b82106108ef5760405162461bcd60e51b815260040161060f906133b9565b60006108fa8461215b565b905060005b6000818152600260205260409020546001600160a01b0316610935578382106109275761096a565b816109318161341a565b9250505b8061093f8161341a565b9150507f00000000000000000000000000000000000000000000000000000000000222e081106108ff575b91506104ef9050565b61097d83836121e2565b9392505050565b60006109af827f00000000000000000000000000000000000000000000000000000000000222e01190565b6109f65760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b604482015260640161060f565b600b8263010000008110610a0c57610a0c613435565b602081049091015460ff601f9092166101000a90041660058111156104ef576104ef613006565b6000610a5e827f00000000000000000000000000000000000000000000000000000000000222e01190565b610aa55760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b604482015260640161060f565b7f0000000000000000000000000000000000000000000000000000000000011170821015610ad557506000919050565b506001919050565b6107458383836040518060200160405280600081525061178d565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610b269060040161344b565b60206040518083038186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b76919061339c565b6001600160a01b0316336001600160a01b031614610ba65760405162461bcd60e51b815260040161060f9061347b565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610bef57600080fd5b505afa158015610c03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2791906134d1565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610c6d57600080fd5b505af1158015610c81573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074591906134ea565b600080600960009054906101000a90046001600160a01b03166001600160a01b031663a564a2e06040518163ffffffff1660e01b815260040160206040518083038186803b158015610cf657600080fd5b505afa158015610d0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2e91906134d1565b9050801580610d3c57504281115b91505090565b60006104ef827f00000000000000000000000000000000000000000000000000000000000222e01190565b60007f00000000000000000000000000000000000000000000000000000000000222e08210610dde5760405162461bcd60e51b815260206004820152601760248201527f496e646578206973206f7574206f6620626f756e64732e000000000000000000604482015260640161060f565b5090565b60095460405163bf40fac160e01b815260206004820152600d60248201526c189c9a5919d950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b158015610e4357600080fd5b505afa158015610e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7b919061339c565b6001600160a01b0316336001600160a01b031614610ef15760405162461bcd60e51b815260206004820152602d60248201527f627269646765436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b606482015260840161060f565b6001600160a01b038116610f635760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527234b233b2903230ba309031b7b73a3930b1ba1760691b606482015260840161060f565b6009546040516001600160a01b038084169216907f6a6e057f21cc834cf349d8150e92867f52cb34d54375f174c09c431538c3dfb990600090a3600980546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fea827f00000000000000000000000000000000000000000000000000000000000222e01190565b801561100b57506000828152600260205260409020546001600160a01b0316155b1561108e5760095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061103e90600401613377565b60206040518083038186803b15801561105657600080fd5b505afa15801561106a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ef919061339c565b6104ef82612234565b60606110a16122ab565b905090565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac1906110d590600401613377565b60206040518083038186803b1580156110ed57600080fd5b505afa158015611101573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611125919061339c565b6001600160a01b0316826001600160a01b0316141561117e576111478261215b565b600854611174907f00000000000000000000000000000000000000000000000000000000000222e0613507565b6104ef919061351e565b6104ef8261215b565b61118f610ca5565b15156001146111b05760405162461bcd60e51b815260040161060f90613286565b60006111bb84610fbf565b6001600160a01b03811660009081526208000b6020908152604080832054905193945091926107be9230926371f0379360e01b9287928a928c92016132d6565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906112299060040161344b565b60206040518083038186803b15801561124157600080fd5b505afa158015611255573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611279919061339c565b6001600160a01b0316336001600160a01b0316146112a95760405162461bcd60e51b815260040161060f9061347b565b6001600160a01b0383166112ff5760405162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c69642072657665727365207265676973747261720000604482015260640161060f565b60405163c47f002760e01b81526001600160a01b0384169063c47f00279061132d9085908590600401613536565b602060405180830381600087803b15801561134757600080fd5b505af115801561135b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137f91906134d1565b50505050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b1580156113e657600080fd5b505afa1580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e919061339c565b6001600160a01b0316336001600160a01b031614806114e3575060095460405163bf40fac160e01b815260206004820152600a602482015269189c9a5919d95219585960b21b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b15801561149657600080fd5b505afa1580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce919061339c565b6001600160a01b0316336001600160a01b0316145b6115555760405162461bcd60e51b815260206004820152603c60248201527f637265617465436f6e74726f6c206b6579206f7220627269646765206865616460448201527f20726571756972656420666f7220746869732066756e6374696f6e2e00000000606482015260840161060f565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061158390600401613377565b60206040518083038186803b15801561159b57600080fd5b505afa1580156115af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d3919061339c565b6001600160a01b03166115e584610fbf565b6001600160a01b0316146116615760405162461bcd60e51b815260206004820152603b60248201527f4f6e6c792063616e207365742070726f7065727469657320666f7220746f6b6560448201527f6e73206f776e65642062792074686520746f6b656e486f6c6465720000000000606482015260840161060f565b8181600081811061167457611674613435565b919091013560f81c9050600b846301000000811061169457611694613435565b602091828204019190066101000a81548160ff021916908360ff160217905550505050565b6060600180546105049061324b565b6001600160a01b0382163314156117215760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161060f565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6117973383611f04565b6117b35760405162461bcd60e51b815260040161060f90613326565b61137f84848484612359565b60606117ea827f00000000000000000000000000000000000000000000000000000000000222e01190565b61184e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161060f565b60006118586122ab565b90506000815111611878576040518060200160405280600081525061097d565b806118828461238c565b604051602001611893929190613565565b6040516020818303038152906040529392505050565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906118d79060040161344b565b60206040518083038186803b1580156118ef57600080fd5b505afa158015611903573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611927919061339c565b6001600160a01b0316336001600160a01b0316146119575760405162461bcd60e51b815260040161060f9061347b565b60405163a22cb46560e01b81526001600160a01b0382811660048301526001602483015283169063a22cb46590604401600060405180830381600087803b1580156119a157600080fd5b505af11580156119b5573d6000803e3d6000fd5b505050505050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b158015611a1e57600080fd5b505afa158015611a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a56919061339c565b6001600160a01b0316336001600160a01b031614611acc5760405162461bcd60e51b815260206004820152602d60248201527f637265617465436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b606482015260840161060f565b600a54831015611b1e5760405162461bcd60e51b815260206004820152601e60248201527f5374617274696e6720494420697320616c7265616479206d696e7465642e0000604482015260640161060f565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac190611b4d90600401613377565b60206040518083038186803b158015611b6557600080fd5b505afa158015611b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9d919061339c565b90506000611bab848661351e565b90507f00000000000000000000000000000000000000000000000000000000000222e0811115611c395760405162461bcd60e51b815260206004820152603360248201527f43616e6e6f742073656e64206d696e74206576656e747320666f72206e6f6e2d60448201527232bc34b9ba34b733903a37b5b2b71024a2399760691b606482015260840161060f565b845b81811015611ca357831580611c6557506000818152600260205260409020546001600160a01b0316155b15611c915760405181906001600160a01b03851690600090600080516020613736833981519152908290a45b80611c9b8161341a565b915050611c3b565b50600a5550505050565b60006001600160e01b031982166380ac58cd60e01b1480611cde57506001600160e01b03198216635b5e139f60e01b145b806104ef57506301ffc9a760e01b6001600160e01b03198316146104ef565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d3282610fbf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611dc4856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000611dd2828461248a565b9050866001600160a01b0316816001600160a01b031614611e5b5760405162461bcd60e51b815260206004820152603e60248201527f5369676e6174757265206e6565647320746f206d6174636820706172616d657460448201527f6572732c206e6f6e63652c20616e642063757272656e74206f776e65722e0000606482015260840161060f565b6001600160a01b0387811660008181526208000b6020908152604091829020548251338152918201528893881692917fba05f551fcc429cba611372aa0055e3573f26273f66d1a48bdb5b4f7896bf022910160405180910390a46001600160a01b03871660009081526208000b60205260408120805491611edb8361341a565b9190505550611efb87858760405180602001604052806000815250612359565b50505050505050565b6000611f2f827f00000000000000000000000000000000000000000000000000000000000222e01190565b611f905760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161060f565b6000611f9b83610fbf565b9050806001600160a01b0316846001600160a01b03161480611fd65750836001600160a01b0316611fcb84610587565b6001600160a01b0316145b8061200657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b6000818152600260205260409020546001600160a01b03161580156120c1575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061205c90600401613377565b60206040518083038186803b15801561207457600080fd5b505afa158015612088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ac919061339c565b6001600160a01b0316836001600160a01b0316145b80156120d257506120d23382611f04565b15612150576120e2600082611cfd565b6120ec82826124ae565b600a54811061211c5760405181906001600160a01b03851690600090600080516020613736833981519152908290a45b80826001600160a01b0316846001600160a01b031660008051602061373683398151915260405160405180910390a4505050565b6107458383836125d1565b60006001600160a01b0382166121c65760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161060f565b506001600160a01b031660009081526003602052604090205490565b60006121ed8361215b565b821061220b5760405162461bcd60e51b815260040161060f906133b9565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6000818152600260205260408120546001600160a01b0316806104ef5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161060f565b6009546040805163261220a360e01b815290516060926001600160a01b03169163261220a3916004808301926000929190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261232c9190810190613594565b6123346116b9565b60405160200161234592919061360b565b604051602081830303815290604052905090565b61236484848461200e565b6123708484848461276a565b61137f5760405162461bcd60e51b815260040161060f9061364b565b6060816123b05750506040805180820190915260018152600360fc1b602082015290565b8160005b81156123da57806123c48161341a565b91506123d39050600a836136b3565b91506123b4565b60008167ffffffffffffffff8111156123f5576123f5612ea7565b6040519080825280601f01601f19166020018201604052801561241f576020820181803683370190505b5090505b841561200657612434600183613507565b9150612441600a866136c7565b61244c90603061351e565b60f81b81838151811061246157612461613435565b60200101906001600160f81b031916908160001a905350612483600a866136b3565b9450612423565b60008060006124998585612877565b915091506124a6816128e7565b509392505050565b6001600160a01b0382166125045760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161060f565b6000818152600260205260409020546001600160a01b0316156125695760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161060f565b61257560008383612aa5565b6001600160a01b038216600090815260036020526040812080546001929061259e90849061351e565b9091555050600090815260026020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b826001600160a01b03166125e482612234565b6001600160a01b03161461264c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161060f565b6001600160a01b0382166126ae5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161060f565b6126b9838383612aa5565b6126c4600082611cfd565b6001600160a01b03831660009081526003602052604081208054600192906126ed908490613507565b90915550506001600160a01b038216600090815260036020526040812080546001929061271b90849061351e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03868116918217909255915184939187169160008051602061373683398151915291a4505050565b60006001600160a01b0384163b1561286c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906127ae9033908990889088906004016136db565b602060405180830381600087803b1580156127c857600080fd5b505af19250505080156127f8575060408051601f3d908101601f191682019092526127f591810190613718565b60015b612852573d808015612826576040519150601f19603f3d011682016040523d82523d6000602084013e61282b565b606091505b50805161284a5760405162461bcd60e51b815260040161060f9061364b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612006565b506001949350505050565b6000808251604114156128ae5760208301516040840151606085015160001a6128a287828585612ad9565b945094505050506128e0565b8251604014156128d857602083015160408401516128cd868383612bc6565b9350935050506128e0565b506000905060025b9250929050565b60008160048111156128fb576128fb613006565b14156129045750565b600181600481111561291857612918613006565b14156129665760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161060f565b600281600481111561297a5761297a613006565b14156129c85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161060f565b60038160048111156129dc576129dc613006565b1415612a355760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161060f565b6004816004811115612a4957612a49613006565b1415612aa25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161060f565b50565b612aad610ca5565b1515600114612ace5760405162461bcd60e51b815260040161060f90613286565b610745838383612bf5565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b105750600090506003612bbd565b8460ff16601b14158015612b2857508460ff16601c14155b15612b395750600090506004612bbd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612b8d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612bb657600060019250925050612bbd565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01612be787828885612ad9565b935093505050935093915050565b6001600160a01b038316612c1157612c0c81612c6e565b612c34565b816001600160a01b0316836001600160a01b031614612c3457612c348382612c86565b6001600160a01b038216612c4b5761074581612d23565b826001600160a01b0316826001600160a01b031614610745576107458282612d6b565b60088054906000612c7e8361341a565b919050555050565b60006001612c938461215b565b612c9d9190613507565b600083815260076020526040902054909150808214612cf0576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60405162461bcd60e51b815260206004820152601c60248201527f5468697320746f6b656e2063616e6e6f74206265206275726e65642e00000000604482015260640161060f565b6000612d768361215b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b031981168114612aa257600080fd5b600060208284031215612dd757600080fd5b813561097d81612daf565b60005b83811015612dfd578181015183820152602001612de5565b8381111561137f5750506000910152565b60008151808452612e26816020860160208601612de2565b601f01601f19169290920160200192915050565b60208152600061097d6020830184612e0e565b600060208284031215612e5f57600080fd5b5035919050565b6001600160a01b0381168114612aa257600080fd5b60008060408385031215612e8e57600080fd5b8235612e9981612e66565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612ee657612ee6612ea7565b604052919050565b600067ffffffffffffffff821115612f0857612f08612ea7565b50601f01601f191660200190565b600082601f830112612f2757600080fd5b8135612f3a612f3582612eee565b612ebd565b818152846020838601011115612f4f57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600060608486031215612f8157600080fd5b833592506020840135612f9381612e66565b9150604084013567ffffffffffffffff811115612faf57600080fd5b612fbb86828701612f16565b9150509250925092565b600080600060608486031215612fda57600080fd5b8335612fe581612e66565b92506020840135612ff581612e66565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b602081016006831061303057613030613006565b91905290565b602081016002831061303057613030613006565b6000806040838503121561305d57600080fd5b823561306881612e66565b9150602083013561307881612e66565b809150509250929050565b60006020828403121561309557600080fd5b813561097d81612e66565b60008083601f8401126130b257600080fd5b50813567ffffffffffffffff8111156130ca57600080fd5b6020830191508360208285010111156128e057600080fd5b6000806000604084860312156130f757600080fd5b833561310281612e66565b9250602084013567ffffffffffffffff81111561311e57600080fd5b61312a868287016130a0565b9497909650939450505050565b60008060006040848603121561314c57600080fd5b83359250602084013567ffffffffffffffff81111561311e57600080fd5b8015158114612aa257600080fd5b6000806040838503121561318b57600080fd5b823561319681612e66565b915060208301356130788161316a565b600080600080608085870312156131bc57600080fd5b84356131c781612e66565b935060208501356131d781612e66565b925060408501359150606085013567ffffffffffffffff8111156131fa57600080fd5b61320687828801612f16565b91505092959194509250565b60008060006060848603121561322757600080fd5b833592506020840135915060408401356132408161316a565b809150509250925092565b600181811c9082168061325f57607f821691505b6020821081141561328057634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526030908201527f546869732063616c6c206f6e6c7920776f726b73207768656e207472616e736660408201526f32b9399030b9329032b730b13632b21760811b606082015260800190565b6bffffffffffffffffffffffff19606097881b811682526001600160e01b031996909616601482015293861b8516601885015291851b909316602c83015260408201929092529182015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252600b908201526a3a37b5b2b72437b63232b960a91b604082015260600190565b6000602082840312156133ae57600080fd5b815161097d81612e66565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060001982141561342e5761342e613404565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252601690820152751d1bdad95b905cdcda59db9b595b9d10dbdb9d1c9bdb60521b604082015260600190565b60208082526036908201527f746f6b656e41737369676e6d656e74436f6e74726f6c206b65792072657175696040820152753932b2103337b9103a3434b990333ab731ba34b7b71760511b606082015260800190565b6000602082840312156134e357600080fd5b5051919050565b6000602082840312156134fc57600080fd5b815161097d8161316a565b60008282101561351957613519613404565b500390565b6000821982111561353157613531613404565b500190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60008351613577818460208801612de2565b83519083019061358b818360208801612de2565b01949350505050565b6000602082840312156135a657600080fd5b815167ffffffffffffffff8111156135bd57600080fd5b8201601f810184136135ce57600080fd5b80516135dc612f3582612eee565b8181528560208385010111156135f157600080fd5b613602826020830160208601612de2565b95945050505050565b6000835161361d818460208801612de2565b835190830190613631818360208801612de2565b652f6d6574612f60d01b9101908152600601949350505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826136c2576136c261369d565b500490565b6000826136d6576136d661369d565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061370e90830184612e0e565b9695505050505050565b60006020828403121561372a57600080fd5b815161097d81612daf56feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212208c2fd9a319703610b04fbe47ca2159e76c0a429ecacb56498aba3fe139c0c07c64736f6c63430008090033

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

0000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c500000000000000000000000000000000000000000000000000000000000222e000000000000000000000000000000000000000000000000000000000000111700000000000000000000000000000000000000000000000000000000000011170

-----Decoded View---------------
Arg [0] : _bridgeDataAddress (address): 0x0884fc15E31B1B634732e140cb3F94b3cbFdD1c5
Arg [1] : _finalSupply (uint256): 140000
Arg [2] : _typeSupplies (uint256[2]): 70000,70000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c5
Arg [1] : 00000000000000000000000000000000000000000000000000000000000222e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000011170
Arg [3] : 0000000000000000000000000000000000000000000000000000000000011170


Deployed Bytecode Sourcemap

58537:13241:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46799:240;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;46799:240:0;;;;;;;;34758:100;;;:::i;:::-;;;;;;;:::i;36221:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;36221:221:0;1528:203:1;35755:400:0;;;;;;:::i;:::-;;:::i;:::-;;69058:597;;;;;;:::i;:::-;;:::i;66508:109::-;66598:11;66508:109;;;3936:25:1;;;3924:2;3909:18;66508:109:0;3790:177:1;37111:305:0;;;;;;:::i;:::-;;:::i;58647:29::-;;;;;-1:-1:-1;;;;;58647:29:0;;;66625:1296;;;;;;:::i;:::-;;:::i;63315:206::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;62985:284::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37487:151::-;;;;;;:::i;:::-;;:::i;71294:193::-;;;;;;:::i;:::-;;:::i;61401:294::-;;;:::i;63849:119::-;;;;;;:::i;:::-;;:::i;47643:183::-;;;;;;:::i;:::-;;:::i;58939:54::-;;;;;;:::i;:::-;;;;;;;;;;;;;;60941:332;;;;;;:::i;:::-;;:::i;65931:348::-;;;;;;:::i;:::-;;:::i;63529:91::-;;;:::i;65533:390::-;;;;;;:::i;:::-;;:::i;68282:511::-;;;;;;:::i;:::-;;:::i;58845:34::-;;;;;;70790:308;;;;;;:::i;:::-;;:::i;62603:337::-;;;;;;:::i;:::-;;:::i;34927:104::-;;;:::i;36514:295::-;;;;;;:::i;:::-;;:::i;37709:285::-;;;;;;:::i;:::-;;:::i;35102:360::-;;;;;;:::i;:::-;;:::i;71603:170::-;;;;;;:::i;:::-;;:::i;36880:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;37001:25:0;;;36977:4;37001:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;36880:164;61842:753;;;;;;:::i;:::-;;:::i;46799:240::-;46904:4;-1:-1:-1;;;;;;46928:50:0;;-1:-1:-1;;;46928:50:0;;:103;;;46995:36;47019:11;46995:23;:36::i;:::-;46921:110;46799:240;-1:-1:-1;;46799:240:0:o;34758:100::-;34812:13;34845:5;34838:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34758:100;:::o;36221:221::-;36297:7;36325:16;36333:7;64091:11;-1:-1:-1;64080:22:0;63974:136;36325:16;36317:73;;;;-1:-1:-1;;;36317:73:0;;10558:2:1;36317:73:0;;;10540:21:1;10597:2;10577:18;;;10570:30;10636:34;10616:18;;;10609:62;-1:-1:-1;;;10687:18:1;;;10680:42;10739:19;;36317:73:0;;;;;;;;;-1:-1:-1;36410:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;36410:24:0;;36221:221::o;35755:400::-;35836:13;35852:16;35860:7;35852;:16::i;:::-;35836:32;;35893:5;-1:-1:-1;;;;;35887:11:0;:2;-1:-1:-1;;;;;35887:11:0;;;35879:57;;;;-1:-1:-1;;;35879:57:0;;10971:2:1;35879:57:0;;;10953:21:1;11010:2;10990:18;;;10983:30;11049:34;11029:18;;;11022:62;-1:-1:-1;;;11100:18:1;;;11093:31;11141:19;;35879:57:0;10769:397:1;35879:57:0;29049:10;-1:-1:-1;;;;;35957:21:0;;;;:72;;-1:-1:-1;35982:47:0;36009:5;29049:10;36880:164;:::i;35982:47::-;35949:164;;;;-1:-1:-1;;;35949:164:0;;11373:2:1;35949:164:0;;;11355:21:1;11412:2;11392:18;;;11385:30;11451:34;11431:18;;;11424:62;11522:26;11502:18;;;11495:54;11566:19;;35949:164:0;11171:420:1;35949:164:0;36126:21;36135:2;36139:7;36126:8;:21::i;:::-;35825:330;35755:400;;:::o;69058:597::-;60774:17;:15;:17::i;:::-;:25;;60795:4;60774:25;60766:86;;;;-1:-1:-1;;;60766:86:0;;;;;;;:::i;:::-;69206:20:::1;69229:17;69237:8;69229:7;:17::i;:::-;-1:-1:-1::0;;;;;69531:33:0;::::1;69396:12;69531:33:::0;;;:19:::1;:33;::::0;;;;;;;;69421:144;;69206:40;;-1:-1:-1;69396:12:0;;69421:144:::1;::::0;69446:4:::1;::::0;-1:-1:-1;;;69453:40:0;69495:10:::1;::::0;69206:40;;69521:8;;69421:144:::1;;:::i;:::-;;;;;;;;;;;;;69411:155;;;;;;69396:170;;69577:70;69601:12;69615:4;69621:8;69631:3;69636:10;69577:23;:70::i;:::-;69195:460;;69058:597:::0;;;:::o;37111:305::-;37272:41;29049:10;37305:7;37272:18;:41::i;:::-;37264:103;;;;-1:-1:-1;;;37264:103:0;;;;;;;:::i;:::-;37380:28;37390:4;37396:2;37400:7;37380:9;:28::i;66625:1296::-;66734:7;66773:27;66793:6;66773:19;:27::i;:::-;66763:6;:37;;:87;;;;-1:-1:-1;66814:10:0;;:36;;-1:-1:-1;;;66814:36:0;;-1:-1:-1;;;;;66814:10:0;;;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;66804:46:0;:6;-1:-1:-1;;;;;66804:46:0;;66763:87;66759:1096;;;67236:17;67246:6;67236:9;:17::i;:::-;67227:6;:26;67219:82;;;;-1:-1:-1;;;67219:82:0;;;;;;;:::i;:::-;67316:17;67336:27;67356:6;67336:19;:27::i;:::-;67316:47;;67378:15;67412:367;39526:4;39550:16;;;:7;:16;;;;;;-1:-1:-1;;;;;39550:16:0;67434:271;;67507:6;67494:9;:19;67490:162;;67623:5;;67490:162;67674:11;;;;:::i;:::-;;;;67434:271;67723:9;;;;:::i;:::-;;;;67766:11;67756:7;:21;67412:367;;;67836:7;-1:-1:-1;67829:14:0;;-1:-1:-1;67829:14:0;66759:1096;67872:41;67898:6;67906;67872:25;:41::i;:::-;67865:48;66625:1296;-1:-1:-1;;;66625:1296:0:o;63315:206::-;63392:7;63420:17;63428:8;64091:11;-1:-1:-1;64080:22:0;63974:136;63420:17;63412:54;;;;-1:-1:-1;;;63412:54:0;;14555:2:1;63412:54:0;;;14537:21:1;14594:2;14574:18;;;14567:30;-1:-1:-1;;;14613:18:1;;;14606:54;14677:18;;63412:54:0;14353:348:1;63412:54:0;63492:10;63503:8;63492:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;63484:29;;;;;;;;:::i;62985:284::-;63060:9;63095:17;63103:8;64091:11;-1:-1:-1;64080:22:0;63974:136;63095:17;63087:54;;;;-1:-1:-1;;;63087:54:0;;14555:2:1;63087:54:0;;;14537:21:1;14594:2;14574:18;;;14567:30;-1:-1:-1;;;14613:18:1;;;14606:54;14677:18;;63087:54:0;14353:348:1;63087:54:0;63167:11;63156:8;:22;63152:77;;;-1:-1:-1;63202:15:0;;62985:284;-1:-1:-1;62985:284:0:o;63152:77::-;-1:-1:-1;63246:15:0;;62985:284;-1:-1:-1;62985:284:0:o;37487:151::-;37591:39;37608:4;37614:2;37618:7;37591:39;;;;;;;;;;;;:16;:39::i;71294:193::-;60587:10;;:47;;-1:-1:-1;;;60587:47:0;;-1:-1:-1;;;;;60587:10:0;;;;:21;;:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60573:61:0;:10;-1:-1:-1;;;;;60573:61:0;;60565:128;;;;-1:-1:-1;;;60565:128:0;;;;;;;:::i;:::-;71440:38:::1;::::0;-1:-1:-1;;;71440:38:0;;71472:4:::1;71440:38;::::0;::::1;1674:51:1::0;-1:-1:-1;;;;;71412:22:0;::::1;::::0;::::1;::::0;71435:3;;71412:22;;71440:23:::1;::::0;1647:18:1;;71440:38:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71412:67;::::0;-1:-1:-1;;;;;;71412:67:0::1;::::0;;;;;;-1:-1:-1;;;;;15993:32:1;;;71412:67:0::1;::::0;::::1;15975:51:1::0;16042:18;;;16035:34;15948:18;;71412:67:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;61401:294::-:0;61459:4;61481:28;61512:10;;;;;;;;;-1:-1:-1;;;;;61512:10:0;-1:-1:-1;;;;;61512:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61481:64;-1:-1:-1;61619:25:0;;;:67;;;61671:15;61648:20;:38;61619:67;61611:76;;;61401:294;:::o;63849:119::-;63914:4;63943:17;63951:8;64091:11;-1:-1:-1;64080:22:0;63974:136;47643:183;47718:7;66598:11;47746:5;:21;47738:57;;;;-1:-1:-1;;;47738:57:0;;16532:2:1;47738:57:0;;;16514:21:1;16571:2;16551:18;;;16544:30;16610:25;16590:18;;;16583:53;16653:18;;47738:57:0;16330:347:1;47738:57:0;-1:-1:-1;47813:5:0;47643:183::o;60941:332::-;60400:10;;:38;;-1:-1:-1;;;60400:38:0;;16884:2:1;60400:38:0;;;16866:21:1;16923:2;16903:18;;;16896:30;-1:-1:-1;;;16942:18:1;;;16935:43;-1:-1:-1;;;;;60400:10:0;;;;:21;;16995:18:1;;60400:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60386:52:0;:10;-1:-1:-1;;;;;60386:52:0;;60378:110;;;;-1:-1:-1;;;60378:110:0;;17226:2:1;60378:110:0;;;17208:21:1;17265:2;17245:18;;;17238:30;17304:34;17284:18;;;17277:62;-1:-1:-1;;;17355:18:1;;;17348:43;17408:19;;60378:110:0;17024:409:1;60378:110:0;-1:-1:-1;;;;;61053:39:0;::::1;61045:103;;;::::0;-1:-1:-1;;;61045:103:0;;17640:2:1;61045:103:0::1;::::0;::::1;17622:21:1::0;17679:2;17659:18;;;17652:30;17718:34;17698:18;;;17691:62;-1:-1:-1;;;17769:18:1;;;17762:49;17828:19;;61045:103:0::1;17438:415:1::0;61045:103:0::1;61190:10;::::0;61164:63:::1;::::0;-1:-1:-1;;;;;61164:63:0;;::::1;::::0;61190:10:::1;::::0;61164:63:::1;::::0;61190:10:::1;::::0;61164:63:::1;61238:10;:27:::0;;-1:-1:-1;;;;;;61238:27:0::1;-1:-1:-1::0;;;;;61238:27:0;;;::::1;::::0;;;::::1;::::0;;60941:332::o;65931:348::-;66026:7;66055:17;66063:8;64091:11;-1:-1:-1;64080:22:0;63974:136;66055:17;:49;;;;-1:-1:-1;39526:4:0;39550:16;;;:7;:16;;;;;;-1:-1:-1;;;;;39550:16:0;:30;66055:49;66051:180;;;66183:10;;:36;;-1:-1:-1;;;66183:36:0;;-1:-1:-1;;;;;66183:10:0;;;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;66051:180::-;66248:23;66262:8;66248:13;:23::i;63529:91::-;63569:13;63602:10;:8;:10::i;:::-;63595:17;;63529:91;:::o;65533:390::-;65667:10;;:36;;-1:-1:-1;;;65667:36:0;;65628:7;;-1:-1:-1;;;;;65667:10:0;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;65657:46:0;:6;-1:-1:-1;;;;;65657:46:0;;65653:222;;;65840:23;65856:6;65840:15;:23::i;:::-;47546:12;;65804:33;;:11;:33;:::i;:::-;:59;;;;:::i;65653:222::-;65892:23;65908:6;65892:15;:23::i;68282:511::-;60774:17;:15;:17::i;:::-;:25;;60795:4;60774:25;60766:86;;;;-1:-1:-1;;;60766:86:0;;;;;;;:::i;:::-;68418:20:::1;68441:17;68449:8;68441:7;:17::i;:::-;-1:-1:-1::0;;;;;68669:33:0;::::1;68553:12;68669:33:::0;;;:19:::1;:33;::::0;;;;;;;;68578:125;;68418:40;;-1:-1:-1;68553:12:0;;68578:125:::1;::::0;68603:4:::1;::::0;-1:-1:-1;;;68610:28:0;68418:40;;68654:3;;68659:8;;68578:125:::1;;:::i;70790:308::-:0;60587:10;;:47;;-1:-1:-1;;;60587:47:0;;-1:-1:-1;;;;;60587:10:0;;;;:21;;:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60573:61:0;:10;-1:-1:-1;;;;;60573:61:0;;60565:128;;;;-1:-1:-1;;;60565:128:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;70945:38:0;::::1;70937:81;;;::::0;-1:-1:-1;;;70937:81:0;;18323:2:1;70937:81:0::1;::::0;::::1;18305:21:1::0;18362:2;18342:18;;;18335:30;18401:32;18381:18;;;18374:60;18451:18;;70937:81:0::1;18121:354:1::0;70937:81:0::1;71029:61;::::0;-1:-1:-1;;;71029:61:0;;-1:-1:-1;;;;;71029:54:0;::::1;::::0;::::1;::::0;:61:::1;::::0;71084:5;;;;71029:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;70790:308:::0;;;:::o;62603:337::-;60154:10;;:38;;-1:-1:-1;;;60154:38:0;;19266:2:1;60154:38:0;;;19248:21:1;19305:2;19285:18;;;19278:30;-1:-1:-1;;;19324:18:1;;;19317:43;-1:-1:-1;;;;;60154:10:0;;;;:21;;19377:18:1;;60154:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60140:52:0;:10;-1:-1:-1;;;;;60140:52:0;;:105;;;-1:-1:-1;60210:10:0;;:35;;-1:-1:-1;;;60210:35:0;;19608:2:1;60210:35:0;;;19590:21:1;19647:2;19627:18;;;19620:30;-1:-1:-1;;;19666:18:1;;;19659:40;-1:-1:-1;;;;;60210:10:0;;;;:21;;19716:18:1;;60210:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60196:49:0;:10;-1:-1:-1;;;;;60196:49:0;;60140:105;60132:178;;;;-1:-1:-1;;;60132:178:0;;19947:2:1;60132:178:0;;;19929:21:1;19986:2;19966:18;;;19959:30;20025:34;20005:18;;;19998:62;20096:30;20076:18;;;20069:58;20144:19;;60132:178:0;19745:424:1;60132:178:0;62779:10:::1;::::0;:36:::1;::::0;-1:-1:-1;;;62779:36:0;;-1:-1:-1;;;;;62779:10:0;;::::1;::::0;:21:::1;::::0;:36:::1;::::0;::::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;62758:57:0::1;:17;62766:8;62758:7;:17::i;:::-;-1:-1:-1::0;;;;;62758:57:0::1;;62750:129;;;::::0;-1:-1:-1;;;62750:129:0;;20376:2:1;62750:129:0::1;::::0;::::1;20358:21:1::0;20415:2;20395:18;;;20388:30;20454:34;20434:18;;;20427:62;20525:29;20505:18;;;20498:57;20572:19;;62750:129:0::1;20174:423:1::0;62750:129:0::1;62919:9;;62929:1;62919:12;;;;;;;:::i;:::-;::::0;;;::::1;;;;::::0;-1:-1:-1;62890:10:0::1;62901:8:::0;62890:20:::1;::::0;::::1;;;;;:::i;:::-;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;62603:337:::0;;;:::o;34927:104::-;34983:13;35016:7;35009:14;;;;;:::i;36514:295::-;-1:-1:-1;;;;;36617:24:0;;29049:10;36617:24;;36609:62;;;;-1:-1:-1;;;36609:62:0;;20804:2:1;36609:62:0;;;20786:21:1;20843:2;20823:18;;;20816:30;20882:27;20862:18;;;20855:55;20927:18;;36609:62:0;20602:349:1;36609:62:0;29049:10;36684:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;36684:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;36684:53:0;;;;;;;;;;36753:48;;540:41:1;;;36684:42:0;;29049:10;36753:48;;513:18:1;36753:48:0;;;;;;;36514:295;;:::o;37709:285::-;37841:41;29049:10;37874:7;37841:18;:41::i;:::-;37833:103;;;;-1:-1:-1;;;37833:103:0;;;;;;;:::i;:::-;37947:39;37961:4;37967:2;37971:7;37980:5;37947:13;:39::i;35102:360::-;35175:13;35209:16;35217:7;64091:11;-1:-1:-1;64080:22:0;63974:136;35209:16;35201:76;;;;-1:-1:-1;;;35201:76:0;;21158:2:1;35201:76:0;;;21140:21:1;21197:2;21177:18;;;21170:30;21236:34;21216:18;;;21209:62;-1:-1:-1;;;21287:18:1;;;21280:45;21342:19;;35201:76:0;20956:411:1;35201:76:0;35290:21;35314:10;:8;:10::i;:::-;35290:34;;35366:1;35348:7;35342:21;:25;:112;;;;;;;;;;;;;;;;;35407:7;35416:18;:7;:16;:18::i;:::-;35390:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;35335:119;35102:360;-1:-1:-1;;;35102:360:0:o;71603:170::-;60587:10;;:47;;-1:-1:-1;;;60587:47:0;;-1:-1:-1;;;;;60587:10:0;;;;:21;;:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60573:61:0;:10;-1:-1:-1;;;;;60573:61:0;;60565:128;;;;-1:-1:-1;;;60565:128:0;;;;;;;:::i;:::-;71725:40:::1;::::0;-1:-1:-1;;;71725:40:0;;-1:-1:-1;;;;;22033:32:1;;;71725:40:0::1;::::0;::::1;22015:51:1::0;71760:4:0::1;22082:18:1::0;;;22075:50;71725:29:0;::::1;::::0;::::1;::::0;21988:18:1;;71725:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;71603:170:::0;;:::o;61842:753::-;59964:10;;:38;;-1:-1:-1;;;59964:38:0;;19266:2:1;59964:38:0;;;19248:21:1;19305:2;19285:18;;;19278:30;-1:-1:-1;;;19324:18:1;;;19317:43;-1:-1:-1;;;;;59964:10:0;;;;:21;;19377:18:1;;59964:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;59950:52:0;:10;-1:-1:-1;;;;;59950:52:0;;59942:110;;;;-1:-1:-1;;;59942:110:0;;22338:2:1;59942:110:0;;;22320:21:1;22377:2;22357:18;;;22350:30;22416:34;22396:18;;;22389:62;-1:-1:-1;;;22467:18:1;;;22460:43;22520:19;;59942:110:0;22136:409:1;59942:110:0;61997:19:::1;;61985:8;:31;;61977:74;;;::::0;-1:-1:-1;;;61977:74:0;;22752:2:1;61977:74:0::1;::::0;::::1;22734:21:1::0;22791:2;22771:18;;;22764:30;22830:32;22810:18;;;22803:60;22880:18;;61977:74:0::1;22550:354:1::0;61977:74:0::1;62084:10;::::0;:36:::1;::::0;-1:-1:-1;;;62084:36:0;;62062:19:::1;::::0;-1:-1:-1;;;;;62084:10:0::1;::::0;:21:::1;::::0;:36:::1;::::0;::::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62062:58:::0;-1:-1:-1;62131:13:0::1;62147:17;62158:6:::0;62147:8;:17:::1;:::i;:::-;62131:33;;62192:11;62183:5;:20;;62175:84;;;::::0;-1:-1:-1;;;62175:84:0;;23111:2:1;62175:84:0::1;::::0;::::1;23093:21:1::0;23150:2;23130:18;;;23123:30;23189:34;23169:18;;;23162:62;-1:-1:-1;;;23240:18:1;;;23233:49;23299:19;;62175:84:0::1;22909:415:1::0;62175:84:0::1;62287:8:::0;62270:280:::1;62301:5;62297:1;:9;62270:280;;;62420:16;62419:17;:42;;;-1:-1:-1::0;39526:4:0;39550:16;;;:7;:16;;;;;;-1:-1:-1;;;;;39550:16:0;:30;62419:42:::1;62415:124;;;62487:36;::::0;62521:1;;-1:-1:-1;;;;;62487:36:0;::::1;::::0;62504:1:::1;::::0;-1:-1:-1;;;;;;;;;;;62487:36:0;62504:1;;62487:36:::1;62415:124;62308:3:::0;::::1;::::0;::::1;:::i;:::-;;;;62270:280;;;-1:-1:-1::0;62560:19:0::1;:27:::0;-1:-1:-1;;;;61842:753:0:o;33826:292::-;33928:4;-1:-1:-1;;;;;;33952:40:0;;-1:-1:-1;;;33952:40:0;;:105;;-1:-1:-1;;;;;;;34009:48:0;;-1:-1:-1;;;34009:48:0;33952:105;:158;;;-1:-1:-1;;;;;;;;;;32096:40:0;;;34074:36;31987:157;43396:167;43471:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;43471:29:0;-1:-1:-1;;;;;43471:29:0;;;;;;;;:24;;43525:16;43471:24;43525:7;:16::i;:::-;-1:-1:-1;;;;;43516:39:0;;;;;;;;;;;43396:167;;:::o;69731:706::-;69888:12;69903:35;69932:5;11514:58;;27312:66:1;11514:58:0;;;27300:79:1;27395:12;;;27388:28;;;11381:7:0;;27432:12:1;;11514:58:0;;;;;;;;;;;;11504:69;;;;;;11497:76;;11312:269;;;;69903:35;69888:50;;69949:14;69966:31;69980:4;69986:10;69966:13;:31::i;:::-;69949:48;;70026:13;-1:-1:-1;;;;;70016:23:0;:6;-1:-1:-1;;;;;70016:23:0;;70008:98;;;;-1:-1:-1;;;70008:98:0;;23531:2:1;70008:98:0;;;23513:21:1;23570:2;23550:18;;;23543:30;23609:34;23589:18;;;23582:62;23680:32;23660:18;;;23653:60;23730:19;;70008:98:0;23329:426:1;70008:98:0;-1:-1:-1;;;;;70232:92:0;;;70289:34;;;;:19;:34;;;;;;;;;;70232:92;;70247:10;15975:51:1;;16042:18;;;16035:34;70279:8:0;;70232:92;;;;;;15948:18:1;70232:92:0;;;;;;;-1:-1:-1;;;;;70335:34:0;;;;;;:19;:34;;;;;:36;;;;;;:::i;:::-;;;;;;70382:47;70396:13;70411:3;70416:8;70382:47;;;;;;;;;;;;:13;:47::i;:::-;69877:560;;69731:706;;;;;:::o;39755:351::-;39848:4;39873:16;39881:7;64091:11;-1:-1:-1;64080:22:0;63974:136;39873:16;39865:73;;;;-1:-1:-1;;;39865:73:0;;23962:2:1;39865:73:0;;;23944:21:1;24001:2;23981:18;;;23974:30;24040:34;24020:18;;;24013:62;-1:-1:-1;;;24091:18:1;;;24084:42;24143:19;;39865:73:0;23760:408:1;39865:73:0;39949:13;39965:16;39973:7;39965;:16::i;:::-;39949:32;;40011:5;-1:-1:-1;;;;;40000:16:0;:7;-1:-1:-1;;;;;40000:16:0;;:51;;;;40044:7;-1:-1:-1;;;;;40020:31:0;:20;40032:7;40020:11;:20::i;:::-;-1:-1:-1;;;;;40020:31:0;;40000:51;:97;;;-1:-1:-1;;;;;;37001:25:0;;;36977:4;37001:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;40055:42;39992:106;39755:351;-1:-1:-1;;;;39755:351:0:o;64586:939::-;39526:4;39550:16;;;:7;:16;;;;;;-1:-1:-1;;;;;39550:16:0;:30;;;64694:77;;-1:-1:-1;64735:10:0;;:36;;-1:-1:-1;;;64735:36:0;;-1:-1:-1;;;;;64735:10:0;;;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;64726:45:0;:5;-1:-1:-1;;;;;64726:45:0;;64694:77;:121;;;;;64775:40;64794:10;64806:8;64775:18;:40::i;:::-;64690:828;;;64888:30;64905:1;64909:8;64888;:30::i;:::-;65229:20;65235:3;65240:8;65229:5;:20::i;:::-;65280:19;;65268:8;:31;65264:114;;65325:37;;65353:8;;-1:-1:-1;;;;;65325:37:0;;;65342:1;;-1:-1:-1;;;;;;;;;;;65325:37:0;65342:1;;65325:37;65264:114;65418:8;65413:3;-1:-1:-1;;;;;65397:30:0;65406:5;-1:-1:-1;;;;;65397:30:0;-1:-1:-1;;;;;;;;;;;65397:30:0;;;;;;;;;35825:330;35755:400;;:::o;64690:828::-;65469:37;65485:5;65492:3;65497:8;65469:15;:37::i;34182:208::-;34254:7;-1:-1:-1;;;;;34282:19:0;;34274:74;;;;-1:-1:-1;;;34274:74:0;;24375:2:1;34274:74:0;;;24357:21:1;24414:2;24394:18;;;24387:30;24453:34;24433:18;;;24426:62;-1:-1:-1;;;24504:18:1;;;24497:40;24554:19;;34274:74:0;24173:406:1;34274:74:0;-1:-1:-1;;;;;;34366:16:0;;;;;:9;:16;;;;;;;34182:208::o;47123:259::-;47220:7;47256:26;47276:5;47256:19;:26::i;:::-;47248:5;:34;47240:90;;;;-1:-1:-1;;;47240:90:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;47348:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;47123:259::o;34452:239::-;34524:7;34560:16;;;:7;:16;;;;;;-1:-1:-1;;;;;34560:16:0;34595:19;34587:73;;;;-1:-1:-1;;;34587:73:0;;24786:2:1;34587:73:0;;;24768:21:1;24825:2;24805:18;;;24798:30;24864:34;24844:18;;;24837:62;-1:-1:-1;;;24915:18:1;;;24908:39;24964:19;;34587:73:0;24584:405:1;63626:164:0;63735:10;;:25;;;-1:-1:-1;;;63735:25:0;;;;63678:13;;-1:-1:-1;;;;;63735:10:0;;:23;;:25;;;;;:10;;:25;;;;;;;:10;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63735:25:0;;;;;;;;;;;;:::i;:::-;63762:8;:6;:8::i;:::-;63718:63;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63704:78;;63626:164;:::o;38876:272::-;38990:28;39000:4;39006:2;39010:7;38990:9;:28::i;:::-;39037:48;39060:4;39066:2;39070:7;39079:5;39037:22;:48::i;:::-;39029:111;;;;-1:-1:-1;;;39029:111:0;;;;;;;:::i;29463:723::-;29519:13;29740:10;29736:53;;-1:-1:-1;;29767:10:0;;;;;;;;;;;;-1:-1:-1;;;29767:10:0;;;;;29463:723::o;29736:53::-;29814:5;29799:12;29855:78;29862:9;;29855:78;;29888:8;;;;:::i;:::-;;-1:-1:-1;29911:10:0;;-1:-1:-1;29919:2:0;29911:10;;:::i;:::-;;;29855:78;;;29943:19;29975:6;29965:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29965:17:0;;29943:39;;29993:154;30000:10;;29993:154;;30027:11;30037:1;30027:11;;:::i;:::-;;-1:-1:-1;30096:10:0;30104:2;30096:5;:10;:::i;:::-;30083:24;;:2;:24;:::i;:::-;30070:39;;30053:6;30060;30053:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;30053:56:0;;;;;;;;-1:-1:-1;30124:11:0;30133:2;30124:11;;:::i;:::-;;;29993:154;;7463:231;7541:7;7562:17;7581:18;7603:27;7614:4;7620:9;7603:10;:27::i;:::-;7561:69;;;;7641:18;7653:5;7641:11;:18::i;:::-;-1:-1:-1;7677:9:0;7463:231;-1:-1:-1;;;7463:231:0:o;41371:431::-;-1:-1:-1;;;;;41451:16:0;;41443:61;;;;-1:-1:-1;;;41443:61:0;;27657:2:1;41443:61:0;;;27639:21:1;;;27676:18;;;27669:30;27735:34;27715:18;;;27708:62;27787:18;;41443:61:0;27455:356:1;41443:61:0;39526:4;39550:16;;;:7;:16;;;;;;-1:-1:-1;;;;;39550:16:0;:30;41515:68;;;;-1:-1:-1;;;41515:68:0;;28018:2:1;41515:68:0;;;28000:21:1;28057:2;28037:18;;;28030:30;28096;28076:18;;;28069:58;28144:18;;41515:68:0;27816:352:1;41515:68:0;41596:45;41625:1;41629:2;41633:7;41596:20;:45::i;:::-;-1:-1:-1;;;;;41654:13:0;;;;;;:9;:13;;;;;:18;;41671:1;;41654:13;:18;;41671:1;;41654:18;:::i;:::-;;;;-1:-1:-1;;41683:16:0;;;;:7;:16;;;;;:21;;-1:-1:-1;;;;;;41683:21:0;-1:-1:-1;;;;;41683:21:0;;;;;;;;;;41371:431::o;42731:547::-;42859:4;-1:-1:-1;;;;;42829:34:0;:26;42847:7;42829:17;:26::i;:::-;-1:-1:-1;;;;;42829:34:0;;42821:88;;;;-1:-1:-1;;;42821:88:0;;28375:2:1;42821:88:0;;;28357:21:1;28414:2;28394:18;;;28387:30;28453:34;28433:18;;;28426:62;-1:-1:-1;;;28504:18:1;;;28497:39;28553:19;;42821:88:0;28173:405:1;42821:88:0;-1:-1:-1;;;;;42928:16:0;;42920:65;;;;-1:-1:-1;;;42920:65:0;;28785:2:1;42920:65:0;;;28767:21:1;28824:2;28804:18;;;28797:30;28863:34;28843:18;;;28836:62;-1:-1:-1;;;28914:18:1;;;28907:34;28958:19;;42920:65:0;28583:400:1;42920:65:0;42998:39;43019:4;43025:2;43029:7;42998:20;:39::i;:::-;43102:29;43119:1;43123:7;43102:8;:29::i;:::-;-1:-1:-1;;;;;43144:15:0;;;;;;:9;:15;;;;;:20;;43163:1;;43144:15;:20;;43163:1;;43144:20;:::i;:::-;;;;-1:-1:-1;;;;;;;43175:13:0;;;;;;:9;:13;;;;;:18;;43192:1;;43175:13;:18;;43192:1;;43175:18;:::i;:::-;;;;-1:-1:-1;;43204:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;43204:21:0;-1:-1:-1;;;;;43204:21:0;;;;;;;;;43243:27;;43204:16;;43243:27;;;;-1:-1:-1;;;;;;;;;;;43243:27:0;;42731:547;;;:::o;44128:843::-;44249:4;-1:-1:-1;;;;;44275:13:0;;21367:20;21415:8;44271:693;;44311:72;;-1:-1:-1;;;44311:72:0;;-1:-1:-1;;;;;44311:36:0;;;;;:72;;29049:10;;44362:4;;44368:7;;44377:5;;44311:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44311:72:0;;;;;;;;-1:-1:-1;;44311:72:0;;;;;;;;;;;;:::i;:::-;;;44307:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44557:13:0;;44553:341;;44600:60;;-1:-1:-1;;;44600:60:0;;;;;;;:::i;44553:341::-;44844:6;44838:13;44829:6;44825:2;44821:15;44814:38;44307:602;-1:-1:-1;;;;;;44434:55:0;-1:-1:-1;;;44434:55:0;;-1:-1:-1;44427:62:0;;44271:693;-1:-1:-1;44948:4:0;44128:843;;;;;;:::o;5353:1308::-;5434:7;5443:12;5668:9;:16;5688:2;5668:22;5664:990;;;5964:4;5949:20;;5943:27;6014:4;5999:20;;5993:27;6072:4;6057:20;;6051:27;5707:9;6043:36;6115:25;6126:4;6043:36;5943:27;5993;6115:10;:25::i;:::-;6108:32;;;;;;;;;5664:990;6162:9;:16;6182:2;6162:22;6158:496;;;6437:4;6422:20;;6416:27;6488:4;6473:20;;6467:27;6530:23;6541:4;6416:27;6467;6530:10;:23::i;:::-;6523:30;;;;;;;;6158:496;-1:-1:-1;6602:1:0;;-1:-1:-1;6606:35:0;6158:496;5353:1308;;;;;:::o;3624:643::-;3702:20;3693:5;:29;;;;;;;;:::i;:::-;;3689:571;;;3624:643;:::o;3689:571::-;3800:29;3791:5;:38;;;;;;;;:::i;:::-;;3787:473;;;3846:34;;-1:-1:-1;;;3846:34:0;;29938:2:1;3846:34:0;;;29920:21:1;29977:2;29957:18;;;29950:30;30016:26;29996:18;;;29989:54;30060:18;;3846:34:0;29736:348:1;3787:473:0;3911:35;3902:5;:44;;;;;;;;:::i;:::-;;3898:362;;;3963:41;;-1:-1:-1;;;3963:41:0;;30291:2:1;3963:41:0;;;30273:21:1;30330:2;30310:18;;;30303:30;30369:33;30349:18;;;30342:61;30420:18;;3963:41:0;30089:355:1;3898:362:0;4035:30;4026:5;:39;;;;;;;;:::i;:::-;;4022:238;;;4082:44;;-1:-1:-1;;;4082:44:0;;30651:2:1;4082:44:0;;;30633:21:1;30690:2;30670:18;;;30663:30;30729:34;30709:18;;;30702:62;-1:-1:-1;;;30780:18:1;;;30773:32;30822:19;;4082:44:0;30449:398:1;4022:238:0;4157:30;4148:5;:39;;;;;;;;:::i;:::-;;4144:116;;;4204:44;;-1:-1:-1;;;4204:44:0;;31054:2:1;4204:44:0;;;31036:21:1;31093:2;31073:18;;;31066:30;31132:34;31112:18;;;31105:62;-1:-1:-1;;;31183:18:1;;;31176:32;31225:19;;4204:44:0;30852:398:1;4144:116:0;3624:643;:::o;64282:199::-;60774:17;:15;:17::i;:::-;:25;;60795:4;60774:25;60766:86;;;;-1:-1:-1;;;60766:86:0;;;;;;;:::i;:::-;64425:48:::1;64452:5;64459:3;64464:8;64425:26;:48::i;8962:1632::-:0;9093:7;;10027:66;10014:79;;10010:163;;;-1:-1:-1;10126:1:0;;-1:-1:-1;10130:30:0;10110:51;;10010:163;10187:1;:7;;10192:2;10187:7;;:18;;;;;10198:1;:7;;10203:2;10198:7;;10187:18;10183:102;;;-1:-1:-1;10238:1:0;;-1:-1:-1;10242:30:0;10222:51;;10183:102;10399:24;;;10382:14;10399:24;;;;;;;;;31482:25:1;;;31555:4;31543:17;;31523:18;;;31516:45;;;;31577:18;;;31570:34;;;31620:18;;;31613:34;;;10399:24:0;;31454:19:1;;10399:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;10399:24:0;;-1:-1:-1;;10399:24:0;;;-1:-1:-1;;;;;;;10438:20:0;;10434:103;;10491:1;10495:29;10475:50;;;;;;;10434:103;10557:6;-1:-1:-1;10565:20:0;;-1:-1:-1;8962:1632:0;;;;;;;;:::o;7957:391::-;8071:7;;-1:-1:-1;;;;;8172:75:0;;8274:3;8270:12;;;8284:2;8266:21;8315:25;8326:4;8266:21;8335:1;8172:75;8315:10;:25::i;:::-;8308:32;;;;;;7957:391;;;;;;:::o;48439:555::-;-1:-1:-1;;;;;48611:18:0;;48607:187;;48646:40;48678:7;48646:31;:40::i;:::-;48607:187;;;48716:2;-1:-1:-1;;;;;48708:10:0;:4;-1:-1:-1;;;;;48708:10:0;;48704:90;;48735:47;48768:4;48774:7;48735:32;:47::i;:::-;-1:-1:-1;;;;;48808:16:0;;48804:183;;48841:45;48878:7;48841:36;:45::i;48804:183::-;48914:4;-1:-1:-1;;;;;48908:10:0;:2;-1:-1:-1;;;;;48908:10:0;;48904:83;;48935:40;48963:2;48967:7;48935:27;:40::i;49719:103::-;49800:12;:14;;;:12;:14;;;:::i;:::-;;;;;;49719:103;:::o;50449:991::-;50715:22;50768:1;50740:25;50760:4;50740:19;:25::i;:::-;:29;;;;:::i;:::-;50780:18;50801:26;;;:17;:26;;;;;;50715:54;;-1:-1:-1;50934:28:0;;;50930:328;;-1:-1:-1;;;;;51001:18:0;;50979:19;51001:18;;;:12;:18;;;;;;;;:34;;;;;;;;;51052:30;;;;;;:44;;;51169:30;;:17;:30;;;;;:43;;;50930:328;-1:-1:-1;51354:26:0;;;;:17;:26;;;;;;;;51347:33;;;-1:-1:-1;;;;;51398:18:0;;;;;:12;:18;;;;;:34;;;;;;;51391:41;50449:991::o;51697:137::-;51788:38;;-1:-1:-1;;;51788:38:0;;31860:2:1;51788:38:0;;;31842:21:1;31899:2;31879:18;;;31872:30;31938;31918:18;;;31911:58;31986:18;;51788:38:0;31658:352:1;49295:224:0;49380:14;49397:23;49417:2;49397:19;:23::i;:::-;-1:-1:-1;;;;;49431:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;49476:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;49295:224:0:o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:131::-;-1:-1:-1;;;;;1811:31:1;;1801:42;;1791:70;;1857:1;1854;1847:12;1872:315;1940:6;1948;2001:2;1989:9;1980:7;1976:23;1972:32;1969:52;;;2017:1;2014;2007:12;1969:52;2056:9;2043:23;2075:31;2100:5;2075:31;:::i;:::-;2125:5;2177:2;2162:18;;;;2149:32;;-1:-1:-1;;;1872:315:1:o;2192:127::-;2253:10;2248:3;2244:20;2241:1;2234:31;2284:4;2281:1;2274:15;2308:4;2305:1;2298:15;2324:275;2395:2;2389:9;2460:2;2441:13;;-1:-1:-1;;2437:27:1;2425:40;;2495:18;2480:34;;2516:22;;;2477:62;2474:88;;;2542:18;;:::i;:::-;2578:2;2571:22;2324:275;;-1:-1:-1;2324:275:1:o;2604:186::-;2652:4;2685:18;2677:6;2674:30;2671:56;;;2707:18;;:::i;:::-;-1:-1:-1;2773:2:1;2752:15;-1:-1:-1;;2748:29:1;2779:4;2744:40;;2604:186::o;2795:462::-;2837:5;2890:3;2883:4;2875:6;2871:17;2867:27;2857:55;;2908:1;2905;2898:12;2857:55;2944:6;2931:20;2975:48;2991:31;3019:2;2991:31;:::i;:::-;2975:48;:::i;:::-;3048:2;3039:7;3032:19;3094:3;3087:4;3082:2;3074:6;3070:15;3066:26;3063:35;3060:55;;;3111:1;3108;3101:12;3060:55;3176:2;3169:4;3161:6;3157:17;3150:4;3141:7;3137:18;3124:55;3224:1;3199:16;;;3217:4;3195:27;3188:38;;;;3203:7;2795:462;-1:-1:-1;;;2795:462:1:o;3262:523::-;3348:6;3356;3364;3417:2;3405:9;3396:7;3392:23;3388:32;3385:52;;;3433:1;3430;3423:12;3385:52;3469:9;3456:23;3446:33;;3529:2;3518:9;3514:18;3501:32;3542:31;3567:5;3542:31;:::i;:::-;3592:5;-1:-1:-1;3648:2:1;3633:18;;3620:32;3675:18;3664:30;;3661:50;;;3707:1;3704;3697:12;3661:50;3730:49;3771:7;3762:6;3751:9;3747:22;3730:49;:::i;:::-;3720:59;;;3262:523;;;;;:::o;3972:456::-;4049:6;4057;4065;4118:2;4106:9;4097:7;4093:23;4089:32;4086:52;;;4134:1;4131;4124:12;4086:52;4173:9;4160:23;4192:31;4217:5;4192:31;:::i;:::-;4242:5;-1:-1:-1;4299:2:1;4284:18;;4271:32;4312:33;4271:32;4312:33;:::i;:::-;3972:456;;4364:7;;-1:-1:-1;;;4418:2:1;4403:18;;;;4390:32;;3972:456::o;4661:127::-;4722:10;4717:3;4713:20;4710:1;4703:31;4753:4;4750:1;4743:15;4777:4;4774:1;4767:15;4793:243;4937:2;4922:18;;4970:1;4959:13;;4949:47;;4976:18;;:::i;:::-;5005:25;;;4793:243;:::o;5041:245::-;5187:2;5172:18;;5220:1;5209:13;;5199:47;;5226:18;;:::i;5291:401::-;5372:6;5380;5433:2;5421:9;5412:7;5408:23;5404:32;5401:52;;;5449:1;5446;5439:12;5401:52;5488:9;5475:23;5507:31;5532:5;5507:31;:::i;:::-;5557:5;-1:-1:-1;5614:2:1;5599:18;;5586:32;5627:33;5586:32;5627:33;:::i;:::-;5679:7;5669:17;;;5291:401;;;;;:::o;5697:247::-;5756:6;5809:2;5797:9;5788:7;5784:23;5780:32;5777:52;;;5825:1;5822;5815:12;5777:52;5864:9;5851:23;5883:31;5908:5;5883:31;:::i;6221:348::-;6273:8;6283:6;6337:3;6330:4;6322:6;6318:17;6314:27;6304:55;;6355:1;6352;6345:12;6304:55;-1:-1:-1;6378:20:1;;6421:18;6410:30;;6407:50;;;6453:1;6450;6443:12;6407:50;6490:4;6482:6;6478:17;6466:29;;6542:3;6535:4;6526:6;6518;6514:19;6510:30;6507:39;6504:59;;;6559:1;6556;6549:12;6574:546;6654:6;6662;6670;6723:2;6711:9;6702:7;6698:23;6694:32;6691:52;;;6739:1;6736;6729:12;6691:52;6778:9;6765:23;6797:31;6822:5;6797:31;:::i;:::-;6847:5;-1:-1:-1;6903:2:1;6888:18;;6875:32;6930:18;6919:30;;6916:50;;;6962:1;6959;6952:12;6916:50;7001:59;7052:7;7043:6;7032:9;7028:22;7001:59;:::i;:::-;6574:546;;7079:8;;-1:-1:-1;6975:85:1;;-1:-1:-1;;;;6574:546:1:o;7125:478::-;7204:6;7212;7220;7273:2;7261:9;7252:7;7248:23;7244:32;7241:52;;;7289:1;7286;7279:12;7241:52;7325:9;7312:23;7302:33;;7386:2;7375:9;7371:18;7358:32;7413:18;7405:6;7402:30;7399:50;;;7445:1;7442;7435:12;7608:118;7694:5;7687:13;7680:21;7673:5;7670:32;7660:60;;7716:1;7713;7706:12;7731:382;7796:6;7804;7857:2;7845:9;7836:7;7832:23;7828:32;7825:52;;;7873:1;7870;7863:12;7825:52;7912:9;7899:23;7931:31;7956:5;7931:31;:::i;:::-;7981:5;-1:-1:-1;8038:2:1;8023:18;;8010:32;8051:30;8010:32;8051:30;:::i;8118:665::-;8213:6;8221;8229;8237;8290:3;8278:9;8269:7;8265:23;8261:33;8258:53;;;8307:1;8304;8297:12;8258:53;8346:9;8333:23;8365:31;8390:5;8365:31;:::i;:::-;8415:5;-1:-1:-1;8472:2:1;8457:18;;8444:32;8485:33;8444:32;8485:33;:::i;:::-;8537:7;-1:-1:-1;8591:2:1;8576:18;;8563:32;;-1:-1:-1;8646:2:1;8631:18;;8618:32;8673:18;8662:30;;8659:50;;;8705:1;8702;8695:12;8659:50;8728:49;8769:7;8760:6;8749:9;8745:22;8728:49;:::i;:::-;8718:59;;;8118:665;;;;;;;:::o;9589:377::-;9663:6;9671;9679;9732:2;9720:9;9711:7;9707:23;9703:32;9700:52;;;9748:1;9745;9738:12;9700:52;9784:9;9771:23;9761:33;;9841:2;9830:9;9826:18;9813:32;9803:42;;9895:2;9884:9;9880:18;9867:32;9908:28;9930:5;9908:28;:::i;:::-;9955:5;9945:15;;;9589:377;;;;;:::o;9971:380::-;10050:1;10046:12;;;;10093;;;10114:61;;10168:4;10160:6;10156:17;10146:27;;10114:61;10221:2;10213:6;10210:14;10190:18;10187:38;10184:161;;;10267:10;10262:3;10258:20;10255:1;10248:31;10302:4;10299:1;10292:15;10330:4;10327:1;10320:15;10184:161;;9971:380;;;:::o;11596:412::-;11798:2;11780:21;;;11837:2;11817:18;;;11810:30;11876:34;11871:2;11856:18;;11849:62;-1:-1:-1;;;11942:2:1;11927:18;;11920:46;11998:3;11983:19;;11596:412::o;12013:637::-;-1:-1:-1;;12350:2:1;12346:15;;;12342:24;;12330:37;;-1:-1:-1;;;;;;12397:33:1;;;;12392:2;12383:12;;12376:55;12465:15;;;12461:24;;12456:2;12447:12;;12440:46;12520:15;;;12516:24;;;12511:2;12502:12;;12495:46;12566:2;12557:12;;12550:28;;;;12594:12;;;12587:28;12640:3;12631:13;;12013:637::o;12655:413::-;12857:2;12839:21;;;12896:2;12876:18;;;12869:30;12935:34;12930:2;12915:18;;12908:62;-1:-1:-1;;;13001:2:1;12986:18;;12979:47;13058:3;13043:19;;12655:413::o;13073:335::-;13275:2;13257:21;;;13314:2;13294:18;;;13287:30;-1:-1:-1;;;13348:2:1;13333:18;;13326:41;13399:2;13384:18;;13073:335::o;13413:251::-;13483:6;13536:2;13524:9;13515:7;13511:23;13507:32;13504:52;;;13552:1;13549;13542:12;13504:52;13584:9;13578:16;13603:31;13628:5;13603:31;:::i;13669:407::-;13871:2;13853:21;;;13910:2;13890:18;;;13883:30;13949:34;13944:2;13929:18;;13922:62;-1:-1:-1;;;14015:2:1;14000:18;;13993:41;14066:3;14051:19;;13669:407::o;14081:127::-;14142:10;14137:3;14133:20;14130:1;14123:31;14173:4;14170:1;14163:15;14197:4;14194:1;14187:15;14213:135;14252:3;-1:-1:-1;;14273:17:1;;14270:43;;;14293:18;;:::i;:::-;-1:-1:-1;14340:1:1;14329:13;;14213:135::o;14706:127::-;14767:10;14762:3;14758:20;14755:1;14748:31;14798:4;14795:1;14788:15;14822:4;14819:1;14812:15;14838:346;15040:2;15022:21;;;15079:2;15059:18;;;15052:30;-1:-1:-1;;;15113:2:1;15098:18;;15091:52;15175:2;15160:18;;14838:346::o;15189:418::-;15391:2;15373:21;;;15430:2;15410:18;;;15403:30;15469:34;15464:2;15449:18;;15442:62;-1:-1:-1;;;15535:2:1;15520:18;;15513:52;15597:3;15582:19;;15189:418::o;15612:184::-;15682:6;15735:2;15723:9;15714:7;15710:23;15706:32;15703:52;;;15751:1;15748;15741:12;15703:52;-1:-1:-1;15774:16:1;;15612:184;-1:-1:-1;15612:184:1:o;16080:245::-;16147:6;16200:2;16188:9;16179:7;16175:23;16171:32;16168:52;;;16216:1;16213;16206:12;16168:52;16248:9;16242:16;16267:28;16289:5;16267:28;:::i;17858:125::-;17898:4;17926:1;17923;17920:8;17917:34;;;17931:18;;:::i;:::-;-1:-1:-1;17968:9:1;;17858:125::o;17988:128::-;18028:3;18059:1;18055:6;18052:1;18049:13;18046:39;;;18065:18;;:::i;:::-;-1:-1:-1;18101:9:1;;17988:128::o;18480:390::-;18639:2;18628:9;18621:21;18678:6;18673:2;18662:9;18658:18;18651:34;18735:6;18727;18722:2;18711:9;18707:18;18694:48;18791:1;18762:22;;;18786:2;18758:31;;;18751:42;;;;18854:2;18833:15;;;-1:-1:-1;;18829:29:1;18814:45;18810:54;;18480:390;-1:-1:-1;18480:390:1:o;21372:470::-;21551:3;21589:6;21583:13;21605:53;21651:6;21646:3;21639:4;21631:6;21627:17;21605:53;:::i;:::-;21721:13;;21680:16;;;;21743:57;21721:13;21680:16;21777:4;21765:17;;21743:57;:::i;:::-;21816:20;;21372:470;-1:-1:-1;;;;21372:470:1:o;24994:635::-;25074:6;25127:2;25115:9;25106:7;25102:23;25098:32;25095:52;;;25143:1;25140;25133:12;25095:52;25176:9;25170:16;25209:18;25201:6;25198:30;25195:50;;;25241:1;25238;25231:12;25195:50;25264:22;;25317:4;25309:13;;25305:27;-1:-1:-1;25295:55:1;;25346:1;25343;25336:12;25295:55;25375:2;25369:9;25400:48;25416:31;25444:2;25416:31;:::i;25400:48::-;25471:2;25464:5;25457:17;25511:7;25506:2;25501;25497;25493:11;25489:20;25486:33;25483:53;;;25532:1;25529;25522:12;25483:53;25545:54;25596:2;25591;25584:5;25580:14;25575:2;25571;25567:11;25545:54;:::i;:::-;25618:5;24994:635;-1:-1:-1;;;;;24994:635:1:o;25634:638::-;25914:3;25952:6;25946:13;25968:53;26014:6;26009:3;26002:4;25994:6;25990:17;25968:53;:::i;:::-;26084:13;;26043:16;;;;26106:57;26084:13;26043:16;26140:4;26128:17;;26106:57;:::i;:::-;-1:-1:-1;;;26185:20:1;;26214:23;;;26264:1;26253:13;;25634:638;-1:-1:-1;;;;25634:638:1:o;26277:414::-;26479:2;26461:21;;;26518:2;26498:18;;;26491:30;26557:34;26552:2;26537:18;;26530:62;-1:-1:-1;;;26623:2:1;26608:18;;26601:48;26681:3;26666:19;;26277:414::o;26696:127::-;26757:10;26752:3;26748:20;26745:1;26738:31;26788:4;26785:1;26778:15;26812:4;26809:1;26802:15;26828:120;26868:1;26894;26884:35;;26899:18;;:::i;:::-;-1:-1:-1;26933:9:1;;26828:120::o;26953:112::-;26985:1;27011;27001:35;;27016:18;;:::i;:::-;-1:-1:-1;27050:9:1;;26953:112::o;28988:489::-;-1:-1:-1;;;;;29257:15:1;;;29239:34;;29309:15;;29304:2;29289:18;;29282:43;29356:2;29341:18;;29334:34;;;29404:3;29399:2;29384:18;;29377:31;;;29182:4;;29425:46;;29451:19;;29443:6;29425:46;:::i;:::-;29417:54;28988:489;-1:-1:-1;;;;;;28988:489:1:o;29482:249::-;29551:6;29604:2;29592:9;29583:7;29579:23;29575:32;29572:52;;;29620:1;29617;29610:12;29572:52;29652:9;29646:16;29671:30;29695:5;29671:30;:::i

Swarm Source

ipfs://8c2fd9a319703610b04fbe47ca2159e76c0a429ecacb56498aba3fe139c0c07c
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.