ETH Price: $3,456.59 (-0.77%)
Gas: 2 Gwei

Token

Crypto stamp Edition 3 (CS3)
 

Overview

Max Total Supply

100,000 CS3

Holders

47

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
4 CS3
0x9dcf2c97d88bb1e69ff6adcac15f2a2acc7c9070
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:
Cryptostamp3L1

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-06-02
*/

/*
 * Crypto stamp 3.0 (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;

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

/**
 * @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 {
    /**
     * @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) {
        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // 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) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
        } else if (signature.length == 64) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let vs := mload(add(signature, 0x40))
                r := mload(add(signature, 0x20))
                s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                v := add(shr(255, vs), 27)
            }
        } else {
            revert("ECDSA: invalid signature length");
        }

        return recover(hash, v, r, s);
    }

    /**
     * @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) {
        // 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 (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): 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.
        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
        require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

    /**
     * @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;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

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

/*
 * Interface for CS3 properties.
 */

interface CS3PropertiesI {

    enum AssetType {
        Whale
    }

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

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

contract Cryptostamp3L1 is ERC721NME_EnumerableSimple, CS3PropertiesI, ERC721SettablePropertiesI {

    BridgeDataI public bridgeData;

    uint256 immutable finalSupply;
    uint256 constant maxSupportedSupply = 2 ** 24;
    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)
    ERC721NME("Crypto stamp Edition 3", "CS3")
    {
        bridgeData = BridgeDataI(_bridgeDataAddress);
        require(address(bridgeData) != address(0x0), "You need to provide an actual bridge data contract.");
        finalSupply = _finalSupply;
        require(_finalSupply <= maxSupportedSupply, "The final supply is too high.");
    }

    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)
    public
    onlyCreateControl
    {
        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++) {
            emit Transfer(address(0), tokenHolder, i);
        }
    }

    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.");
        return AssetType.Whale;
    }

    // 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, mint even has to
            // be sent via virtualMintSeries() beforehand!
            _mint(_to, _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"}],"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 CS3PropertiesI.SColors","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getType","outputs":[{"internalType":"enum CS3PropertiesI.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":[{"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"}],"name":"virtualMintSeries","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b50604051620038d3380380620038d383398101604081905262000034916200024f565b604080518082018252601681527f43727970746f207374616d702045646974696f6e20330000000000000000000060208083019182528351808501909452600384526243533360e81b9084015281519192916200009491600091620001a9565b508051620000aa906001906020840190620001a9565b5050600980546001600160a01b0319166001600160a01b03851690811790915515159050620001465760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527f69646765206461746120636f6e74726163742e0000000000000000000000000060648201526084015b60405180910390fd5b60808190526301000000811115620001a15760405162461bcd60e51b815260206004820152601d60248201527f5468652066696e616c20737570706c7920697320746f6f20686967682e00000060448201526064016200013d565b5050620002c6565b828054620001b79062000289565b90600052602060002090601f016020900481019282620001db576000855562000226565b82601f10620001f657805160ff191683800117855562000226565b8280016001018555821562000226579182015b828111156200022657825182559160200191906001019062000209565b506200023492915062000238565b5090565b5b8082111562000234576000815560010162000239565b6000806040838503121562000262578182fd5b82516001600160a01b038116811462000279578283fd5b6020939093015192949293505050565b600181811c908216806200029e57607f821691505b60208210811415620002c057634e487b7160e01b600052602260045260246000fd5b50919050565b6080516135a46200032f6000396000818161027c0152818161057b015281816109300152818161097801528181610a4301528181610d2201528181610d4901528181610f9f015281816111280152818161192101528181611a370152611e8c01526135a46000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80634f6ccce71161010f5780638f22332f116100a2578063b88d4fde11610071578063b88d4fde14610441578063c87b56dd14610454578063dd48f77414610467578063e985e9c51461047a57600080fd5b80638f22332f1461040057806395d89b4114610413578063a22cb4651461041b578063b6b7b82b1461042e57600080fd5b80636c0360eb116100de5780636c0360eb146103bf57806370a08231146103c757806371f03793146103da5780638e8fa11f146103ed57600080fd5b80634f6ccce71461036457806353a1397c1461037757806353cdef02146103995780636352211e146103ac57600080fd5b80632481bb5c1161018757806342842e0e1161015657806342842e0e146103235780634707d000146103365780634cd412d5146103495780634f558e791461035157600080fd5b80632481bb5c146102bd5780632f745c59146102d057806333c186fd146102e35780634036ab781461030357600080fd5b8063095ea7b3116101c3578063095ea7b3146102525780630f5746251461026757806318160ddd1461027a57806323b872dd146102aa57600080fd5b806301ffc9a7146101ea57806306fdde0314610212578063081812fc14610227575b600080fd5b6101fd6101f8366004612ebc565b6104b6565b60405190151581526020015b60405180910390f35b61021a6104e1565b60405161020991906131ac565b61023a610235366004612f70565b610573565b6040516001600160a01b039091168152602001610209565b610265610260366004612e5d565b610620565b005b610265610275366004612f88565b610736565b7f00000000000000000000000000000000000000000000000000000000000000005b604051908152602001610209565b6102656102b8366004612d33565b6107d6565b60095461023a906001600160a01b031681565b61029c6102de366004612e5d565b610807565b6102f66102f1366004612f70565b610970565b6040516102099190613169565b610316610311366004612f70565b610a3b565b604051610209919061314f565b610265610331366004612d33565b610ab5565b610265610344366004612ef4565b610ad0565b6101fd610c7d565b6101fd61035f366004612f70565b610d1a565b61029c610372366004612f70565b610d45565b61029c610385366004612cc3565b6208000a6020526000908152604090205481565b6102656103a7366004612cc3565b610dba565b61023a6103ba366004612f70565b610f97565b61021a61106f565b61029c6103d5366004612cc3565b61107e565b6102656103e8366004612f88565b61115f565b6102656103fb366004612e0a565b6111d3565b61026561040e366004612fdf565b61135d565b61021a6116ad565b610265610429366004612ddd565b6116bc565b61026561043c366004613010565b611781565b61026561044f366004612d73565b6119fd565b61021a610462366004612f70565b611a2f565b610265610475366004612ef4565b611b19565b6101fd610488366004612cfb565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b0319821663780e9d6360e01b14806104db57506104db82611c2d565b92915050565b6060600080546104f090613470565b80601f016020809104026020016040519081016040528092919081815260200182805461051c90613470565b80156105695780601f1061053e57610100808354040283529160200191610569565b820191906000526020600020905b81548152906001019060200180831161054c57829003601f168201915b5050505050905090565b600061059e827f00000000000000000000000000000000000000000000000000000000000000001190565b6106045760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061062b82610f97565b9050806001600160a01b0316836001600160a01b031614156106995760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016105fb565b336001600160a01b03821614806106b557506106b58133610488565b6107275760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016105fb565b6107318383611c7d565b505050565b61073e610c7d565b151560011461075f5760405162461bcd60e51b81526004016105fb906132b1565b600061076a84610f97565b6001600160a01b03811660009081526208000a6020908152604080832054905193945091926107aa923092630f57462560e01b92339288928c920161305d565b6040516020818303038152906040528051906020012090506107cf8282878787611ceb565b5050505050565b6107e03382611e84565b6107fc5760405162461bcd60e51b81526004016105fb90613357565b610731838383611f8e565b6000610812836120bd565b82101580156108af575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061084a906004016131bf565b60206040518083038186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089a9190612cdf565b6001600160a01b0316836001600160a01b0316145b1561095f576108bd8361107e565b82106108db5760405162461bcd60e51b81526004016105fb906131e4565b60006108e6846120bd565b905060005b6000818152600260205260409020546001600160a01b03166109215783821061091357610956565b8161091d816134ab565b9250505b8061092b816134ab565b9150507f000000000000000000000000000000000000000000000000000000000000000081106108eb575b91506104db9050565b6109698383612144565b9392505050565b600061099b827f00000000000000000000000000000000000000000000000000000000000000001190565b6109e25760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b60448201526064016105fb565b600a8263010000008110610a0657634e487b7160e01b600052603260045260246000fd5b602081049091015460ff601f9092166101000a90041660058111156104db57634e487b7160e01b600052602160045260246000fd5b6000610a66827f00000000000000000000000000000000000000000000000000000000000000001190565b610aad5760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b60448201526064016105fb565b506000919050565b610731838383604051806020016040528060008152506119fd565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610afe90600401613281565b60206040518083038186803b158015610b1657600080fd5b505afa158015610b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4e9190612cdf565b6001600160a01b0316336001600160a01b031614610b7e5760405162461bcd60e51b81526004016105fb90613301565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610bc757600080fd5b505afa158015610bdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bff9190612ea4565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610c4557600080fd5b505af1158015610c59573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107319190612e88565b600080600960009054906101000a90046001600160a01b03166001600160a01b031663a564a2e06040518163ffffffff1660e01b815260040160206040518083038186803b158015610cce57600080fd5b505afa158015610ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d069190612ea4565b9050801580610d1457504281115b91505090565b60006104db827f00000000000000000000000000000000000000000000000000000000000000001190565b60007f00000000000000000000000000000000000000000000000000000000000000008210610db65760405162461bcd60e51b815260206004820152601760248201527f496e646578206973206f7574206f6620626f756e64732e00000000000000000060448201526064016105fb565b5090565b60095460405163bf40fac160e01b815260206004820152600d60248201526c189c9a5919d950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b158015610e1b57600080fd5b505afa158015610e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e539190612cdf565b6001600160a01b0316336001600160a01b031614610ec95760405162461bcd60e51b815260206004820152602d60248201527f627269646765436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b60648201526084016105fb565b6001600160a01b038116610f3b5760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527234b233b2903230ba309031b7b73a3930b1ba1760691b60648201526084016105fb565b6009546040516001600160a01b038084169216907f6a6e057f21cc834cf349d8150e92867f52cb34d54375f174c09c431538c3dfb990600090a3600980546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fc2827f00000000000000000000000000000000000000000000000000000000000000001190565b8015610fe357506000828152600260205260409020546001600160a01b0316155b156110665760095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190611016906004016131bf565b60206040518083038186803b15801561102e57600080fd5b505afa158015611042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104db9190612cdf565b6104db82612196565b606061107961220d565b905090565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac1906110ad906004016131bf565b60206040518083038186803b1580156110c557600080fd5b505afa1580156110d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fd9190612cdf565b6001600160a01b0316826001600160a01b031614156111565761111f826120bd565b60085461114c907f000000000000000000000000000000000000000000000000000000000000000061342d565b6104db9190613401565b6104db826120bd565b611167610c7d565b15156001146111885760405162461bcd60e51b81526004016105fb906132b1565b600061119384610f97565b6001600160a01b03811660009081526208000a6020908152604080832054905193945091926107aa9230926371f0379360e01b9287928a928c920161305d565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061120190600401613281565b60206040518083038186803b15801561121957600080fd5b505afa15801561122d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112519190612cdf565b6001600160a01b0316336001600160a01b0316146112815760405162461bcd60e51b81526004016105fb90613301565b6001600160a01b0383166112d75760405162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c6964207265766572736520726567697374726172000060448201526064016105fb565b60405163c47f002760e01b81526001600160a01b0384169063c47f002790611305908590859060040161317d565b602060405180830381600087803b15801561131f57600080fd5b505af1158015611333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113579190612ea4565b50505050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b1580156113be57600080fd5b505afa1580156113d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f69190612cdf565b6001600160a01b0316336001600160a01b031614806114bb575060095460405163bf40fac160e01b815260206004820152600a602482015269189c9a5919d95219585960b21b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b15801561146e57600080fd5b505afa158015611482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a69190612cdf565b6001600160a01b0316336001600160a01b0316145b61152d5760405162461bcd60e51b815260206004820152603c60248201527f637265617465436f6e74726f6c206b6579206f7220627269646765206865616460448201527f20726571756972656420666f7220746869732066756e6374696f6e2e0000000060648201526084016105fb565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061155b906004016131bf565b60206040518083038186803b15801561157357600080fd5b505afa158015611587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ab9190612cdf565b6001600160a01b03166115bd84610f97565b6001600160a01b0316146116395760405162461bcd60e51b815260206004820152603b60248201527f4f6e6c792063616e207365742070726f7065727469657320666f7220746f6b6560448201527f6e73206f776e65642062792074686520746f6b656e486f6c646572000000000060648201526084016105fb565b8181600081811061165a57634e487b7160e01b600052603260045260246000fd5b919091013560f81c9050600a846301000000811061168857634e487b7160e01b600052603260045260246000fd5b602091828204019190066101000a81548160ff021916908360ff160217905550505050565b6060600180546104f090613470565b6001600160a01b0382163314156117155760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016105fb565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b1580156117e257600080fd5b505afa1580156117f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181a9190612cdf565b6001600160a01b0316336001600160a01b0316146118905760405162461bcd60e51b815260206004820152602d60248201527f637265617465436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b60648201526084016105fb565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac1906118bf906004016131bf565b60206040518083038186803b1580156118d757600080fd5b505afa1580156118eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190f9190612cdf565b9050600061191d8385613401565b90507f000000000000000000000000000000000000000000000000000000000000000081106119a95760405162461bcd60e51b815260206004820152603260248201527f43616e6e6f742073656e64206d696e74206576656e747320666f72206e6f6e2d6044820152716578697374696e6720746f6b656e2049447360701b60648201526084016105fb565b835b818110156107cf5760405181906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4806119f5816134ab565b9150506119ab565b611a073383611e84565b611a235760405162461bcd60e51b81526004016105fb90613357565b611357848484846122bb565b6060611a5a827f00000000000000000000000000000000000000000000000000000000000000001190565b611abe5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016105fb565b6000611ac861220d565b90506000815111611ae85760405180602001604052806000815250610969565b80611af2846122ee565b604051602001611b039291906130ad565b6040516020818303038152906040529392505050565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190611b4790600401613281565b60206040518083038186803b158015611b5f57600080fd5b505afa158015611b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b979190612cdf565b6001600160a01b0316336001600160a01b031614611bc75760405162461bcd60e51b81526004016105fb90613301565b60405163a22cb46560e01b81526001600160a01b0382811660048301526001602483015283169063a22cb46590604401600060405180830381600087803b158015611c1157600080fd5b505af1158015611c25573d6000803e3d6000fd5b505050505050565b60006001600160e01b031982166380ac58cd60e01b1480611c5e57506001600160e01b03198216635b5e139f60e01b145b806104db57506301ffc9a760e01b6001600160e01b03198316146104db565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611cb282610f97565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d44856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000611d528284612408565b9050866001600160a01b0316816001600160a01b031614611ddb5760405162461bcd60e51b815260206004820152603e60248201527f5369676e6174757265206e6565647320746f206d6174636820706172616d657460448201527f6572732c206e6f6e63652c20616e642063757272656e74206f776e65722e000060648201526084016105fb565b6001600160a01b0387811660008181526208000a6020908152604091829020548251338152918201528893881692917fba05f551fcc429cba611372aa0055e3573f26273f66d1a48bdb5b4f7896bf022910160405180910390a46001600160a01b03871660009081526208000a60205260408120805491611e5b836134ab565b9190505550611e7b878587604051806020016040528060008152506122bb565b50505050505050565b6000611eaf827f00000000000000000000000000000000000000000000000000000000000000001190565b611f105760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016105fb565b6000611f1b83610f97565b9050806001600160a01b0316846001600160a01b03161480611f565750836001600160a01b0316611f4b84610573565b6001600160a01b0316145b80611f8657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b6000818152600260205260409020546001600160a01b0316158015612041575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190611fdc906004016131bf565b60206040518083038186803b158015611ff457600080fd5b505afa158015612008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202c9190612cdf565b6001600160a01b0316836001600160a01b0316145b801561205257506120523382611e84565b156120b257612062600082611c7d565b61206c82826124be565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6107318383836125e1565b60006001600160a01b0382166121285760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016105fb565b506001600160a01b031660009081526003602052604090205490565b600061214f836120bd565b821061216d5760405162461bcd60e51b81526004016105fb906131e4565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6000818152600260205260408120546001600160a01b0316806104db5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016105fb565b6009546040805163261220a360e01b815290516060926001600160a01b03169163261220a3916004808301926000929190829003018186803b15801561225257600080fd5b505afa158015612266573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261228e9190810190612f06565b6122966116ad565b6040516020016122a79291906130dc565b604051602081830303815290604052905090565b6122c6848484611f8e565b6122d28484848461278c565b6113575760405162461bcd60e51b81526004016105fb9061322f565b6060816123125750506040805180820190915260018152600360fc1b602082015290565b8160005b811561233c5780612326816134ab565b91506123359050600a83613419565b9150612316565b60008167ffffffffffffffff81111561236557634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561238f576020820181803683370190505b5090505b8415611f86576123a460018361342d565b91506123b1600a866134c6565b6123bc906030613401565b60f81b8183815181106123df57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612401600a86613419565b9450612393565b6000806000808451604114156124325750505060208201516040830151606084015160001a6124a8565b8451604014156124605750505060408201516020830151906001600160ff1b0381169060ff1c601b016124a8565b60405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105fb565b6124b486828585612899565b9695505050505050565b6001600160a01b0382166125145760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016105fb565b6000818152600260205260409020546001600160a01b0316156125795760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016105fb565b61258560008383612a42565b6001600160a01b03821660009081526003602052604081208054600192906125ae908490613401565b9091555050600090815260026020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b826001600160a01b03166125f482612196565b6001600160a01b03161461265c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016105fb565b6001600160a01b0382166126be5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016105fb565b6126c9838383612a42565b6126d4600082611c7d565b6001600160a01b03831660009081526003602052604081208054600192906126fd90849061342d565b90915550506001600160a01b038216600090815260036020526040812080546001929061272b908490613401565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006001600160a01b0384163b1561288e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906127d090339089908890889060040161311c565b602060405180830381600087803b1580156127ea57600080fd5b505af192505050801561281a575060408051601f3d908101601f1916820190925261281791810190612ed8565b60015b612874573d808015612848576040519150601f19603f3d011682016040523d82523d6000602084013e61284d565b606091505b50805161286c5760405162461bcd60e51b81526004016105fb9061322f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611f86565b506001949350505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156129165760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105fb565b8360ff16601b148061292b57508360ff16601c145b6129825760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016105fb565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa1580156129d6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612a395760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105fb565b95945050505050565b612a4a610c7d565b1515600114612a6b5760405162461bcd60e51b81526004016105fb906132b1565b6107318383836001600160a01b038316612a8d57612a8881612aea565b612ab0565b816001600160a01b0316836001600160a01b031614612ab057612ab08382612b02565b6001600160a01b038216612ac75761073181612b9f565b826001600160a01b0316826001600160a01b031614610731576107318282612be7565b60088054906000612afa836134ab565b919050555050565b60006001612b0f846120bd565b612b19919061342d565b600083815260076020526040902054909150808214612b6c576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60405162461bcd60e51b815260206004820152601c60248201527f5468697320746f6b656e2063616e6e6f74206265206275726e65642e0000000060448201526064016105fb565b6000612bf2836120bd565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008083601f840112612c3c578182fd5b50813567ffffffffffffffff811115612c53578182fd5b602083019150836020828501011115612c6b57600080fd5b9250929050565b600082601f830112612c82578081fd5b8135612c95612c90826133d9565b6133a8565b818152846020838601011115612ca9578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612cd4578081fd5b813561096981613532565b600060208284031215612cf0578081fd5b815161096981613532565b60008060408385031215612d0d578081fd5b8235612d1881613532565b91506020830135612d2881613532565b809150509250929050565b600080600060608486031215612d47578081fd5b8335612d5281613532565b92506020840135612d6281613532565b929592945050506040919091013590565b60008060008060808587031215612d88578081fd5b8435612d9381613532565b93506020850135612da381613532565b925060408501359150606085013567ffffffffffffffff811115612dc5578182fd5b612dd187828801612c72565b91505092959194509250565b60008060408385031215612def578182fd5b8235612dfa81613532565b91506020830135612d288161354a565b600080600060408486031215612e1e578283fd5b8335612e2981613532565b9250602084013567ffffffffffffffff811115612e44578283fd5b612e5086828701612c2b565b9497909650939450505050565b60008060408385031215612e6f578182fd5b8235612e7a81613532565b946020939093013593505050565b600060208284031215612e99578081fd5b81516109698161354a565b600060208284031215612eb5578081fd5b5051919050565b600060208284031215612ecd578081fd5b813561096981613558565b600060208284031215612ee9578081fd5b815161096981613558565b60008060408385031215612d0d578182fd5b600060208284031215612f17578081fd5b815167ffffffffffffffff811115612f2d578182fd5b8201601f81018413612f3d578182fd5b8051612f4b612c90826133d9565b818152856020838501011115612f5f578384fd5b612a39826020830160208601613444565b600060208284031215612f81578081fd5b5035919050565b600080600060608486031215612f9c578081fd5b833592506020840135612fae81613532565b9150604084013567ffffffffffffffff811115612fc9578182fd5b612fd586828701612c72565b9150509250925092565b600080600060408486031215612ff3578081fd5b83359250602084013567ffffffffffffffff811115612e44578182fd5b60008060408385031215613022578182fd5b50508035926020909101359150565b60008151808452613049816020860160208601613444565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff19606097881b811682526001600160e01b031996909616601482015293861b8516601885015291851b909316602c83015260408201929092529182015260800190565b600083516130bf818460208801613444565b8351908301906130d3818360208801613444565b01949350505050565b600083516130ee818460208801613444565b835190830190613102818360208801613444565b652f6d6574612f60d01b9101908152600601949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906124b490830184613031565b602081016001831061316357613163613506565b91905290565b602081016006831061316357613163613506565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6020815260006109696020830184613031565b6020808252600b908201526a3a37b5b2b72437b63232b960a91b604082015260600190565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601690820152751d1bdad95b905cdcda59db9b595b9d10dbdb9d1c9bdb60521b604082015260600190565b60208082526030908201527f546869732063616c6c206f6e6c7920776f726b73207768656e207472616e736660408201526f32b9399030b9329032b730b13632b21760811b606082015260800190565b60208082526036908201527f746f6b656e41737369676e6d656e74436f6e74726f6c206b65792072657175696040820152753932b2103337b9103a3434b990333ab731ba34b7b71760511b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff811182821017156133d1576133d161351c565b604052919050565b600067ffffffffffffffff8211156133f3576133f361351c565b50601f01601f191660200190565b60008219821115613414576134146134da565b500190565b600082613428576134286134f0565b500490565b60008282101561343f5761343f6134da565b500390565b60005b8381101561345f578181015183820152602001613447565b838111156113575750506000910152565b600181811c9082168061348457607f821691505b602082108114156134a557634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156134bf576134bf6134da565b5060010190565b6000826134d5576134d56134f0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461354757600080fd5b50565b801515811461354757600080fd5b6001600160e01b03198116811461354757600080fdfea26469706673582212204e8b63f6716a82b312264e20523b3f70eac98bd14e3023425ac2f26677c7192c64736f6c634300080400330000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c500000000000000000000000000000000000000000000000000000000000186a0

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80634f6ccce71161010f5780638f22332f116100a2578063b88d4fde11610071578063b88d4fde14610441578063c87b56dd14610454578063dd48f77414610467578063e985e9c51461047a57600080fd5b80638f22332f1461040057806395d89b4114610413578063a22cb4651461041b578063b6b7b82b1461042e57600080fd5b80636c0360eb116100de5780636c0360eb146103bf57806370a08231146103c757806371f03793146103da5780638e8fa11f146103ed57600080fd5b80634f6ccce71461036457806353a1397c1461037757806353cdef02146103995780636352211e146103ac57600080fd5b80632481bb5c1161018757806342842e0e1161015657806342842e0e146103235780634707d000146103365780634cd412d5146103495780634f558e791461035157600080fd5b80632481bb5c146102bd5780632f745c59146102d057806333c186fd146102e35780634036ab781461030357600080fd5b8063095ea7b3116101c3578063095ea7b3146102525780630f5746251461026757806318160ddd1461027a57806323b872dd146102aa57600080fd5b806301ffc9a7146101ea57806306fdde0314610212578063081812fc14610227575b600080fd5b6101fd6101f8366004612ebc565b6104b6565b60405190151581526020015b60405180910390f35b61021a6104e1565b60405161020991906131ac565b61023a610235366004612f70565b610573565b6040516001600160a01b039091168152602001610209565b610265610260366004612e5d565b610620565b005b610265610275366004612f88565b610736565b7f00000000000000000000000000000000000000000000000000000000000186a05b604051908152602001610209565b6102656102b8366004612d33565b6107d6565b60095461023a906001600160a01b031681565b61029c6102de366004612e5d565b610807565b6102f66102f1366004612f70565b610970565b6040516102099190613169565b610316610311366004612f70565b610a3b565b604051610209919061314f565b610265610331366004612d33565b610ab5565b610265610344366004612ef4565b610ad0565b6101fd610c7d565b6101fd61035f366004612f70565b610d1a565b61029c610372366004612f70565b610d45565b61029c610385366004612cc3565b6208000a6020526000908152604090205481565b6102656103a7366004612cc3565b610dba565b61023a6103ba366004612f70565b610f97565b61021a61106f565b61029c6103d5366004612cc3565b61107e565b6102656103e8366004612f88565b61115f565b6102656103fb366004612e0a565b6111d3565b61026561040e366004612fdf565b61135d565b61021a6116ad565b610265610429366004612ddd565b6116bc565b61026561043c366004613010565b611781565b61026561044f366004612d73565b6119fd565b61021a610462366004612f70565b611a2f565b610265610475366004612ef4565b611b19565b6101fd610488366004612cfb565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b0319821663780e9d6360e01b14806104db57506104db82611c2d565b92915050565b6060600080546104f090613470565b80601f016020809104026020016040519081016040528092919081815260200182805461051c90613470565b80156105695780601f1061053e57610100808354040283529160200191610569565b820191906000526020600020905b81548152906001019060200180831161054c57829003601f168201915b5050505050905090565b600061059e827f00000000000000000000000000000000000000000000000000000000000186a01190565b6106045760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061062b82610f97565b9050806001600160a01b0316836001600160a01b031614156106995760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016105fb565b336001600160a01b03821614806106b557506106b58133610488565b6107275760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016105fb565b6107318383611c7d565b505050565b61073e610c7d565b151560011461075f5760405162461bcd60e51b81526004016105fb906132b1565b600061076a84610f97565b6001600160a01b03811660009081526208000a6020908152604080832054905193945091926107aa923092630f57462560e01b92339288928c920161305d565b6040516020818303038152906040528051906020012090506107cf8282878787611ceb565b5050505050565b6107e03382611e84565b6107fc5760405162461bcd60e51b81526004016105fb90613357565b610731838383611f8e565b6000610812836120bd565b82101580156108af575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061084a906004016131bf565b60206040518083038186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089a9190612cdf565b6001600160a01b0316836001600160a01b0316145b1561095f576108bd8361107e565b82106108db5760405162461bcd60e51b81526004016105fb906131e4565b60006108e6846120bd565b905060005b6000818152600260205260409020546001600160a01b03166109215783821061091357610956565b8161091d816134ab565b9250505b8061092b816134ab565b9150507f00000000000000000000000000000000000000000000000000000000000186a081106108eb575b91506104db9050565b6109698383612144565b9392505050565b600061099b827f00000000000000000000000000000000000000000000000000000000000186a01190565b6109e25760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b60448201526064016105fb565b600a8263010000008110610a0657634e487b7160e01b600052603260045260246000fd5b602081049091015460ff601f9092166101000a90041660058111156104db57634e487b7160e01b600052602160045260246000fd5b6000610a66827f00000000000000000000000000000000000000000000000000000000000186a01190565b610aad5760405162461bcd60e51b81526020600482015260186024820152772a37b5b2b71024a2103732b2b239903a379032bc34b9ba1760411b60448201526064016105fb565b506000919050565b610731838383604051806020016040528060008152506119fd565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610afe90600401613281565b60206040518083038186803b158015610b1657600080fd5b505afa158015610b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4e9190612cdf565b6001600160a01b0316336001600160a01b031614610b7e5760405162461bcd60e51b81526004016105fb90613301565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610bc757600080fd5b505afa158015610bdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bff9190612ea4565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610c4557600080fd5b505af1158015610c59573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107319190612e88565b600080600960009054906101000a90046001600160a01b03166001600160a01b031663a564a2e06040518163ffffffff1660e01b815260040160206040518083038186803b158015610cce57600080fd5b505afa158015610ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d069190612ea4565b9050801580610d1457504281115b91505090565b60006104db827f00000000000000000000000000000000000000000000000000000000000186a01190565b60007f00000000000000000000000000000000000000000000000000000000000186a08210610db65760405162461bcd60e51b815260206004820152601760248201527f496e646578206973206f7574206f6620626f756e64732e00000000000000000060448201526064016105fb565b5090565b60095460405163bf40fac160e01b815260206004820152600d60248201526c189c9a5919d950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b158015610e1b57600080fd5b505afa158015610e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e539190612cdf565b6001600160a01b0316336001600160a01b031614610ec95760405162461bcd60e51b815260206004820152602d60248201527f627269646765436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b60648201526084016105fb565b6001600160a01b038116610f3b5760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527234b233b2903230ba309031b7b73a3930b1ba1760691b60648201526084016105fb565b6009546040516001600160a01b038084169216907f6a6e057f21cc834cf349d8150e92867f52cb34d54375f174c09c431538c3dfb990600090a3600980546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fc2827f00000000000000000000000000000000000000000000000000000000000186a01190565b8015610fe357506000828152600260205260409020546001600160a01b0316155b156110665760095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190611016906004016131bf565b60206040518083038186803b15801561102e57600080fd5b505afa158015611042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104db9190612cdf565b6104db82612196565b606061107961220d565b905090565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac1906110ad906004016131bf565b60206040518083038186803b1580156110c557600080fd5b505afa1580156110d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fd9190612cdf565b6001600160a01b0316826001600160a01b031614156111565761111f826120bd565b60085461114c907f00000000000000000000000000000000000000000000000000000000000186a061342d565b6104db9190613401565b6104db826120bd565b611167610c7d565b15156001146111885760405162461bcd60e51b81526004016105fb906132b1565b600061119384610f97565b6001600160a01b03811660009081526208000a6020908152604080832054905193945091926107aa9230926371f0379360e01b9287928a928c920161305d565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061120190600401613281565b60206040518083038186803b15801561121957600080fd5b505afa15801561122d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112519190612cdf565b6001600160a01b0316336001600160a01b0316146112815760405162461bcd60e51b81526004016105fb90613301565b6001600160a01b0383166112d75760405162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c6964207265766572736520726567697374726172000060448201526064016105fb565b60405163c47f002760e01b81526001600160a01b0384169063c47f002790611305908590859060040161317d565b602060405180830381600087803b15801561131f57600080fd5b505af1158015611333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113579190612ea4565b50505050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b1580156113be57600080fd5b505afa1580156113d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f69190612cdf565b6001600160a01b0316336001600160a01b031614806114bb575060095460405163bf40fac160e01b815260206004820152600a602482015269189c9a5919d95219585960b21b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b15801561146e57600080fd5b505afa158015611482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a69190612cdf565b6001600160a01b0316336001600160a01b0316145b61152d5760405162461bcd60e51b815260206004820152603c60248201527f637265617465436f6e74726f6c206b6579206f7220627269646765206865616460448201527f20726571756972656420666f7220746869732066756e6374696f6e2e0000000060648201526084016105fb565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061155b906004016131bf565b60206040518083038186803b15801561157357600080fd5b505afa158015611587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ab9190612cdf565b6001600160a01b03166115bd84610f97565b6001600160a01b0316146116395760405162461bcd60e51b815260206004820152603b60248201527f4f6e6c792063616e207365742070726f7065727469657320666f7220746f6b6560448201527f6e73206f776e65642062792074686520746f6b656e486f6c646572000000000060648201526084016105fb565b8181600081811061165a57634e487b7160e01b600052603260045260246000fd5b919091013560f81c9050600a846301000000811061168857634e487b7160e01b600052603260045260246000fd5b602091828204019190066101000a81548160ff021916908360ff160217905550505050565b6060600180546104f090613470565b6001600160a01b0382163314156117155760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016105fb565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60095460405163bf40fac160e01b815260206004820152600d60248201526c18dc99585d1950dbdb9d1c9bdb609a1b60448201526001600160a01b039091169063bf40fac19060640160206040518083038186803b1580156117e257600080fd5b505afa1580156117f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181a9190612cdf565b6001600160a01b0316336001600160a01b0316146118905760405162461bcd60e51b815260206004820152602d60248201527f637265617465436f6e74726f6c206b657920726571756972656420666f72207460448201526c3434b990333ab731ba34b7b71760991b60648201526084016105fb565b60095460405163bf40fac160e01b81526000916001600160a01b03169063bf40fac1906118bf906004016131bf565b60206040518083038186803b1580156118d757600080fd5b505afa1580156118eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190f9190612cdf565b9050600061191d8385613401565b90507f00000000000000000000000000000000000000000000000000000000000186a081106119a95760405162461bcd60e51b815260206004820152603260248201527f43616e6e6f742073656e64206d696e74206576656e747320666f72206e6f6e2d6044820152716578697374696e6720746f6b656e2049447360701b60648201526084016105fb565b835b818110156107cf5760405181906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4806119f5816134ab565b9150506119ab565b611a073383611e84565b611a235760405162461bcd60e51b81526004016105fb90613357565b611357848484846122bb565b6060611a5a827f00000000000000000000000000000000000000000000000000000000000186a01190565b611abe5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016105fb565b6000611ac861220d565b90506000815111611ae85760405180602001604052806000815250610969565b80611af2846122ee565b604051602001611b039291906130ad565b6040516020818303038152906040529392505050565b60095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190611b4790600401613281565b60206040518083038186803b158015611b5f57600080fd5b505afa158015611b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b979190612cdf565b6001600160a01b0316336001600160a01b031614611bc75760405162461bcd60e51b81526004016105fb90613301565b60405163a22cb46560e01b81526001600160a01b0382811660048301526001602483015283169063a22cb46590604401600060405180830381600087803b158015611c1157600080fd5b505af1158015611c25573d6000803e3d6000fd5b505050505050565b60006001600160e01b031982166380ac58cd60e01b1480611c5e57506001600160e01b03198216635b5e139f60e01b145b806104db57506301ffc9a760e01b6001600160e01b03198316146104db565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611cb282610f97565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d44856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000611d528284612408565b9050866001600160a01b0316816001600160a01b031614611ddb5760405162461bcd60e51b815260206004820152603e60248201527f5369676e6174757265206e6565647320746f206d6174636820706172616d657460448201527f6572732c206e6f6e63652c20616e642063757272656e74206f776e65722e000060648201526084016105fb565b6001600160a01b0387811660008181526208000a6020908152604091829020548251338152918201528893881692917fba05f551fcc429cba611372aa0055e3573f26273f66d1a48bdb5b4f7896bf022910160405180910390a46001600160a01b03871660009081526208000a60205260408120805491611e5b836134ab565b9190505550611e7b878587604051806020016040528060008152506122bb565b50505050505050565b6000611eaf827f00000000000000000000000000000000000000000000000000000000000186a01190565b611f105760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016105fb565b6000611f1b83610f97565b9050806001600160a01b0316846001600160a01b03161480611f565750836001600160a01b0316611f4b84610573565b6001600160a01b0316145b80611f8657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b6000818152600260205260409020546001600160a01b0316158015612041575060095460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190611fdc906004016131bf565b60206040518083038186803b158015611ff457600080fd5b505afa158015612008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202c9190612cdf565b6001600160a01b0316836001600160a01b0316145b801561205257506120523382611e84565b156120b257612062600082611c7d565b61206c82826124be565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6107318383836125e1565b60006001600160a01b0382166121285760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016105fb565b506001600160a01b031660009081526003602052604090205490565b600061214f836120bd565b821061216d5760405162461bcd60e51b81526004016105fb906131e4565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6000818152600260205260408120546001600160a01b0316806104db5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016105fb565b6009546040805163261220a360e01b815290516060926001600160a01b03169163261220a3916004808301926000929190829003018186803b15801561225257600080fd5b505afa158015612266573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261228e9190810190612f06565b6122966116ad565b6040516020016122a79291906130dc565b604051602081830303815290604052905090565b6122c6848484611f8e565b6122d28484848461278c565b6113575760405162461bcd60e51b81526004016105fb9061322f565b6060816123125750506040805180820190915260018152600360fc1b602082015290565b8160005b811561233c5780612326816134ab565b91506123359050600a83613419565b9150612316565b60008167ffffffffffffffff81111561236557634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561238f576020820181803683370190505b5090505b8415611f86576123a460018361342d565b91506123b1600a866134c6565b6123bc906030613401565b60f81b8183815181106123df57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612401600a86613419565b9450612393565b6000806000808451604114156124325750505060208201516040830151606084015160001a6124a8565b8451604014156124605750505060408201516020830151906001600160ff1b0381169060ff1c601b016124a8565b60405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105fb565b6124b486828585612899565b9695505050505050565b6001600160a01b0382166125145760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016105fb565b6000818152600260205260409020546001600160a01b0316156125795760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016105fb565b61258560008383612a42565b6001600160a01b03821660009081526003602052604081208054600192906125ae908490613401565b9091555050600090815260026020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b826001600160a01b03166125f482612196565b6001600160a01b03161461265c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016105fb565b6001600160a01b0382166126be5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016105fb565b6126c9838383612a42565b6126d4600082611c7d565b6001600160a01b03831660009081526003602052604081208054600192906126fd90849061342d565b90915550506001600160a01b038216600090815260036020526040812080546001929061272b908490613401565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006001600160a01b0384163b1561288e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906127d090339089908890889060040161311c565b602060405180830381600087803b1580156127ea57600080fd5b505af192505050801561281a575060408051601f3d908101601f1916820190925261281791810190612ed8565b60015b612874573d808015612848576040519150601f19603f3d011682016040523d82523d6000602084013e61284d565b606091505b50805161286c5760405162461bcd60e51b81526004016105fb9061322f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611f86565b506001949350505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156129165760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105fb565b8360ff16601b148061292b57508360ff16601c145b6129825760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016105fb565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa1580156129d6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612a395760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105fb565b95945050505050565b612a4a610c7d565b1515600114612a6b5760405162461bcd60e51b81526004016105fb906132b1565b6107318383836001600160a01b038316612a8d57612a8881612aea565b612ab0565b816001600160a01b0316836001600160a01b031614612ab057612ab08382612b02565b6001600160a01b038216612ac75761073181612b9f565b826001600160a01b0316826001600160a01b031614610731576107318282612be7565b60088054906000612afa836134ab565b919050555050565b60006001612b0f846120bd565b612b19919061342d565b600083815260076020526040902054909150808214612b6c576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60405162461bcd60e51b815260206004820152601c60248201527f5468697320746f6b656e2063616e6e6f74206265206275726e65642e0000000060448201526064016105fb565b6000612bf2836120bd565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008083601f840112612c3c578182fd5b50813567ffffffffffffffff811115612c53578182fd5b602083019150836020828501011115612c6b57600080fd5b9250929050565b600082601f830112612c82578081fd5b8135612c95612c90826133d9565b6133a8565b818152846020838601011115612ca9578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612cd4578081fd5b813561096981613532565b600060208284031215612cf0578081fd5b815161096981613532565b60008060408385031215612d0d578081fd5b8235612d1881613532565b91506020830135612d2881613532565b809150509250929050565b600080600060608486031215612d47578081fd5b8335612d5281613532565b92506020840135612d6281613532565b929592945050506040919091013590565b60008060008060808587031215612d88578081fd5b8435612d9381613532565b93506020850135612da381613532565b925060408501359150606085013567ffffffffffffffff811115612dc5578182fd5b612dd187828801612c72565b91505092959194509250565b60008060408385031215612def578182fd5b8235612dfa81613532565b91506020830135612d288161354a565b600080600060408486031215612e1e578283fd5b8335612e2981613532565b9250602084013567ffffffffffffffff811115612e44578283fd5b612e5086828701612c2b565b9497909650939450505050565b60008060408385031215612e6f578182fd5b8235612e7a81613532565b946020939093013593505050565b600060208284031215612e99578081fd5b81516109698161354a565b600060208284031215612eb5578081fd5b5051919050565b600060208284031215612ecd578081fd5b813561096981613558565b600060208284031215612ee9578081fd5b815161096981613558565b60008060408385031215612d0d578182fd5b600060208284031215612f17578081fd5b815167ffffffffffffffff811115612f2d578182fd5b8201601f81018413612f3d578182fd5b8051612f4b612c90826133d9565b818152856020838501011115612f5f578384fd5b612a39826020830160208601613444565b600060208284031215612f81578081fd5b5035919050565b600080600060608486031215612f9c578081fd5b833592506020840135612fae81613532565b9150604084013567ffffffffffffffff811115612fc9578182fd5b612fd586828701612c72565b9150509250925092565b600080600060408486031215612ff3578081fd5b83359250602084013567ffffffffffffffff811115612e44578182fd5b60008060408385031215613022578182fd5b50508035926020909101359150565b60008151808452613049816020860160208601613444565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff19606097881b811682526001600160e01b031996909616601482015293861b8516601885015291851b909316602c83015260408201929092529182015260800190565b600083516130bf818460208801613444565b8351908301906130d3818360208801613444565b01949350505050565b600083516130ee818460208801613444565b835190830190613102818360208801613444565b652f6d6574612f60d01b9101908152600601949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906124b490830184613031565b602081016001831061316357613163613506565b91905290565b602081016006831061316357613163613506565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6020815260006109696020830184613031565b6020808252600b908201526a3a37b5b2b72437b63232b960a91b604082015260600190565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601690820152751d1bdad95b905cdcda59db9b595b9d10dbdb9d1c9bdb60521b604082015260600190565b60208082526030908201527f546869732063616c6c206f6e6c7920776f726b73207768656e207472616e736660408201526f32b9399030b9329032b730b13632b21760811b606082015260800190565b60208082526036908201527f746f6b656e41737369676e6d656e74436f6e74726f6c206b65792072657175696040820152753932b2103337b9103a3434b990333ab731ba34b7b71760511b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff811182821017156133d1576133d161351c565b604052919050565b600067ffffffffffffffff8211156133f3576133f361351c565b50601f01601f191660200190565b60008219821115613414576134146134da565b500190565b600082613428576134286134f0565b500490565b60008282101561343f5761343f6134da565b500390565b60005b8381101561345f578181015183820152602001613447565b838111156113575750506000910152565b600181811c9082168061348457607f821691505b602082108114156134a557634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156134bf576134bf6134da565b5060010190565b6000826134d5576134d56134f0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461354757600080fd5b50565b801515811461354757600080fd5b6001600160e01b03198116811461354757600080fdfea26469706673582212204e8b63f6716a82b312264e20523b3f70eac98bd14e3023425ac2f26677c7192c64736f6c63430008040033

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

0000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c500000000000000000000000000000000000000000000000000000000000186a0

-----Decoded View---------------
Arg [0] : _bridgeDataAddress (address): 0x0884fc15E31B1B634732e140cb3F94b3cbFdD1c5
Arg [1] : _finalSupply (uint256): 100000

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c5
Arg [1] : 00000000000000000000000000000000000000000000000000000000000186a0


Deployed Bytecode Sourcemap

54757:12285:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43043:240;;;;;;:::i;:::-;;:::i;:::-;;;12597:14:1;;12590:22;12572:41;;12560:2;12545:18;43043:240:0;;;;;;;;31002:100;;;:::i;:::-;;;;;;;:::i;32465:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;11327:32:1;;;11309:51;;11297:2;11282:18;32465:221:0;11264:102:1;31999:400:0;;;;;;:::i;:::-;;:::i;:::-;;64322:597;;;;;;:::i;:::-;;:::i;61768:109::-;61858:11;61768:109;;;28996:25:1;;;28984:2;28969:18;61768:109:0;28951:76:1;33355:305:0;;;;;;:::i;:::-;;:::i;54863:29::-;;;;;-1:-1:-1;;;;;54863:29:0;;;61886:1299;;;;;;:::i;:::-;;:::i;58769:206::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;58531:192::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;33731:151::-;;;;;;:::i;:::-;;:::i;66558:193::-;;;;;;:::i;:::-;;:::i;57264:294::-;;;:::i;59303:119::-;;;;;;:::i;:::-;;:::i;43887:183::-;;;;;;:::i;:::-;;:::i;55042:54::-;;;;;;:::i;:::-;;;;;;;;;;;;;;56804:332;;;;;;:::i;:::-;;:::i;61191:348::-;;;;;;:::i;:::-;;:::i;58983:91::-;;;:::i;60793:390::-;;;;;;:::i;:::-;;:::i;63546:511::-;;;;;;:::i;:::-;;:::i;66054:308::-;;;;;;:::i;:::-;;:::i;58149:337::-;;;;;;:::i;:::-;;:::i;31171:104::-;;;:::i;32758:295::-;;;;;;:::i;:::-;;:::i;57705:436::-;;;;;;:::i;:::-;;:::i;33953:285::-;;;;;;:::i;:::-;;:::i;31346:360::-;;;;;;:::i;:::-;;:::i;66867:170::-;;;;;;:::i;:::-;;:::i;33124:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;33245:25:0;;;33221:4;33245:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;33124:164;43043:240;43148:4;-1:-1:-1;;;;;;43172:50:0;;-1:-1:-1;;;43172:50:0;;:103;;;43239:36;43263:11;43239:23;:36::i;:::-;43165:110;43043:240;-1:-1:-1;;43043:240:0:o;31002:100::-;31056:13;31089:5;31082:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31002:100;:::o;32465:221::-;32541:7;32569:16;32577:7;59545:11;-1:-1:-1;59534:22:0;59428:136;32569:16;32561:73;;;;-1:-1:-1;;;32561:73:0;;24321:2:1;32561:73:0;;;24303:21:1;24360:2;24340:18;;;24333:30;24399:34;24379:18;;;24372:62;-1:-1:-1;;;24450:18:1;;;24443:42;24502:19;;32561:73:0;;;;;;;;;-1:-1:-1;32654:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;32654:24:0;;32465:221::o;31999:400::-;32080:13;32096:16;32104:7;32096;:16::i;:::-;32080:32;;32137:5;-1:-1:-1;;;;;32131:11:0;:2;-1:-1:-1;;;;;32131:11:0;;;32123:57;;;;-1:-1:-1;;;32123:57:0;;26752:2:1;32123:57:0;;;26734:21:1;26791:2;26771:18;;;26764:30;26830:34;26810:18;;;26803:62;-1:-1:-1;;;26881:18:1;;;26874:31;26922:19;;32123:57:0;26724:223:1;32123:57:0;25165:10;-1:-1:-1;;;;;32201:21:0;;;;:72;;-1:-1:-1;32226:47:0;32253:5;25165:10;33124:164;:::i;32226:47::-;32193:164;;;;-1:-1:-1;;;32193:164:0;;21119:2:1;32193:164:0;;;21101:21:1;21158:2;21138:18;;;21131:30;21197:34;21177:18;;;21170:62;21268:26;21248:18;;;21241:54;21312:19;;32193:164:0;21091:246:1;32193:164:0;32370:21;32379:2;32383:7;32370:8;:21::i;:::-;31999:400;;;:::o;64322:597::-;56637:17;:15;:17::i;:::-;:25;;56658:4;56637:25;56629:86;;;;-1:-1:-1;;;56629:86:0;;;;;;;:::i;:::-;64470:20:::1;64493:17;64501:8;64493:7;:17::i;:::-;-1:-1:-1::0;;;;;64795:33:0;::::1;64660:12;64795:33:::0;;;:19:::1;:33;::::0;;;;;;;;64685:144;;64470:40;;-1:-1:-1;64660:12:0;;64685:144:::1;::::0;64710:4:::1;::::0;-1:-1:-1;;;64717:40:0;64759:10:::1;::::0;64470:40;;64785:8;;64685:144:::1;;:::i;:::-;;;;;;;;;;;;;64675:155;;;;;;64660:170;;64841:70;64865:12;64879:4;64885:8;64895:3;64900:10;64841:23;:70::i;:::-;56726:1;;64322:597:::0;;;:::o;33355:305::-;33516:41;25165:10;33549:7;33516:18;:41::i;:::-;33508:103;;;;-1:-1:-1;;;33508:103:0;;;;;;;:::i;:::-;33624:28;33634:4;33640:2;33644:7;33624:9;:28::i;61886:1299::-;61997:7;62037:27;62057:6;62037:19;:27::i;:::-;62027:6;:37;;:87;;;;-1:-1:-1;62078:10:0;;:36;;-1:-1:-1;;;62078:36:0;;-1:-1:-1;;;;;62078:10:0;;;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;62068:46:0;:6;-1:-1:-1;;;;;62068:46:0;;62027:87;62023:1096;;;62500:17;62510:6;62500:9;:17::i;:::-;62491:6;:26;62483:82;;;;-1:-1:-1;;;62483:82:0;;;;;;;:::i;:::-;62580:17;62600:27;62620:6;62600:19;:27::i;:::-;62580:47;;62642:15;62676:367;35770:4;35794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;35794:16:0;62698:271;;62771:6;62758:9;:19;62754:162;;62887:5;;62754:162;62938:11;;;;:::i;:::-;;;;62698:271;62987:9;;;;:::i;:::-;;;;63030:11;63020:7;:21;62676:367;;;63100:7;-1:-1:-1;63093:14:0;;-1:-1:-1;63093:14:0;62023:1096;63136:41;63162:6;63170;63136:25;:41::i;:::-;63129:48;61886:1299;-1:-1:-1;;;61886:1299:0:o;58769:206::-;58846:7;58874:17;58882:8;59545:11;-1:-1:-1;59534:22:0;59428:136;58874:17;58866:54;;;;-1:-1:-1;;;58866:54:0;;28340:2:1;58866:54:0;;;28322:21:1;28379:2;28359:18;;;28352:30;-1:-1:-1;;;28398:18:1;;;28391:54;28462:18;;58866:54:0;28312:174:1;58866:54:0;58946:10;58957:8;58946:20;;;;;-1:-1:-1;;;58946:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;58938:29;;;;;;-1:-1:-1;;;58938:29:0;;;;;;;;58531:192;58606:9;58636:17;58644:8;59545:11;-1:-1:-1;59534:22:0;59428:136;58636:17;58628:54;;;;-1:-1:-1;;;58628:54:0;;28340:2:1;58628:54:0;;;28322:21:1;28379:2;28359:18;;;28352:30;-1:-1:-1;;;28398:18:1;;;28391:54;28462:18;;58628:54:0;28312:174:1;58628:54:0;-1:-1:-1;58700:15:0;;58531:192;-1:-1:-1;58531:192:0:o;33731:151::-;33835:39;33852:4;33858:2;33862:7;33835:39;;;;;;;;;;;;:16;:39::i;66558:193::-;56450:10;;:47;;-1:-1:-1;;;56450:47:0;;-1:-1:-1;;;;;56450:10:0;;;;:21;;:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56436:61:0;:10;-1:-1:-1;;;;;56436:61:0;;56428:128;;;;-1:-1:-1;;;56428:128:0;;;;;;;:::i;:::-;66704:38:::1;::::0;-1:-1:-1;;;66704:38:0;;66736:4:::1;66704:38;::::0;::::1;11309:51:1::0;-1:-1:-1;;;;;66676:22:0;::::1;::::0;::::1;::::0;66699:3;;66676:22;;66704:23:::1;::::0;11282:18:1;;66704:38:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66676:67;::::0;-1:-1:-1;;;;;;66676:67:0::1;::::0;;;;;;-1:-1:-1;;;;;12345:32:1;;;66676:67:0::1;::::0;::::1;12327:51:1::0;12394:18;;;12387:34;12300:18;;66676:67:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;57264:294::-:0;57322:4;57344:28;57375:10;;;;;;;;;-1:-1:-1;;;;;57375:10:0;-1:-1:-1;;;;;57375:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57344:64;-1:-1:-1;57482:25:0;;;:67;;;57534:15;57511:20;:38;57482:67;57474:76;;;57264:294;:::o;59303:119::-;59368:4;59397:17;59405:8;59545:11;-1:-1:-1;59534:22:0;59428:136;43887:183;43962:7;61858:11;43990:5;:21;43982:57;;;;-1:-1:-1;;;43982:57:0;;24734:2:1;43982:57:0;;;24716:21:1;24773:2;24753:18;;;24746:30;24812:25;24792:18;;;24785:53;24855:18;;43982:57:0;24706:173:1;43982:57:0;-1:-1:-1;44057:5:0;43887:183::o;56804:332::-;56263:10;;:38;;-1:-1:-1;;;56263:38:0;;23979:2:1;56263:38:0;;;23961:21:1;24018:2;23998:18;;;23991:30;-1:-1:-1;;;24037:18:1;;;24030:43;-1:-1:-1;;;;;56263:10:0;;;;:21;;24090:18:1;;56263:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56249:52:0;:10;-1:-1:-1;;;;;56249:52:0;;56241:110;;;;-1:-1:-1;;;56241:110:0;;20291:2:1;56241:110:0;;;20273:21:1;20330:2;20310:18;;;20303:30;20369:34;20349:18;;;20342:62;-1:-1:-1;;;20420:18:1;;;20413:43;20473:19;;56241:110:0;20263:235:1;56241:110:0;-1:-1:-1;;;;;56916:39:0;::::1;56908:103;;;::::0;-1:-1:-1;;;56908:103:0;;14930:2:1;56908:103:0::1;::::0;::::1;14912:21:1::0;14969:2;14949:18;;;14942:30;15008:34;14988:18;;;14981:62;-1:-1:-1;;;15059:18:1;;;15052:49;15118:19;;56908:103:0::1;14902:241:1::0;56908:103:0::1;57053:10;::::0;57027:63:::1;::::0;-1:-1:-1;;;;;57027:63:0;;::::1;::::0;57053:10:::1;::::0;57027:63:::1;::::0;57053:10:::1;::::0;57027:63:::1;57101:10;:27:::0;;-1:-1:-1;;;;;;57101:27:0::1;-1:-1:-1::0;;;;;57101:27:0;;;::::1;::::0;;;::::1;::::0;;56804:332::o;61191:348::-;61286:7;61315:17;61323:8;59545:11;-1:-1:-1;59534:22:0;59428:136;61315:17;:49;;;;-1:-1:-1;35770:4:0;35794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;35794:16:0;:30;61315:49;61311:180;;;61443:10;;:36;;-1:-1:-1;;;61443:36:0;;-1:-1:-1;;;;;61443:10:0;;;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;61311:180::-;61508:23;61522:8;61508:13;:23::i;58983:91::-;59023:13;59056:10;:8;:10::i;:::-;59049:17;;58983:91;:::o;60793:390::-;60927:10;;:36;;-1:-1:-1;;;60927:36:0;;60888:7;;-1:-1:-1;;;;;60927:10:0;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60917:46:0;:6;-1:-1:-1;;;;;60917:46:0;;60913:222;;;61100:23;61116:6;61100:15;:23::i;:::-;43790:12;;61064:33;;:11;:33;:::i;:::-;:59;;;;:::i;60913:222::-;61152:23;61168:6;61152:15;:23::i;63546:511::-;56637:17;:15;:17::i;:::-;:25;;56658:4;56637:25;56629:86;;;;-1:-1:-1;;;56629:86:0;;;;;;;:::i;:::-;63682:20:::1;63705:17;63713:8;63705:7;:17::i;:::-;-1:-1:-1::0;;;;;63933:33:0;::::1;63817:12;63933:33:::0;;;:19:::1;:33;::::0;;;;;;;;63842:125;;63682:40;;-1:-1:-1;63817:12:0;;63842:125:::1;::::0;63867:4:::1;::::0;-1:-1:-1;;;63874:28:0;63682:40;;63918:3;;63923:8;;63842:125:::1;;:::i;66054:308::-:0;56450:10;;:47;;-1:-1:-1;;;56450:47:0;;-1:-1:-1;;;;;56450:10:0;;;;:21;;:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56436:61:0;:10;-1:-1:-1;;;;;56436:61:0;;56428:128;;;;-1:-1:-1;;;56428:128:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66209:38:0;::::1;66201:81;;;::::0;-1:-1:-1;;;66201:81:0;;28693:2:1;66201:81:0::1;::::0;::::1;28675:21:1::0;28732:2;28712:18;;;28705:30;28771:32;28751:18;;;28744:60;28821:18;;66201:81:0::1;28665:180:1::0;66201:81:0::1;66293:61;::::0;-1:-1:-1;;;66293:61:0;;-1:-1:-1;;;;;66293:54:0;::::1;::::0;::::1;::::0;:61:::1;::::0;66348:5;;;;66293:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66054:308:::0;;;:::o;58149:337::-;56017:10;;:38;;-1:-1:-1;;;56017:38:0;;17666:2:1;56017:38:0;;;17648:21:1;17705:2;17685:18;;;17678:30;-1:-1:-1;;;17724:18:1;;;17717:43;-1:-1:-1;;;;;56017:10:0;;;;:21;;17777:18:1;;56017:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56003:52:0;:10;-1:-1:-1;;;;;56003:52:0;;:105;;;-1:-1:-1;56073:10:0;;:35;;-1:-1:-1;;;56073:35:0;;27572:2:1;56073:35:0;;;27554:21:1;27611:2;27591:18;;;27584:30;-1:-1:-1;;;27630:18:1;;;27623:40;-1:-1:-1;;;;;56073:10:0;;;;:21;;27680:18:1;;56073:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56059:49:0;:10;-1:-1:-1;;;;;56059:49:0;;56003:105;55995:178;;;;-1:-1:-1;;;55995:178:0;;27911:2:1;55995:178:0;;;27893:21:1;27950:2;27930:18;;;27923:30;27989:34;27969:18;;;27962:62;28060:30;28040:18;;;28033:58;28108:19;;55995:178:0;27883:250:1;55995:178:0;58325:10:::1;::::0;:36:::1;::::0;-1:-1:-1;;;58325:36:0;;-1:-1:-1;;;;;58325:10:0;;::::1;::::0;:21:::1;::::0;:36:::1;::::0;::::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58304:57:0::1;:17;58312:8;58304:7;:17::i;:::-;-1:-1:-1::0;;;;;58304:57:0::1;;58296:129;;;::::0;-1:-1:-1;;;58296:129:0;;15350:2:1;58296:129:0::1;::::0;::::1;15332:21:1::0;15389:2;15369:18;;;15362:30;15428:34;15408:18;;;15401:62;15499:29;15479:18;;;15472:57;15546:19;;58296:129:0::1;15322:249:1::0;58296:129:0::1;58465:9;;58475:1;58465:12;;;;;-1:-1:-1::0;;;58465:12:0::1;;;;;;;;;::::0;;;::::1;;;;::::0;-1:-1:-1;58436:10:0::1;58447:8:::0;58436:20:::1;::::0;::::1;;;-1:-1:-1::0;;;58436:20:0::1;;;;;;;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;58149:337:::0;;;:::o;31171:104::-;31227:13;31260:7;31253:14;;;;;:::i;32758:295::-;-1:-1:-1;;;;;32861:24:0;;25165:10;32861:24;;32853:62;;;;-1:-1:-1;;;32853:62:0;;18770:2:1;32853:62:0;;;18752:21:1;18809:2;18789:18;;;18782:30;18848:27;18828:18;;;18821:55;18893:18;;32853:62:0;18742:175:1;32853:62:0;25165:10;32928:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;32928:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;32928:53:0;;;;;;;;;;32997:48;;12572:41:1;;;32928:42:0;;25165:10;32997:48;;12545:18:1;32997:48:0;;;;;;;32758:295;;:::o;57705:436::-;55827:10;;:38;;-1:-1:-1;;;55827:38:0;;17666:2:1;55827:38:0;;;17648:21:1;17705:2;17685:18;;;17678:30;-1:-1:-1;;;17724:18:1;;;17717:43;-1:-1:-1;;;;;55827:10:0;;;;:21;;17777:18:1;;55827:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;55813:52:0;:10;-1:-1:-1;;;;;55813:52:0;;55805:110;;;;-1:-1:-1;;;55805:110:0;;20705:2:1;55805:110:0;;;20687:21:1;20744:2;20724:18;;;20717:30;20783:34;20763:18;;;20756:62;-1:-1:-1;;;20834:18:1;;;20827:43;20887:19;;55805:110:0;20677:235:1;55805:110:0;57839:10:::1;::::0;:36:::1;::::0;-1:-1:-1;;;57839:36:0;;57817:19:::1;::::0;-1:-1:-1;;;;;57839:10:0::1;::::0;:21:::1;::::0;:36:::1;::::0;::::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57817:58:::0;-1:-1:-1;57886:13:0::1;57902:17;57913:6:::0;57902:8;:17:::1;:::i;:::-;57886:33;;57946:11;57938:5;:19;57930:82;;;::::0;-1:-1:-1;;;57930:82:0;;21955:2:1;57930:82:0::1;::::0;::::1;21937:21:1::0;21994:2;21974:18;;;21967:30;22033:34;22013:18;;;22006:62;-1:-1:-1;;;22084:18:1;;;22077:48;22142:19;;57930:82:0::1;21927:240:1::0;57930:82:0::1;58040:8:::0;58023:111:::1;58054:5;58050:1;:9;58023:111;;;58086:36;::::0;58120:1;;-1:-1:-1;;;;;58086:36:0;::::1;::::0;58103:1:::1;::::0;58086:36:::1;::::0;58103:1;;58086:36:::1;58061:3:::0;::::1;::::0;::::1;:::i;:::-;;;;58023:111;;33953:285:::0;34085:41;25165:10;34118:7;34085:18;:41::i;:::-;34077:103;;;;-1:-1:-1;;;34077:103:0;;;;;;;:::i;:::-;34191:39;34205:4;34211:2;34215:7;34224:5;34191:13;:39::i;31346:360::-;31419:13;31453:16;31461:7;59545:11;-1:-1:-1;59534:22:0;59428:136;31453:16;31445:76;;;;-1:-1:-1;;;31445:76:0;;25496:2:1;31445:76:0;;;25478:21:1;25535:2;25515:18;;;25508:30;25574:34;25554:18;;;25547:62;-1:-1:-1;;;25625:18:1;;;25618:45;25680:19;;31445:76:0;25468:237:1;31445:76:0;31534:21;31558:10;:8;:10::i;:::-;31534:34;;31610:1;31592:7;31586:21;:25;:112;;;;;;;;;;;;;;;;;31651:7;31660:18;:7;:16;:18::i;:::-;31634:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;31579:119;31346:360;-1:-1:-1;;;31346:360:0:o;66867:170::-;56450:10;;:47;;-1:-1:-1;;;56450:47:0;;-1:-1:-1;;;;;56450:10:0;;;;:21;;:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56436:61:0;:10;-1:-1:-1;;;;;56436:61:0;;56428:128;;;;-1:-1:-1;;;56428:128:0;;;;;;;:::i;:::-;66989:40:::1;::::0;-1:-1:-1;;;66989:40:0;;-1:-1:-1;;;;;12050:32:1;;;66989:40:0::1;::::0;::::1;12032:51:1::0;67024:4:0::1;12099:18:1::0;;;12092:50;66989:29:0;::::1;::::0;::::1;::::0;12005:18:1;;66989:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;66867:170:::0;;:::o;30070:292::-;30172:4;-1:-1:-1;;;;;;30196:40:0;;-1:-1:-1;;;30196:40:0;;:105;;-1:-1:-1;;;;;;;30253:48:0;;-1:-1:-1;;;30253:48:0;30196:105;:158;;;-1:-1:-1;;;;;;;;;;28340:40:0;;;30318:36;28231:157;39640:167;39715:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;39715:29:0;-1:-1:-1;;;;;39715:29:0;;;;;;;;:24;;39769:16;39715:24;39769:7;:16::i;:::-;-1:-1:-1;;;;;39760:39:0;;;;;;;;;;;39640:167;;:::o;64995:706::-;65152:12;65167:35;65196:5;7841:58;;11020:66:1;7841:58:0;;;11008:79:1;11103:12;;;11096:28;;;7708:7:0;;11140:12:1;;7841:58:0;;;;;;;;;;;;7831:69;;;;;;7824:76;;7639:269;;;;65167:35;65152:50;;65213:14;65230:31;65244:4;65250:10;65230:13;:31::i;:::-;65213:48;;65290:13;-1:-1:-1;;;;;65280:23:0;:6;-1:-1:-1;;;;;65280:23:0;;65272:98;;;;-1:-1:-1;;;65272:98:0;;22784:2:1;65272:98:0;;;22766:21:1;22823:2;22803:18;;;22796:30;22862:34;22842:18;;;22835:62;22933:32;22913:18;;;22906:60;22983:19;;65272:98:0;22756:252:1;65272:98:0;-1:-1:-1;;;;;65496:92:0;;;65553:34;;;;:19;:34;;;;;;;;;;65496:92;;65511:10;12327:51:1;;12394:18;;;12387:34;65543:8:0;;65496:92;;;;;;12300:18:1;65496:92:0;;;;;;;-1:-1:-1;;;;;65599:34:0;;;;;;:19;:34;;;;;:36;;;;;;:::i;:::-;;;;;;65646:47;65660:13;65675:3;65680:8;65646:47;;;;;;;;;;;;:13;:47::i;:::-;64995:706;;;;;;;:::o;35999:351::-;36092:4;36117:16;36125:7;59545:11;-1:-1:-1;59534:22:0;59428:136;36117:16;36109:73;;;;-1:-1:-1;;;36109:73:0;;19878:2:1;36109:73:0;;;19860:21:1;19917:2;19897:18;;;19890:30;19956:34;19936:18;;;19929:62;-1:-1:-1;;;20007:18:1;;;20000:42;20059:19;;36109:73:0;19850:234:1;36109:73:0;36193:13;36209:16;36217:7;36209;:16::i;:::-;36193:32;;36255:5;-1:-1:-1;;;;;36244:16:0;:7;-1:-1:-1;;;;;36244:16:0;;:51;;;;36288:7;-1:-1:-1;;;;;36264:31:0;:20;36276:7;36264:11;:20::i;:::-;-1:-1:-1;;;;;36264:31:0;;36244:51;:97;;;-1:-1:-1;;;;;;33245:25:0;;;33221:4;33245:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;36299:42;36236:106;35999:351;-1:-1:-1;;;;35999:351:0:o;60040:745::-;35770:4;35794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;35794:16:0;:30;;;60148:77;;-1:-1:-1;60189:10:0;;:36;;-1:-1:-1;;;60189:36:0;;-1:-1:-1;;;;;60189:10:0;;;;:21;;:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60180:45:0;:5;-1:-1:-1;;;;;60180:45:0;;60148:77;:121;;;;;60229:40;60248:10;60260:8;60229:18;:40::i;:::-;60144:634;;;60342:30;60359:1;60363:8;60342;:30::i;:::-;60617:20;60623:3;60628:8;60617:5;:20::i;:::-;60678:8;60673:3;-1:-1:-1;;;;;60657:30:0;60666:5;-1:-1:-1;;;;;60657:30:0;;;;;;;;;;;31999:400;;;:::o;60144:634::-;60729:37;60745:5;60752:3;60757:8;60729:15;:37::i;30426:208::-;30498:7;-1:-1:-1;;;;;30526:19:0;;30518:74;;;;-1:-1:-1;;;30518:74:0;;21544:2:1;30518:74:0;;;21526:21:1;21583:2;21563:18;;;21556:30;21622:34;21602:18;;;21595:62;-1:-1:-1;;;21673:18:1;;;21666:40;21723:19;;30518:74:0;21516:232:1;30518:74:0;-1:-1:-1;;;;;;30610:16:0;;;;;:9;:16;;;;;;;30426:208::o;43367:259::-;43464:7;43500:26;43520:5;43500:19;:26::i;:::-;43492:5;:34;43484:90;;;;-1:-1:-1;;;43484:90:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;43592:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;43367:259::o;30696:239::-;30768:7;30804:16;;;:7;:16;;;;;;-1:-1:-1;;;;;30804:16:0;30839:19;30831:73;;;;-1:-1:-1;;;30831:73:0;;22374:2:1;30831:73:0;;;22356:21:1;22413:2;22393:18;;;22386:30;22452:34;22432:18;;;22425:62;-1:-1:-1;;;22503:18:1;;;22496:39;22552:19;;30831:73:0;22346:231:1;59080:164:0;59189:10;;:25;;;-1:-1:-1;;;59189:25:0;;;;59132:13;;-1:-1:-1;;;;;59189:10:0;;:23;;:25;;;;;:10;;:25;;;;;;;:10;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59189:25:0;;;;;;;;;;;;:::i;:::-;59216:8;:6;:8::i;:::-;59172:63;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59158:78;;59080:164;:::o;35120:272::-;35234:28;35244:4;35250:2;35254:7;35234:9;:28::i;:::-;35281:48;35304:4;35310:2;35314:7;35323:5;35281:22;:48::i;:::-;35273:111;;;;-1:-1:-1;;;35273:111:0;;;;;;;:::i;25709:723::-;25765:13;25986:10;25982:53;;-1:-1:-1;;26013:10:0;;;;;;;;;;;;-1:-1:-1;;;26013:10:0;;;;;25709:723::o;25982:53::-;26060:5;26045:12;26101:78;26108:9;;26101:78;;26134:8;;;;:::i;:::-;;-1:-1:-1;26157:10:0;;-1:-1:-1;26165:2:0;26157:10;;:::i;:::-;;;26101:78;;;26189:19;26221:6;26211:17;;;;;;-1:-1:-1;;;26211:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26211:17:0;;26189:39;;26239:154;26246:10;;26239:154;;26273:11;26283:1;26273:11;;:::i;:::-;;-1:-1:-1;26342:10:0;26350:2;26342:5;:10;:::i;:::-;26329:24;;:2;:24;:::i;:::-;26316:39;;26299:6;26306;26299:14;;;;;;-1:-1:-1;;;26299:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;26299:56:0;;;;;;;;-1:-1:-1;26370:11:0;26379:2;26370:11;;:::i;:::-;;;26239:154;;4276:1492;4354:7;4431:9;4451;4471:7;4691:9;:16;4711:2;4691:22;4687:1032;;;-1:-1:-1;;;4978:4:0;4963:20;;4957:27;5028:4;5013:20;;5007:27;5086:4;5071:20;;5065:27;5062:1;5057:36;4933:175;;;5129:9;:16;5149:2;5129:22;5125:594;;;-1:-1:-1;;;5421:4:0;5406:20;;5400:27;5471:4;5456:20;;5450:27;;-1:-1:-1;;;;;5500:75:0;;;5606:3;5602:12;5616:2;5598:21;5371:263;;;5666:41;;-1:-1:-1;;;5666:41:0;;16475:2:1;5666:41:0;;;16457:21:1;16514:2;16494:18;;;16487:30;16553:33;16533:18;;;16526:61;16604:18;;5666:41:0;16447:181:1;5125:594:0;5738:22;5746:4;5752:1;5755;5758;5738:7;:22::i;:::-;5731:29;4276:1492;-1:-1:-1;;;;;;4276:1492:0:o;37615:431::-;-1:-1:-1;;;;;37695:16:0;;37687:61;;;;-1:-1:-1;;;37687:61:0;;23618:2:1;37687:61:0;;;23600:21:1;;;23637:18;;;23630:30;23696:34;23676:18;;;23669:62;23748:18;;37687:61:0;23590:182:1;37687:61:0;35770:4;35794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;35794:16:0;:30;37759:68;;;;-1:-1:-1;;;37759:68:0;;18008:2:1;37759:68:0;;;17990:21:1;18047:2;18027:18;;;18020:30;18086;18066:18;;;18059:58;18134:18;;37759:68:0;17980:178:1;37759:68:0;37840:45;37869:1;37873:2;37877:7;37840:20;:45::i;:::-;-1:-1:-1;;;;;37898:13:0;;;;;;:9;:13;;;;;:18;;37915:1;;37898:13;:18;;37915:1;;37898:18;:::i;:::-;;;;-1:-1:-1;;37927:16:0;;;;:7;:16;;;;;:21;;-1:-1:-1;;;;;;37927:21:0;-1:-1:-1;;;;;37927:21:0;;;;;;;;;;37615:431::o;38975:547::-;39103:4;-1:-1:-1;;;;;39073:34:0;:26;39091:7;39073:17;:26::i;:::-;-1:-1:-1;;;;;39073:34:0;;39065:88;;;;-1:-1:-1;;;39065:88:0;;25086:2:1;39065:88:0;;;25068:21:1;25125:2;25105:18;;;25098:30;25164:34;25144:18;;;25137:62;-1:-1:-1;;;25215:18:1;;;25208:39;25264:19;;39065:88:0;25058:231:1;39065:88:0;-1:-1:-1;;;;;39172:16:0;;39164:65;;;;-1:-1:-1;;;39164:65:0;;18365:2:1;39164:65:0;;;18347:21:1;18404:2;18384:18;;;18377:30;18443:34;18423:18;;;18416:62;-1:-1:-1;;;18494:18:1;;;18487:34;18538:19;;39164:65:0;18337:226:1;39164:65:0;39242:39;39263:4;39269:2;39273:7;39242:20;:39::i;:::-;39346:29;39363:1;39367:7;39346:8;:29::i;:::-;-1:-1:-1;;;;;39388:15:0;;;;;;:9;:15;;;;;:20;;39407:1;;39388:15;:20;;39407:1;;39388:20;:::i;:::-;;;;-1:-1:-1;;;;;;;39419:13:0;;;;;;:9;:13;;;;;:18;;39436:1;;39419:13;:18;;39436:1;;39419:18;:::i;:::-;;;;-1:-1:-1;;39448:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;39448:21:0;-1:-1:-1;;;;;39448:21:0;;;;;;;;;39487:27;;39448:16;;39487:27;;;;;;;38975:547;;;:::o;40372:843::-;40493:4;-1:-1:-1;;;;;40519:13:0;;17600:20;17639:8;40515:693;;40555:72;;-1:-1:-1;;;40555:72:0;;-1:-1:-1;;;;;40555:36:0;;;;;:72;;25165:10;;40606:4;;40612:7;;40621:5;;40555:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40555:72:0;;;;;;;;-1:-1:-1;;40555:72:0;;;;;;;;;;;;:::i;:::-;;;40551:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40801:13:0;;40797:341;;40844:60;;-1:-1:-1;;;40844:60:0;;;;;;;:::i;40797:341::-;41088:6;41082:13;41073:6;41069:2;41065:15;41058:38;40551:602;-1:-1:-1;;;;;;40678:55:0;-1:-1:-1;;;40678:55:0;;-1:-1:-1;40671:62:0;;40515:693;-1:-1:-1;41192:4:0;40372:843;;;;;;:::o;5907:1432::-;5992:7;6917:66;6903:80;;;6895:127;;;;-1:-1:-1;;;6895:127:0;;19124:2:1;6895:127:0;;;19106:21:1;19163:2;19143:18;;;19136:30;19202:34;19182:18;;;19175:62;-1:-1:-1;;;19253:18:1;;;19246:32;19295:19;;6895:127:0;19096:224:1;6895:127:0;7041:1;:7;;7046:2;7041:7;:18;;;;7052:1;:7;;7057:2;7052:7;7041:18;7033:65;;;;-1:-1:-1;;;7033:65:0;;23215:2:1;7033:65:0;;;23197:21:1;23254:2;23234:18;;;23227:30;23293:34;23273:18;;;23266:62;-1:-1:-1;;;23344:18:1;;;23337:32;23386:19;;7033:65:0;23187:224:1;7033:65:0;7213:24;;;7196:14;7213:24;;;;;;;;;12851:25:1;;;12924:4;12912:17;;12892:18;;;12885:45;;;;12946:18;;;12939:34;;;12989:18;;;12982:34;;;7213:24:0;;12823:19:1;;7213:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7213:24:0;;-1:-1:-1;;7213:24:0;;;-1:-1:-1;;;;;;;7256:20:0;;7248:57;;;;-1:-1:-1;;;7248:57:0;;14577:2:1;7248:57:0;;;14559:21:1;14616:2;14596:18;;;14589:30;14655:26;14635:18;;;14628:54;14699:18;;7248:57:0;14549:174:1;7248:57:0;7325:6;5907:1432;-1:-1:-1;;;;;5907:1432:0:o;59736:199::-;56637:17;:15;:17::i;:::-;:25;;56658:4;56637:25;56629:86;;;;-1:-1:-1;;;56629:86:0;;;;;;;:::i;:::-;59879:48:::1;59906:5;59913:3;59918:8;-1:-1:-1::0;;;;;44855:18:0;;44851:187;;44890:40;44922:7;44890:31;:40::i;:::-;44851:187;;;44960:2;-1:-1:-1;;;;;44952:10:0;:4;-1:-1:-1;;;;;44952:10:0;;44948:90;;44979:47;45012:4;45018:7;44979:32;:47::i;:::-;-1:-1:-1;;;;;45052:16:0;;45048:183;;45085:45;45122:7;45085:36;:45::i;45048:183::-;45158:4;-1:-1:-1;;;;;45152:10:0;:2;-1:-1:-1;;;;;45152:10:0;;45148:83;;45179:40;45207:2;45211:7;45179:27;:40::i;45963:103::-;46044:12;:14;;;:12;:14;;;:::i;:::-;;;;;;45963:103;:::o;46693:991::-;46959:22;47012:1;46984:25;47004:4;46984:19;:25::i;:::-;:29;;;;:::i;:::-;47024:18;47045:26;;;:17;:26;;;;;;46959:54;;-1:-1:-1;47178:28:0;;;47174:328;;-1:-1:-1;;;;;47245:18:0;;47223:19;47245:18;;;:12;:18;;;;;;;;:34;;;;;;;;;47296:30;;;;;;:44;;;47413:30;;:17;:30;;;;;:43;;;47174:328;-1:-1:-1;47598:26:0;;;;:17;:26;;;;;;;;47591:33;;;-1:-1:-1;;;;;47642:18:0;;;;;:12;:18;;;;;:34;;;;;;;47635:41;46693:991::o;47941:137::-;48032:38;;-1:-1:-1;;;48032:38:0;;15778:2:1;48032:38:0;;;15760:21:1;15817:2;15797:18;;;15790:30;15856;15836:18;;;15829:58;15904:18;;48032:38:0;15750:178:1;45539:224:0;45624:14;45641:23;45661:2;45641:19;:23::i;:::-;-1:-1:-1;;;;;45675:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;45720:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;45539:224:0:o;14:375:1:-;65:8;75:6;129:3;122:4;114:6;110:17;106:27;96:2;;154:8;144;137:26;96:2;-1:-1:-1;184:20:1;;227:18;216:30;;213:2;;;266:8;256;249:26;213:2;310:4;302:6;298:17;286:29;;362:3;355:4;346:6;338;334:19;330:30;327:39;324:2;;;379:1;376;369:12;324:2;86:303;;;;;:::o;394:482::-;436:5;489:3;482:4;474:6;470:17;466:27;456:2;;511:5;504;497:20;456:2;551:6;538:20;582:48;598:31;626:2;598:31;:::i;:::-;582:48;:::i;:::-;655:2;646:7;639:19;701:3;694:4;689:2;681:6;677:15;673:26;670:35;667:2;;;722:5;715;708:20;667:2;791;784:4;776:6;772:17;765:4;756:7;752:18;739:55;814:16;;;832:4;810:27;803:42;;;;818:7;446:430;-1:-1:-1;;446:430:1:o;881:257::-;940:6;993:2;981:9;972:7;968:23;964:32;961:2;;;1014:6;1006;999:22;961:2;1058:9;1045:23;1077:31;1102:5;1077:31;:::i;1143:261::-;1213:6;1266:2;1254:9;1245:7;1241:23;1237:32;1234:2;;;1287:6;1279;1272:22;1234:2;1324:9;1318:16;1343:31;1368:5;1343:31;:::i;1409:398::-;1477:6;1485;1538:2;1526:9;1517:7;1513:23;1509:32;1506:2;;;1559:6;1551;1544:22;1506:2;1603:9;1590:23;1622:31;1647:5;1622:31;:::i;:::-;1672:5;-1:-1:-1;1729:2:1;1714:18;;1701:32;1742:33;1701:32;1742:33;:::i;:::-;1794:7;1784:17;;;1496:311;;;;;:::o;1812:466::-;1889:6;1897;1905;1958:2;1946:9;1937:7;1933:23;1929:32;1926:2;;;1979:6;1971;1964:22;1926:2;2023:9;2010:23;2042:31;2067:5;2042:31;:::i;:::-;2092:5;-1:-1:-1;2149:2:1;2134:18;;2121:32;2162:33;2121:32;2162:33;:::i;:::-;1916:362;;2214:7;;-1:-1:-1;;;2268:2:1;2253:18;;;;2240:32;;1916:362::o;2283:685::-;2378:6;2386;2394;2402;2455:3;2443:9;2434:7;2430:23;2426:33;2423:2;;;2477:6;2469;2462:22;2423:2;2521:9;2508:23;2540:31;2565:5;2540:31;:::i;:::-;2590:5;-1:-1:-1;2647:2:1;2632:18;;2619:32;2660:33;2619:32;2660:33;:::i;:::-;2712:7;-1:-1:-1;2766:2:1;2751:18;;2738:32;;-1:-1:-1;2821:2:1;2806:18;;2793:32;2848:18;2837:30;;2834:2;;;2885:6;2877;2870:22;2834:2;2913:49;2954:7;2945:6;2934:9;2930:22;2913:49;:::i;:::-;2903:59;;;2413:555;;;;;;;:::o;2973:392::-;3038:6;3046;3099:2;3087:9;3078:7;3074:23;3070:32;3067:2;;;3120:6;3112;3105:22;3067:2;3164:9;3151:23;3183:31;3208:5;3183:31;:::i;:::-;3233:5;-1:-1:-1;3290:2:1;3275:18;;3262:32;3303:30;3262:32;3303:30;:::i;3370:565::-;3450:6;3458;3466;3519:2;3507:9;3498:7;3494:23;3490:32;3487:2;;;3540:6;3532;3525:22;3487:2;3584:9;3571:23;3603:31;3628:5;3603:31;:::i;:::-;3653:5;-1:-1:-1;3709:2:1;3694:18;;3681:32;3736:18;3725:30;;3722:2;;;3773:6;3765;3758:22;3722:2;3817:58;3867:7;3858:6;3847:9;3843:22;3817:58;:::i;:::-;3477:458;;3894:8;;-1:-1:-1;3791:84:1;;-1:-1:-1;;;;3477:458:1:o;3940:325::-;4008:6;4016;4069:2;4057:9;4048:7;4044:23;4040:32;4037:2;;;4090:6;4082;4075:22;4037:2;4134:9;4121:23;4153:31;4178:5;4153:31;:::i;:::-;4203:5;4255:2;4240:18;;;;4227:32;;-1:-1:-1;;;4027:238:1:o;4270:255::-;4337:6;4390:2;4378:9;4369:7;4365:23;4361:32;4358:2;;;4411:6;4403;4396:22;4358:2;4448:9;4442:16;4467:28;4489:5;4467:28;:::i;4530:194::-;4600:6;4653:2;4641:9;4632:7;4628:23;4624:32;4621:2;;;4674:6;4666;4659:22;4621:2;-1:-1:-1;4702:16:1;;4611:113;-1:-1:-1;4611:113:1:o;4729:255::-;4787:6;4840:2;4828:9;4819:7;4815:23;4811:32;4808:2;;;4861:6;4853;4846:22;4808:2;4905:9;4892:23;4924:30;4948:5;4924:30;:::i;4989:259::-;5058:6;5111:2;5099:9;5090:7;5086:23;5082:32;5079:2;;;5132:6;5124;5117:22;5079:2;5169:9;5163:16;5188:30;5212:5;5188:30;:::i;5535:411::-;5616:6;5624;5677:2;5665:9;5656:7;5652:23;5648:32;5645:2;;;5698:6;5690;5683:22;6369:675;6449:6;6502:2;6490:9;6481:7;6477:23;6473:32;6470:2;;;6523:6;6515;6508:22;6470:2;6561:9;6555:16;6594:18;6586:6;6583:30;6580:2;;;6631:6;6623;6616:22;6580:2;6659:22;;6712:4;6704:13;;6700:27;-1:-1:-1;6690:2:1;;6746:6;6738;6731:22;6690:2;6780;6774:9;6805:48;6821:31;6849:2;6821:31;:::i;6805:48::-;6876:2;6869:5;6862:17;6916:7;6911:2;6906;6902;6898:11;6894:20;6891:33;6888:2;;;6942:6;6934;6927:22;6888:2;6960:54;7011:2;7006;6999:5;6995:14;6990:2;6986;6982:11;6960:54;:::i;7049:190::-;7108:6;7161:2;7149:9;7140:7;7136:23;7132:32;7129:2;;;7182:6;7174;7167:22;7129:2;-1:-1:-1;7210:23:1;;7119:120;-1:-1:-1;7119:120:1:o;7443:543::-;7529:6;7537;7545;7598:2;7586:9;7577:7;7573:23;7569:32;7566:2;;;7619:6;7611;7604:22;7566:2;7660:9;7647:23;7637:33;;7720:2;7709:9;7705:18;7692:32;7733:31;7758:5;7733:31;:::i;:::-;7783:5;-1:-1:-1;7839:2:1;7824:18;;7811:32;7866:18;7855:30;;7852:2;;;7903:6;7895;7888:22;7852:2;7931:49;7972:7;7963:6;7952:9;7948:22;7931:49;:::i;:::-;7921:59;;;7556:430;;;;;:::o;7991:497::-;8070:6;8078;8086;8139:2;8127:9;8118:7;8114:23;8110:32;8107:2;;;8160:6;8152;8145:22;8107:2;8201:9;8188:23;8178:33;;8262:2;8251:9;8247:18;8234:32;8289:18;8281:6;8278:30;8275:2;;;8326:6;8318;8311:22;8493:258;8561:6;8569;8622:2;8610:9;8601:7;8597:23;8593:32;8590:2;;;8643:6;8635;8628:22;8590:2;-1:-1:-1;;8671:23:1;;;8741:2;8726:18;;;8713:32;;-1:-1:-1;8580:171:1:o;8756:257::-;8797:3;8835:5;8829:12;8862:6;8857:3;8850:19;8878:63;8934:6;8927:4;8922:3;8918:14;8911:4;8904:5;8900:16;8878:63;:::i;:::-;8995:2;8974:15;-1:-1:-1;;8970:29:1;8961:39;;;;9002:4;8957:50;;8805:208;-1:-1:-1;;8805:208:1:o;9018:637::-;-1:-1:-1;;9355:2:1;9351:15;;;9347:24;;9335:37;;-1:-1:-1;;;;;;9402:33:1;;;;9397:2;9388:12;;9381:55;9470:15;;;9466:24;;9461:2;9452:12;;9445:46;9525:15;;;9521:24;;;9516:2;9507:12;;9500:46;9571:2;9562:12;;9555:28;;;;9599:12;;;9592:28;9645:3;9636:13;;9275:380::o;9660:470::-;9839:3;9877:6;9871:13;9893:53;9939:6;9934:3;9927:4;9919:6;9915:17;9893:53;:::i;:::-;10009:13;;9968:16;;;;10031:57;10009:13;9968:16;10065:4;10053:17;;10031:57;:::i;:::-;10104:20;;9847:283;-1:-1:-1;;;;9847:283:1:o;10135:638::-;10415:3;10453:6;10447:13;10469:53;10515:6;10510:3;10503:4;10495:6;10491:17;10469:53;:::i;:::-;10585:13;;10544:16;;;;10607:57;10585:13;10544:16;10641:4;10629:17;;10607:57;:::i;:::-;-1:-1:-1;;;10686:20:1;;10715:23;;;10765:1;10754:13;;10423:350;-1:-1:-1;;;;10423:350:1:o;11371:488::-;-1:-1:-1;;;;;11640:15:1;;;11622:34;;11692:15;;11687:2;11672:18;;11665:43;11739:2;11724:18;;11717:34;;;11787:3;11782:2;11767:18;;11760:31;;;11565:4;;11808:45;;11833:19;;11825:6;11808:45;:::i;13255:245::-;13401:2;13386:18;;13434:1;13423:13;;13413:2;;13440:18;;:::i;:::-;13469:25;;;13368:132;:::o;13505:243::-;13649:2;13634:18;;13682:1;13671:13;;13661:2;;13688:18;;:::i;13753:393::-;13912:2;13901:9;13894:21;13951:6;13946:2;13935:9;13931:18;13924:34;14008:6;14000;13995:2;13984:9;13980:18;13967:48;13875:4;14035:22;;;14059:2;14031:31;;;14024:45;;;;14130:2;14109:15;;;-1:-1:-1;;14105:29:1;14090:45;14086:54;;13884:262;-1:-1:-1;13884:262:1:o;14151:219::-;14300:2;14289:9;14282:21;14263:4;14320:44;14360:2;14349:9;14345:18;14337:6;14320:44;:::i;15933:335::-;16135:2;16117:21;;;16174:2;16154:18;;;16147:30;-1:-1:-1;;;16208:2:1;16193:18;;16186:41;16259:2;16244:18;;16107:161::o;16633:407::-;16835:2;16817:21;;;16874:2;16854:18;;;16847:30;16913:34;16908:2;16893:18;;16886:62;-1:-1:-1;;;16979:2:1;16964:18;;16957:41;17030:3;17015:19;;16807:233::o;17045:414::-;17247:2;17229:21;;;17286:2;17266:18;;;17259:30;17325:34;17320:2;17305:18;;17298:62;-1:-1:-1;;;17391:2:1;17376:18;;17369:48;17449:3;17434:19;;17219:240::o;19325:346::-;19527:2;19509:21;;;19566:2;19546:18;;;19539:30;-1:-1:-1;;;19600:2:1;19585:18;;19578:52;19662:2;19647:18;;19499:172::o;25710:412::-;25912:2;25894:21;;;25951:2;25931:18;;;25924:30;25990:34;25985:2;25970:18;;25963:62;-1:-1:-1;;;26056:2:1;26041:18;;26034:46;26112:3;26097:19;;25884:238::o;26127:418::-;26329:2;26311:21;;;26368:2;26348:18;;;26341:30;26407:34;26402:2;26387:18;;26380:62;-1:-1:-1;;;26473:2:1;26458:18;;26451:52;26535:3;26520:19;;26301:244::o;26952:413::-;27154:2;27136:21;;;27193:2;27173:18;;;27166:30;27232:34;27227:2;27212:18;;27205:62;-1:-1:-1;;;27298:2:1;27283:18;;27276:47;27355:3;27340:19;;27126:239::o;29032:275::-;29103:2;29097:9;29168:2;29149:13;;-1:-1:-1;;29145:27:1;29133:40;;29203:18;29188:34;;29224:22;;;29185:62;29182:2;;;29250:18;;:::i;:::-;29286:2;29279:22;29077:230;;-1:-1:-1;29077:230:1:o;29312:186::-;29360:4;29393:18;29385:6;29382:30;29379:2;;;29415:18;;:::i;:::-;-1:-1:-1;29481:2:1;29460:15;-1:-1:-1;;29456:29:1;29487:4;29452:40;;29369:129::o;29503:128::-;29543:3;29574:1;29570:6;29567:1;29564:13;29561:2;;;29580:18;;:::i;:::-;-1:-1:-1;29616:9:1;;29551:80::o;29636:120::-;29676:1;29702;29692:2;;29707:18;;:::i;:::-;-1:-1:-1;29741:9:1;;29682:74::o;29761:125::-;29801:4;29829:1;29826;29823:8;29820:2;;;29834:18;;:::i;:::-;-1:-1:-1;29871:9:1;;29810:76::o;29891:258::-;29963:1;29973:113;29987:6;29984:1;29981:13;29973:113;;;30063:11;;;30057:18;30044:11;;;30037:39;30009:2;30002:10;29973:113;;;30104:6;30101:1;30098:13;30095:2;;;-1:-1:-1;;30139:1:1;30121:16;;30114:27;29944:205::o;30154:380::-;30233:1;30229:12;;;;30276;;;30297:2;;30351:4;30343:6;30339:17;30329:27;;30297:2;30404;30396:6;30393:14;30373:18;30370:38;30367:2;;;30450:10;30445:3;30441:20;30438:1;30431:31;30485:4;30482:1;30475:15;30513:4;30510:1;30503:15;30367:2;;30209:325;;;:::o;30539:135::-;30578:3;-1:-1:-1;;30599:17:1;;30596:2;;;30619:18;;:::i;:::-;-1:-1:-1;30666:1:1;30655:13;;30586:88::o;30679:112::-;30711:1;30737;30727:2;;30742:18;;:::i;:::-;-1:-1:-1;30776:9:1;;30717:74::o;30796:127::-;30857:10;30852:3;30848:20;30845:1;30838:31;30888:4;30885:1;30878:15;30912:4;30909:1;30902:15;30928:127;30989:10;30984:3;30980:20;30977:1;30970:31;31020:4;31017:1;31010:15;31044:4;31041:1;31034:15;31060:127;31121:10;31116:3;31112:20;31109:1;31102:31;31152:4;31149:1;31142:15;31176:4;31173:1;31166:15;31192:127;31253:10;31248:3;31244:20;31241:1;31234:31;31284:4;31281:1;31274:15;31308:4;31305:1;31298:15;31324:131;-1:-1:-1;;;;;31399:31:1;;31389:42;;31379:2;;31445:1;31442;31435:12;31379:2;31369:86;:::o;31460:118::-;31546:5;31539:13;31532:21;31525:5;31522:32;31512:2;;31568:1;31565;31558:12;31583:131;-1:-1:-1;;;;;;31657:32:1;;31647:43;;31637:2;;31704:1;31701;31694:12

Swarm Source

ipfs://4e8b63f6716a82b312264e20523b3f70eac98bd14e3023425ac2f26677c7192c
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.