ETH Price: $3,358.30 (+0.31%)

Token

ForgeToken (FORGE)
 

Overview

Max Total Supply

3,292 FORGE

Holders

1,727

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
0 FORGE
0xcac1561326730095b268e0616b660883118a1a1d
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Our mission is to help gamers unlock the value of their gaming profile and earn rewards in the form of in-game content from the most promising up-and-coming games, simply by playing games and contributing to their communities.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ForgeToken

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-10-16
*/

/**`
 *Submitted for verification at polygonscan.com on 2023-04-26
*/

// SPDX-License-Identifier: MIT
// File: Forge Token/Forge_ERC721.sol

// Contract based on https://docs.openzeppelin.com/contracts/4.x/erc721

pragma solidity ^0.8.4;

interface IERC721Receiver {
    function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes memory _data
    ) external returns(bytes4);
}


//=============================================================================
/// @title Forge_ERC721
/// @dev Implementation of the ERC-721 Non-Fungible Token Standard.
///  - This implementation was created to support giving tokens attribute data
///  without increasing the gas cost of minting.
///  - This implementation also enables tokenOfOwnerByIndex and totalSupply.
/// @author Forge Inc.
//=============================================================================
abstract contract Forge_ERC721 {
    //-------------------------------------------------------------------------
    /// @title TokenData
    /// @dev A data structure containing information about a specific token ID.
    ///  - Initializing TokenData costs the same amount of gas as initializing
    ///  _owners for the token ID in the OpenZeppelin ERC721 implementation.
    //-------------------------------------------------------------------------
    struct TokenData {
        // The owner of this token. An address takes up 20 bytes.
        address tokenOwner;
        // The index of this token in OwnerData's tokensOwned array. Max value 65536.
        uint16 tokenIndex;
        // Leftover to fill with arbitrary data by the implementation contract.
        uint80 extraData;
    }

    //-------------------------------------------------------------------------
    /// @title OwnerData
    /// @dev A data structure containing information about a specific address.
    ///  - Initialized the first time an owner either receives a token or sets
    ///  an address approved operator. The expected-case is that OwnerData is
    ///  initialized when an owner mints their first token. 
    ///  - Initializing OwnerData costs the same amount of gas as initializing
    ///  _balances for the owner in the OpenZeppelin ERC721 implementation.
    //-------------------------------------------------------------------------
    struct OwnerData {
        // An array containing the token ids of all tokens owned by this owner
        uint24[] tokensOwned;
        // A mapping of addresses to if they are approved operators for this owner
        mapping (address=>bool) operatorApprovals;
    }

    // Token name
    string public name;
    // Token symbol
    string public symbol;

    // An array containing TokenData for all tokens ever minted.
    // A token's identifier is used to index directly to its data, so the
    // order of _tokenData must never be modified.
    TokenData[] internal _tokenData;
    // A mapping containing OwnerData for all addresses
    mapping (address=>OwnerData) internal _ownerData;
    // A mapping containing approved addresses for each token ID
    mapping (uint=>address) private _tokenApprovals;
    // Number of burned tokens, used to calculate total supply
    uint internal _burnedTokens;

    //-------------------------------------------------------------------------
    /// @dev This emits when ownership of any NFT changes by any mechanism.
    ///  This event also emits when NFTs are created (`from` == 0) and
    ///  destroyed (`to` == 0). Also indicates that the approved address for
    ///  the NFT is reset to none.
    //-------------------------------------------------------------------------
    event Transfer(
        address indexed _from,
        address indexed _to,
        uint256 indexed _tokenId
    );
    
    //-------------------------------------------------------------------------
    /// @dev This emits when the approved address for an NFT is changed or
    ///  reaffirmed. The zero address indicates there is no approved address.
    //-------------------------------------------------------------------------
    event Approval(
        address indexed _owner,
        address indexed _approved,
        uint256 indexed _tokenId
    );

    //-------------------------------------------------------------------------
    /// @dev This emits when an operator is enabled or disabled for an owner.
    ///  The operator can transfer all NFTs of the owner.
    //-------------------------------------------------------------------------
    event ApprovalForAll(
        address indexed _owner,
        address indexed _operator,
        bool _approved
    );

    //-------------------------------------------------------------------------
    /// @dev Throws if a token does not exist or has been burned
    //-------------------------------------------------------------------------
    modifier exists(uint _tokenId) {
        require(
            _tokenId < _tokenData.length && 
            _tokenData[_tokenId].tokenOwner != address(0),
            "ERC721: Token with this ID does not exist"
        );
        _;
    }
    
    //-------------------------------------------------------------------------
    /// @dev Initializes the contract, setting the token collection's `name`
    ///  and `symbol`.
    //-------------------------------------------------------------------------
    constructor(string memory _name, string memory _symbol) {
        _tokenData.push(TokenData(address(0),0,0));
        name = _name;
        symbol = _symbol;
    }


    //=========================================================================
    // PUBLIC FUNCTIONS
    //=========================================================================
    //-------------------------------------------------------------------------
    /// @notice Transfers the ownership of an NFT from one address to another
    ///  -- THE CALLER IS RESPONSIBLE TO CONFIRM THAT `_to` IS CAPABLE OF 
    ///  RECEIVING NFTS OR ELSE THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    //-------------------------------------------------------------------------
    function transferFrom(address _from, address _to, uint _tokenId)
        public
        exists(_tokenId)
    {
        address tokenOwner = _tokenData[_tokenId].tokenOwner;
        require(
            msg.sender == tokenOwner ||
            msg.sender == _tokenApprovals[_tokenId] ||
            _ownerData[tokenOwner].operatorApprovals[msg.sender],
            "ERC721: Sender not owner or approved operator for this token"
        );
        require(
            _from == tokenOwner,
            "ERC721: _from parameter is not the owner of this token"
        );

        _transfer(_to, _tokenId);
    }
    
    function safeTransferFrom(address _from, address _to, uint _tokenId)
        external
    {
        safeTransferFrom(_from, _to, _tokenId, "");
    }
    
    //-------------------------------------------------------------------------
    /// @notice Transfers the ownership of an NFT from one address to another
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
    ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
    ///  `onERC721Received` on `_to` and throws if the return value is not
    ///  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param _data Additional data with no specified format, sent to `_to`
    //-------------------------------------------------------------------------
    function safeTransferFrom(
        address _from,
        address _to,
        uint _tokenId,
        bytes memory _data
    )
        public
        exists(_tokenId)
    {
        address tokenOwner = _tokenData[_tokenId].tokenOwner;
        require(
            msg.sender == tokenOwner ||
            msg.sender == _tokenApprovals[_tokenId] ||
            _ownerData[tokenOwner].operatorApprovals[msg.sender],
            "ERC721: Sender not owner or approved operator for this token"
        );
        require(
            _from == tokenOwner,
            "ERC721: _from parameter is not the owner of this token"
        );

        _transfer(_to, _tokenId);

        require(
            _checkOnERC721Received(address(0), _to, _tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    //-------------------------------------------------------------------------
    /// @notice Change or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    ///  Throws unless `msg.sender` is the current NFT owner, or an
    ///  authorized operator of the current owner.
    /// @param _approved The new approved NFT controller
    /// @param _tokenId The NFT to approve
    //-------------------------------------------------------------------------
    function approve(address _approved, uint256 _tokenId)
        public
        exists(_tokenId)
    {
        address tokenOwner = _tokenData[_tokenId].tokenOwner;
        require(
            msg.sender == tokenOwner ||
            _ownerData[tokenOwner].operatorApprovals[msg.sender],
            "ERC721: Sender does not own this token"
        );
        _tokenApprovals[_tokenId] = _approved;
        emit Approval(_tokenData[_tokenId].tokenOwner, _approved, _tokenId);
    }

    //-------------------------------------------------------------------------
    /// @notice Enable or disable approval for a third party ("operator") to
    ///  manage all of `msg.sender`'s tokens
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
    ///  multiple operators per owner.
    /// @param _operator Address to add to the set of authorized operators
    /// @param _approved True if the operator is approved, false to revoke approval
    //-------------------------------------------------------------------------
    function setApprovalForAll(address _operator, bool _approved) external {
        _ownerData[msg.sender].operatorApprovals[_operator] = _approved;
        emit ApprovalForAll(msg.sender, _operator, _approved);
    }
    
    //-------------------------------------------------------------------------
    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///  uses less than 30,000 gas.
    /// @return bool True if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff
    //-------------------------------------------------------------------------
    function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
        return (
            interfaceID == 0x01ffc9a7 || // ERC165
            interfaceID == 0x80ac58cd || // ERC721
            interfaceID == 0x5b5e139f // ERC721Metadata
        );
    }


    //=========================================================================
    // PUBLIC VIEW FUNCTIONS
    //=========================================================================
    //-------------------------------------------------------------------------
    /// @notice Get the number of valid NFTs tracked by this contract, where
    ///  each one of them has an assigned and queryable owner not equal to
    ///  the zero address.
    /// @return uint Total number of valid NFTs tracked by this contract.
    //-------------------------------------------------------------------------
    function totalSupply() external view returns (uint) {
        return _tokenData.length - _burnedTokens - 1;
    }

    //-------------------------------------------------------------------------
    /// @notice Find the owner of an NFT
    /// @dev NFTs assigned to zero address are considered invalid, and queries
    ///  about them do throw.
    /// @param _tokenId The identifier for an NFT
    /// @return address The address of the owner of the NFT
    //-------------------------------------------------------------------------
    function ownerOf(uint _tokenId)
        external
        view
        exists(_tokenId)
        returns (address)
    {
        return _tokenData[_tokenId].tokenOwner;
    }

    //-------------------------------------------------------------------------
    /// @notice Count all NFTs assigned to an owner
    /// @dev NFTs assigned to the zero address are considered invalid, and
    ///  this function throws for queries about the zero address.
    /// @param _owner The address of the owner to query
    /// @return uint The number of NFTs owned by `_owner`, possibly zero
    //-------------------------------------------------------------------------
    function balanceOf(address _owner) external view returns (uint) {
        require (_owner != address(0), "Invalid balance query");
        return _ownerData[_owner].tokensOwned.length;
    }

    //-------------------------------------------------------------------------
    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    ///  `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner  The address of the owner to query
    /// @param _index A counter less than `balanceOf(_owner)`
    /// @return The token identifier for the `_index`th NFT assigned to
    ///  `_owner`, (sort order not specified)
    //-------------------------------------------------------------------------
    function tokenOfOwnerByIndex(address _owner, uint256 _index)
        external
        view
        returns (uint24)
    {
        require (
            _owner != address(0),
            "ERC721Enumerable: Invalid owner address"
        );
        require (
            _index < _ownerData[_owner].tokensOwned.length,
            "ERC721Enumerable: Invalid index"
        );
        return _ownerData[_owner].tokensOwned[_index];
    }

    //-------------------------------------------------------------------------
    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    ///  `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner  The address of the owner to query
    /// @return uint24[] The token identifiers for the tokens owned by `_owner`,
    ///   (sort order not specified)
    //-------------------------------------------------------------------------
    function tokensOfOwner(address _owner)
        external
        view
        returns (uint24[] memory)
    {
        require (
            _owner != address(0),
            "ERC721Enumerable: Invalid owner address"
        );
        return _ownerData[_owner].tokensOwned;
    }

    //-------------------------------------------------------------------------
    /// @notice Get the approved address for a single NFT
    /// @dev Throws if `_tokenId` is not a valid NFT.
    /// @param _tokenId The NFT to find the approved address for
    /// @return address The approved address for this NFT, or the zero address
    ///  if there is none
    //-------------------------------------------------------------------------
    function getApproved(uint _tokenId)
        external
        view
        exists(_tokenId)
        returns (address)
    {
        return _tokenApprovals[_tokenId];
    }

    //-------------------------------------------------------------------------
    /// @notice Query if an address is an authorized operator for another address
    /// @param _owner The address that owns the NFTs
    /// @param _operator The address that acts on behalf of the owner
    /// @return bool True if `_operator` is an approved operator for `_owner`
    //-------------------------------------------------------------------------
    function isApprovedForAll(address _owner, address _operator)
        external
        view
        returns (bool)
    {
        return _ownerData[_owner].operatorApprovals[_operator];
    }
    
    //-------------------------------------------------------------------------
    /// @notice A distinct Uniform Resource Identifier (URI) for a given token.
    /// @dev Throws if `_tokenId` is not a valid NFT
    /// @param _tokenId The identifier for an NFT
    /// @return string The URI of the specified token
    //-------------------------------------------------------------------------
    function tokenURI(uint256 _tokenId)
        public
        view
        virtual
        returns (string memory);


    //=========================================================================
    // INTERNAL / PRIVATE FUNCTIONS
    //=========================================================================
    function _transfer(address _to, uint _tokenId) private {
        TokenData storage tokenData = _tokenData[_tokenId];
        address from = tokenData.tokenOwner;
        
        // modify `from` owner data
        OwnerData storage ownerData = _ownerData[from];
        uint numberOfTokensOwned = ownerData.tokensOwned.length;
        if (tokenData.tokenIndex < numberOfTokensOwned - 1) {
            uint24 lastOwnedToken = ownerData.tokensOwned[numberOfTokensOwned - 1];
            // swap token to transfer with last owned token in ownerData array
            ownerData.tokensOwned[tokenData.tokenIndex] = lastOwnedToken;
            // set index of last owned token to the swapped index
            _tokenData[lastOwnedToken].tokenIndex = tokenData.tokenIndex;
        }
        // pop the owned token array
        ownerData.tokensOwned.pop();

        // modify `to` owner data
        if (_to != address(0)) {
            // set token index to the new owner's token position
            tokenData.tokenIndex = uint16(_ownerData[_to].tokensOwned.length);
            // add token to new owner's owned token array
            _ownerData[_to].tokensOwned.push(uint24(_tokenId));
        }
        
        // set the ownership of the token
        tokenData.tokenOwner = _to;

        // reset approval
        _tokenApprovals[_tokenId] = address(0);

        // emit transfer event
        emit Transfer(from, _to, _tokenId);
    }

    //-------------------------------------------------------------------------
    /// @dev Safely mints a new token and transfers it to `to`. If `to` refers
    ///  to a smart contract, it must implement {IERC721Receiver-onERC721Received},
    ///  which is called upon a safe transfer. Emits a {Transfer} event.
    /// @param _to target address that will receive the token
    /// @param _extraData arbitrary data to be handled by the
    ///  implementation contract.
    /// @param _data arbitrary data to be handled by the receiver.
    //-------------------------------------------------------------------------
    function _safeMint(address _to, uint80 _extraData, bytes memory _data)
        internal
    {
        uint24 tokenId = uint24(_tokenData.length);
        uint16 tokenIndex = uint16(_ownerData[_to].tokensOwned.length);
        _tokenData.push(TokenData(_to, tokenIndex, _extraData));

        // add token to new owner's owned token array
        _ownerData[_to].tokensOwned.push(tokenId);

        // emit transfer event
        emit Transfer(address(0), _to, tokenId);

        require(
            _checkOnERC721Received(address(0), _to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }    

    //-------------------------------------------------------------------------
    /// @dev Equivalent to `_safeMint(to, quantity, '')`.
    //-------------------------------------------------------------------------
    function _safeMint(address _to, uint80 _extraData) internal {
        _safeMint(_to, _extraData, "");
    }

    //-------------------------------------------------------------------------
    /// @dev Destroys `tokenId`. The approval is cleared when the token is
    ///  burned. This is an internal function that does not check if the sender
    ///  is authorized to operate on the token. Throws if `tokenId` does not
    ///  exist. Emits a {Transfer} event.
    /// @param _tokenId The token to burn
    //-------------------------------------------------------------------------
    function _burn(uint _tokenId) internal exists(_tokenId) {
        _tokenApprovals[_tokenId] = address(0);
        _transfer(address(0), _tokenId);
        ++_burnedTokens;
    }

    //-------------------------------------------------------------------------
    /// @dev Internal function to invoke {IERC721Receiver-onERC721Received} on
    /// a target address.
    /// @param _from address representing the previous owner of the given token ID
    /// @param _to target address that will receive the token
    /// @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.code.length > 0) {
            try IERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }
}
// File: @openzeppelin/contracts/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

// File: Forge Token/ForgeToken.sol

// Contract based on https://docs.openzeppelin.com/contracts/4.x/erc721

pragma solidity ^0.8.4;



interface Forge_Metadata {
    function tokenURI(uint _tokenId) external view returns(string memory);
}

interface IRandomizer {
    function getRandomSeed(
        address userAddress,
        uint256 nonce,
        uint256 lastExtradata,
        bytes calldata signature
    ) external view returns (bytes32);
}

//-----------------------------------------------------------------------------
/// @title FORGE LAUNCH TOKEN
//-----------------------------------------------------------------------------
contract ForgeToken is Forge_ERC721, Ownable {

    struct TokenAttributes {
        uint16 xp;
        bool isSpecialVariant;
    }

    uint private constant _NUM_XP_VALUES = 10;
    // [0064 = 100, 01F4 = 500, 03E8 = 1000, 1388 = 5000, 1D4C = 7500, 2710 = 10000, 3A98 = 15000, 4E20 = 20000, 61A8 = 25000, 7FF8 = 32760]
    bytes32 private constant _XP_VALUES = 0x006401F403E813881D4C27103A984E2061A87FF8000000000000000000000000;
    // 02 = ~1%, 05 = ~2%, 0D = ~5%, 1A = ~10%, 33 = ~20%
    bytes32 private constant _XP_OCCURRENCE_RATES = 0x1A3333331A1A0D05050200000000000000000000000000000000000000000000;
    // 13/256 = ~5%
    uint8 private constant _SPECIAL_VARIANT_RATE = 13;

    Forge_Metadata public metadataContract = Forge_Metadata(0x31d64a222ad81004613C4Bb830733438877D8E21);

    address public minterAddress = 0x86FeD702bCAF26f0b41476a58d4E88242654146E;

    // Oct 16 2023 at 12:30:00 UTC
    uint256 public dropStartTime = 1697459400;

    // Approx 6 months
    uint256 public dropDuration = 4380 hours;

    uint256 public supplyLimit = 3333;
    uint256 public reservedMints = 433;


    // In order to ensure each owner only mints once per signature, each mint
    // is assigned a unique nonce. Subsequent mint attempts with the same
    // nonce will fail.
    mapping(uint256 => bool) public usedNonces;

    // Randomizer contract
    IRandomizer private _randomizerContract;
    uint256 private _specialVariants = 0;

    //-------------------------------------------------------------------------
    /// @dev This emits when XP is burned from a Forge Token
    //-------------------------------------------------------------------------
    event BurnXp(uint _tokenId, uint16 _amountBurned);

    constructor() Forge_ERC721("ForgeToken", "FORGE") {}

    //-------------------------------------------------------------------------
    /// @notice Sets a new address to be the Minter
    /// @dev Throws if sender is not the contract owner
    /// @param _newMinter The new address to be the Minter
    //-------------------------------------------------------------------------
    function setMinterAddress(address _newMinter) external onlyOwner {
        minterAddress = _newMinter;
    }

    //-------------------------------------------------------------------------
    /// @notice Replaces the current metadata contract reference with a new one
    /// @dev Throws if sender is not the contract owner
    /// @param _contractAddress The address of the metadata contract
    //-------------------------------------------------------------------------
    function setMetadataContract(address _contractAddress) external onlyOwner {
        metadataContract = Forge_Metadata(_contractAddress);
    }

    //-------------------------------------------------------------------------
    /// @notice Sets the randomizer contract address
    /// @dev Throws if sender is not the contract owner
    /// @param _contractAddress The address of the randomizer contract
    //-------------------------------------------------------------------------
    function setRandomizerContract(address _contractAddress) external onlyOwner {
        _randomizerContract = IRandomizer(_contractAddress);
    }

    //-------------------------------------------------------------------------
    /// @notice Sets the start time where minting is allowed
    /// @dev Throws if sender is not the contract owner
    /// @param _dropStartTime The new timestamp in seconds
    //-------------------------------------------------------------------------
    function setDropStartTime(uint256 _dropStartTime) external onlyOwner {
        require(
            _dropStartTime >= block.timestamp,
            "Drop start time must be later than now"
        );
        dropStartTime = _dropStartTime;
    }

    //-------------------------------------------------------------------------
    /// @notice Sets the duration where minting is allowed
    /// @dev Throws if sender is not the contract owner
    /// @param _dropDuration The new duration in seconds
    //-------------------------------------------------------------------------
    function setDropDuration(uint256 _dropDuration) external onlyOwner {
        require (_dropDuration > 0, "Drop duration must be greater than zero");
        dropDuration = _dropDuration;
    }

    //-------------------------------------------------------------------------
    /// @notice Sets the supply limit to a higher number
    /// @dev Throws if `_newSupplyLimit` is less than current supply limit.
    ///  Throws if sender is not the contract owner.
    /// @param _newSupplyLimit The new supply limit
    //-------------------------------------------------------------------------
    function increaseSupplyLimit(uint256 _newSupplyLimit) external onlyOwner {
        require (
            block.timestamp <= dropStartTime + dropDuration,
            "Drop ended, increasing supply limit no longer allowed"
        );
        require (
            _newSupplyLimit > supplyLimit, 
            "New supply limit must be greater than previous supply limit"
        );
        supplyLimit = _newSupplyLimit;
    }

    //-------------------------------------------------------------------------
    /// @notice Mints a new Forge Badge for the sender.
    ///  Validates using a signature signed by the minter
    ///  The token ID of the new badge is determined by the totalSupply when
    ///  minted. Randomly rolls XP and specialVariant value.
    /// @dev Throws if there's a signer address mismatch
    /// @param _nonce A unique ID used to guard against double-mints
    /// @param _sig The signature of the recipient of the minted NFT
    //-------------------------------------------------------------------------
    function safeMint(uint256 _nonce, bytes memory _sig) external {
        require(block.timestamp >= dropStartTime, "Drop not started");
        require(block.timestamp <= dropStartTime + dropDuration, "Drop ended");
        require(tx.origin == msg.sender, "Transaction origin not from sender");
        require(
            _tokenData.length - 1 < supplyLimit - reservedMints,
            "Collection has minted out"
        );
        require(!usedNonces[_nonce], "Nonce already used");

        // validate message
        bytes32 message = _generateMessage(msg.sender, _nonce, address(this));
        require(
            _recoverSigner(message, _sig) == minterAddress,
            "Signer address mismatch"
        );

        // Generate random seed
        bytes32 randomSeed = _randomizerContract.getRandomSeed(
            msg.sender,
            _nonce,
            uint256(_tokenData[_tokenData.length - 1].extraData),
            _sig
        );

        // Roll attributes
        uint16 xpValue = _calculateXpValue(uint8(randomSeed[0]));
        // Also check if used special variants are less than 5% of supply limit
        bool isSpecialVariant = (
            uint8(randomSeed[1]) < _SPECIAL_VARIANT_RATE &&
            _specialVariants < supplyLimit * 13 / 256
        );
        if (isSpecialVariant) {
            ++_specialVariants;
        }

        uint40 packedAttributes = (uint24(xpValue) << 8) + (isSpecialVariant ? 1 : 0);

        // mint the new token
        usedNonces[_nonce] = true;
        _safeMint(msg.sender, packedAttributes);
    }

    //-------------------------------------------------------------------------
    /// @notice Mints a new Forge Badge for a given address only by the minter.
    ///  The token ID of the new badge is determined by the totalSupply when
    ///  minted. Randomly rolls XP and specialVariant value.
    /// @dev Throws if there's a signer address mismatch
    /// @param _nonce A unique ID used to guard against double-mints
    /// @param _to address of the recipient of the minted NFT
    //-------------------------------------------------------------------------
    function safeMint(uint256 _nonce, address _to) external {
        require(msg.sender == minterAddress, "Only minterAddress can mint");
        require(reservedMints > 0, "No more tokens in reserve");
        require(!usedNonces[_nonce], "Nonce already used");

        // Generate random seed
        bytes32 randomSeed = keccak256(
            abi.encodePacked(
                block.timestamp,
                _to,
                _tokenData.length
            )
        );

        // Roll attributes
        uint16 xpValue = _calculateXpValue(uint8(randomSeed[0]));
        bool isSpecialVariant = uint8(randomSeed[1]) < _SPECIAL_VARIANT_RATE;
        uint40 packedAttributes = (uint24(xpValue) << 8) + (isSpecialVariant ? 1 : 0);

        // mint the new token
        usedNonces[_nonce] = true;
        _safeMint(_to, packedAttributes);

        --reservedMints;
    }

    //-------------------------------------------------------------------------
    /// @notice Burns an existing Forge Badge. Its XP value will be emitted as
    ///  an event.
    /// @dev Throws if sender is not the owner of the specified token.
    /// @param _tokenId The ID of the token to burn
    //-------------------------------------------------------------------------
    function burn(uint _tokenId) external {
        require (
            msg.sender == _tokenData[_tokenId].tokenOwner,
            "Sender must own token to burn"
        );

        TokenAttributes memory attributes = tokenAttributes(_tokenId);

        uint16 amountBurned = attributes.xp;

        _burn(_tokenId);

        emit BurnXp(_tokenId, amountBurned);
    }

    //-------------------------------------------------------------------------
    /// @notice Gets the attributes of a given token
    /// @param _tokenId The ID of the token to query
    //-------------------------------------------------------------------------
    function tokenAttributes(uint _tokenId) 
        public
        view
        exists(_tokenId)
        returns(TokenAttributes memory attributes)
    {
        uint tokenData = _tokenData[_tokenId].extraData;
        // extraData ends in 1 if the token is a special variant
        attributes.isSpecialVariant = tokenData % 2 == 1;
        attributes.xp = uint16(tokenData >> 8);
    }

    //-------------------------------------------------------------------------
    /// @dev delegates tokenURI to external smart contract
    //-------------------------------------------------------------------------
    function tokenURI(uint _tokenId)
        public
        view
        override
        returns (string memory)
    {
        return metadataContract.tokenURI(_tokenId);
    }

    //-------------------------------------------------------------------------
    // Takes a random number from 0 to 255 and returns an xp value
    //-------------------------------------------------------------------------
    function _calculateXpValue(uint8 _rand)
        private
        pure
        returns (uint16)
    {
        // get index from occurrence rates
        uint index;
        for (uint i = 0; i < _NUM_XP_VALUES; ++i) {
            if (_rand < uint8(_XP_OCCURRENCE_RATES[i])) {
                index = i;
                break;
            }
            _rand -= uint8(_XP_OCCURRENCE_RATES[i]);
        }

        // convert index into a bytes16 value
        uint16 xpValue = uint16(uint8(_XP_VALUES[index * 2])) << 8;
        xpValue += uint8(_XP_VALUES[index * 2 + 1]);

        return xpValue;
    }

    //-------------------------------------------------------------------------
    // Takes a message and signature and retrieves the signer address
    //-------------------------------------------------------------------------
    function _recoverSigner(bytes32 _message, bytes memory _sig)
        private
        pure
        returns (address)
    {
        require(_sig.length == 65, "Length of signature must be 65");

        // split signature
        uint8 v;
        bytes32 r;
        bytes32 s;
        assembly {
            // first 32 bytes, after the length prefix
            r := mload(add(_sig, 32))
            // second 32 bytes
            s := mload(add(_sig, 64))
            // final byte (first byte of the next 32 bytes)
            v := byte(0, mload(add(_sig, 96)))
        }

        // return the address from the given signature by calculating a
        // recovery function of ECDSA
        return ecrecover(_message, v, r, s);
    }

    //-------------------------------------------------------------------------
    // Builds an encoded message with a prefixed hash to mimic the behavior
    // of eth_sign.
    //-------------------------------------------------------------------------
    function _generateMessage(address _sender, uint _nonce, address _contract)
        private
        pure
        returns (bytes32 message)
    {
        message = keccak256(abi.encodePacked(_sender, _nonce, _contract));
        message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"_amountBurned","type":"uint16"}],"name":"BurnXp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_approved","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dropDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dropStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newSupplyLimit","type":"uint256"}],"name":"increaseSupplyLimit","outputs":[],"stateMutability":"nonpayable","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":"metadataContract","outputs":[{"internalType":"contract Forge_Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"_sig","type":"bytes"}],"name":"safeMint","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":"uint256","name":"_dropDuration","type":"uint256"}],"name":"setDropDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dropStartTime","type":"uint256"}],"name":"setDropStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setMetadataContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newMinter","type":"address"}],"name":"setMinterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setRandomizerContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenAttributes","outputs":[{"components":[{"internalType":"uint16","name":"xp","type":"uint16"},{"internalType":"bool","name":"isSpecialVariant","type":"bool"}],"internalType":"struct ForgeToken.TokenAttributes","name":"attributes","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint24[]","name":"","type":"uint24[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedNonces","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

6080604052600780546001600160a01b03199081167331d64a222ad81004613c4bb830733438877d8e2117909155600880549091167386fed702bcaf26f0b41476a58d4e88242654146e17905563652d2cc860095562f099c0600a55610d05600b556101b1600c556000600f553480156200007957600080fd5b50604080518082018252600a8152692337b933b2aa37b5b2b760b11b602080830191909152825180840184526005815264464f52474560d81b81830152835160608101855260008082529281018381529481018381526002805460018101825590855291517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9092018054965191516001600160501b0316600160b01b026001600160b01b0361ffff93909316600160a01b026001600160b01b03199098166001600160a01b0394909416939093179690961716179093559091906200016083826200028d565b5060016200016f82826200028d565b5050506200018c620001866200019260201b60201c565b62000196565b62000359565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200021357607f821691505b6020821081036200023457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200028857600081815260208120601f850160051c81016020861015620002635750805b601f850160051c820191505b8181101562000284578281556001016200026f565b5050505b505050565b81516001600160401b03811115620002a957620002a9620001e8565b620002c181620002ba8454620001fe565b846200023a565b602080601f831160018114620002f95760008415620002e05750858301515b600019600386901b1c1916600185901b17855562000284565b600085815260208120601f198616915b828110156200032a5788860151825594840194600190910190840162000309565b5085821015620003495787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6129f380620003696000396000f3fe608060405234801561001057600080fd5b506004361061021c5760003560e01c8063624ae7ae11610125578063a22cb465116100ad578063e5187f431161007c578063e5187f4314610493578063e985e9c5146104a6578063ed565234146104e6578063f2824b53146104f9578063f2fde38b1461052d57600080fd5b8063a22cb46514610447578063a3106b951461045a578063b88d4fde1461046d578063c87b56dd1461048057600080fd5b806370a08231116100f457806370a08231146103f3578063715018a6146104065780638462151c1461040e5780638da5cb5b1461042e57806395d89b411461043f57600080fd5b8063624ae7ae1461039757806362bdfceb146103aa5780636352211e146103bd5780636717e41c146103d057600080fd5b80632cb9b2ac116101a857806342842e0e1161017757806342842e0e1461034257806342966c68146103555780635143b4d61461036857806354d259de146103715780635b74bb491461038457600080fd5b80632cb9b2ac146102ec5780632f745c59146102f557806334d722c91461031c578063352098211461032f57600080fd5b8063095ea7b3116101ef578063095ea7b3146102a057806318160ddd146102b557806319d1997a146102bd5780631e7427e7146102c657806323b872dd146102d957600080fd5b806301ffc9a714610221578063044ad6221461024957806306fdde0314610260578063081812fc14610275575b600080fd5b61023461022f36600461220d565b610540565b60405190151581526020015b60405180910390f35b610252600a5481565b604051908152602001610240565b610268610592565b6040516102409190612281565b610288610283366004612294565b610620565b6040516001600160a01b039091168152602001610240565b6102b36102ae3660046122c9565b6106ad565b005b61025261084d565b610252600b5481565b6102b36102d4366004612294565b610872565b6102b36102e73660046122f3565b610973565b610252600c5481565b6103086103033660046122c9565b610ab2565b60405162ffffff9091168152602001610240565b600854610288906001600160a01b031681565b600754610288906001600160a01b031681565b6102b36103503660046122f3565b610b98565b6102b3610363366004612294565b610bb8565b61025260095481565b6102b361037f366004612294565b610c88565b6102b3610392366004612294565b610cf4565b6102b36103a536600461232f565b610d61565b6102b36103b836600461234a565b610d8b565b6102886103cb366004612294565b610f65565b6102346103de366004612294565b600d6020526000908152604090205460ff1681565b61025261040136600461232f565b610ff7565b6102b3611063565b61042161041c36600461232f565b611077565b6040516102409190612376565b6006546001600160a01b0316610288565b610268611133565b6102b36104553660046123bf565b611140565b6102b361046836600461232f565b6111b0565b6102b361047b3660046124c0565b6111da565b61026861048e366004612294565b611343565b6102b36104a136600461232f565b6113b5565b6102346104b4366004612528565b6001600160a01b0391821660009081526003602090815260408083209390941682526001909201909152205460ff1690565b6102b36104f4366004612552565b6113df565b61050c610507366004612294565b6117fa565b60408051825161ffff16815260209283015115159281019290925201610240565b6102b361053b36600461232f565b6118c3565b60006301ffc9a760e01b6001600160e01b03198316148061057157506380ac58cd60e01b6001600160e01b03198316145b8061058c5750635b5e139f60e01b6001600160e01b03198316145b92915050565b6000805461059f90612599565b80601f01602080910402602001604051908101604052809291908181526020018280546105cb90612599565b80156106185780601f106105ed57610100808354040283529160200191610618565b820191906000526020600020905b8154815290600101906020018083116105fb57829003601f168201915b505050505081565b600254600090829081108015610667575060006001600160a01b03166002828154811061064f5761064f6125cd565b6000918252602090912001546001600160a01b031614155b61068c5760405162461bcd60e51b8152600401610683906125e3565b60405180910390fd5b6000838152600460205260409020546001600160a01b031691505b50919050565b6002548190811080156106f1575060006001600160a01b0316600282815481106106d9576106d96125cd565b6000918252602090912001546001600160a01b031614155b61070d5760405162461bcd60e51b8152600401610683906125e3565b600060028381548110610722576107226125cd565b6000918252602090912001546001600160a01b031690503381148061076d57506001600160a01b038116600090815260036020908152604080832033845260010190915290205460ff165b6107c85760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2053656e64657220646f6573206e6f74206f776e2074686973604482015265103a37b5b2b760d11b6064820152608401610683565b600083815260046020526040902080546001600160a01b0319166001600160a01b03861690811790915560028054859291908390811061080a5761080a6125cd565b60009182526020822001546040516001600160a01b03909116917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b6005546002546000916001916108639190612642565b61086d9190612642565b905090565b61087a61193c565b600a5460095461088a9190612655565b4211156108f75760405162461bcd60e51b815260206004820152603560248201527f44726f7020656e6465642c20696e6372656173696e6720737570706c79206c696044820152741b5a5d081b9bc81b1bdb99d95c88185b1b1bddd959605a1b6064820152608401610683565b600b54811161096e5760405162461bcd60e51b815260206004820152603b60248201527f4e657720737570706c79206c696d6974206d757374206265206772656174657260448201527f207468616e2070726576696f757320737570706c79206c696d697400000000006064820152608401610683565b600b55565b6002548190811080156109b7575060006001600160a01b03166002828154811061099f5761099f6125cd565b6000918252602090912001546001600160a01b031614155b6109d35760405162461bcd60e51b8152600401610683906125e3565b6000600283815481106109e8576109e86125cd565b6000918252602090912001546001600160a01b0316905033811480610a2357506000838152600460205260409020546001600160a01b031633145b80610a5457506001600160a01b038116600090815260036020908152604080832033845260010190915290205460ff165b610a705760405162461bcd60e51b815260040161068390612668565b806001600160a01b0316856001600160a01b031614610aa15760405162461bcd60e51b8152600401610683906126c5565b610aab8484611996565b5050505050565b60006001600160a01b038316610ada5760405162461bcd60e51b81526004016106839061271b565b6001600160a01b0383166000908152600360205260409020548210610b415760405162461bcd60e51b815260206004820152601f60248201527f455243373231456e756d657261626c653a20496e76616c696420696e646578006044820152606401610683565b6001600160a01b0383166000908152600360205260409020805483908110610b6b57610b6b6125cd565b90600052602060002090600a91828204019190066003029054906101000a900462ffffff16905092915050565b610bb3838383604051806020016040528060008152506111da565b505050565b60028181548110610bcb57610bcb6125cd565b6000918252602090912001546001600160a01b03163314610c2e5760405162461bcd60e51b815260206004820152601d60248201527f53656e646572206d757374206f776e20746f6b656e20746f206275726e0000006044820152606401610683565b6000610c39826117fa565b8051909150610c4783611c1a565b6040805184815261ffff831660208201527fa02a1adcdf79c09fc7fa0260c243670fdcf57eb0ce227002b0e5a68ebf0fd8bc910160405180910390a1505050565b610c9061193c565b42811015610cef5760405162461bcd60e51b815260206004820152602660248201527f44726f702073746172742074696d65206d757374206265206c61746572207468604482015265616e206e6f7760d01b6064820152608401610683565b600955565b610cfc61193c565b60008111610d5c5760405162461bcd60e51b815260206004820152602760248201527f44726f70206475726174696f6e206d7573742062652067726561746572207468604482015266616e207a65726f60c81b6064820152608401610683565b600a55565b610d6961193c565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b03163314610de55760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206d696e746572416464726573732063616e206d696e7400000000006044820152606401610683565b6000600c5411610e375760405162461bcd60e51b815260206004820152601960248201527f4e6f206d6f726520746f6b656e7320696e2072657365727665000000000000006044820152606401610683565b6000828152600d602052604090205460ff1615610e8b5760405162461bcd60e51b8152602060048201526012602482015271139bdb98d948185b1c9958591e481d5cd95960721b6044820152606401610683565b600254604051600091610ec7914291859160200192835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b60408051601f19818403018152919052805160209091012090506000610eef82825b1a611cb7565b9050600d600183901a10600081610f07576000610f0a565b60015b610f209060ff1662ffff00600886901b16612762565b6000878152600d60205260409020805460ff1916600117905562ffffff169050610f4a8582611dc6565b600c60008154610f5990612785565b90915550505050505050565b600254600090829081108015610fac575060006001600160a01b031660028281548110610f9457610f946125cd565b6000918252602090912001546001600160a01b031614155b610fc85760405162461bcd60e51b8152600401610683906125e3565b60028381548110610fdb57610fdb6125cd565b6000918252602090912001546001600160a01b03169392505050565b60006001600160a01b0382166110475760405162461bcd60e51b8152602060048201526015602482015274496e76616c69642062616c616e636520717565727960581b6044820152606401610683565b506001600160a01b031660009081526003602052604090205490565b61106b61193c565b6110756000611de4565b565b60606001600160a01b03821661109f5760405162461bcd60e51b81526004016106839061271b565b6001600160a01b0382166000908152600360209081526040918290208054835181840281018401909452808452909183018282801561112757602002820191906000526020600020906000905b82829054906101000a900462ffffff1662ffffff16815260200190600301906020826002010492830192600103820291508084116110ec5790505b50505050509050919050565b6001805461059f90612599565b3360008181526003602090815260408083206001600160a01b0387168085526001909101835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6111b861193c565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b60025482908110801561121e575060006001600160a01b031660028281548110611206576112066125cd565b6000918252602090912001546001600160a01b031614155b61123a5760405162461bcd60e51b8152600401610683906125e3565b60006002848154811061124f5761124f6125cd565b6000918252602090912001546001600160a01b031690503381148061128a57506000848152600460205260409020546001600160a01b031633145b806112bb57506001600160a01b038116600090815260036020908152604080832033845260010190915290205460ff165b6112d75760405162461bcd60e51b815260040161068390612668565b806001600160a01b0316866001600160a01b0316146113085760405162461bcd60e51b8152600401610683906126c5565b6113128585611996565b61131f6000868686611e36565b61133b5760405162461bcd60e51b81526004016106839061279c565b505050505050565b60075460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd90602401600060405180830381865afa15801561138d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261058c91908101906127ee565b6113bd61193c565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6009544210156114245760405162461bcd60e51b815260206004820152601060248201526f111c9bdc081b9bdd081cdd185c9d195960821b6044820152606401610683565b600a546009546114349190612655565b4211156114705760405162461bcd60e51b815260206004820152600a602482015269111c9bdc08195b99195960b21b6044820152606401610683565b3233146114ca5760405162461bcd60e51b815260206004820152602260248201527f5472616e73616374696f6e206f726967696e206e6f742066726f6d2073656e6460448201526132b960f11b6064820152608401610683565b600c54600b546114da9190612642565b6002546114e990600190612642565b106115365760405162461bcd60e51b815260206004820152601960248201527f436f6c6c656374696f6e20686173206d696e746564206f7574000000000000006044820152606401610683565b6000828152600d602052604090205460ff161561158a5760405162461bcd60e51b8152602060048201526012602482015271139bdb98d948185b1c9958591e481d5cd95960721b6044820152606401610683565b6040805133606090811b6bffffffffffffffffffffffff19908116602080850191909152603484018790523090921b166054830152825160488184030181526068830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000608884015260a4808401919091528351808403909101815260c490920190925280519101206008546001600160a01b03166116318284611f37565b6001600160a01b0316146116875760405162461bcd60e51b815260206004820152601760248201527f5369676e65722061646472657373206d69736d617463680000000000000000006044820152606401610683565b600e54600280546000926001600160a01b031691639b84229891339188916116b190600190612642565b815481106116c1576116c16125cd565b60009182526020909120015460405160e085901b6001600160e01b0319168152611702939291600160b01b90046001600160501b0316908990600401612865565b602060405180830381865afa15801561171f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611743919061289c565b905060006117518282610ee9565b90506000600d8360011a1080156117845750610100600b54600d61177591906128b5565b61177f91906128e2565b600f54105b905080156117a057600f6000815461179b906128f6565b909155505b6000816117ae5760006117b1565b60015b6117c79060ff1662ffff00600886901b16612762565b6000888152600d60205260409020805460ff1916600117905562ffffff1690506117f13382611dc6565b50505050505050565b6040805180820190915260008082526020820152600254829081108015611852575060006001600160a01b03166002828154811061183a5761183a6125cd565b6000918252602090912001546001600160a01b031614155b61186e5760405162461bcd60e51b8152600401610683906125e3565b600060028481548110611883576118836125cd565b600091825260209091200154600160b01b90046001600160501b031690506118ac60028261290f565b600114602084015260081c61ffff16825250919050565b6118cb61193c565b6001600160a01b0381166119305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610683565b61193981611de4565b50565b6006546001600160a01b031633146110755760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610683565b6000600282815481106119ab576119ab6125cd565b6000918252602080832090910180546001600160a01b031680845260039092526040909220805492935090916119e2600182612642565b8454600160a01b900461ffff161015611aeb57600082611a03600184612642565b81548110611a1357611a136125cd565b90600052602060002090600a91828204019190066003029054906101000a900462ffffff16905080836000018660000160149054906101000a900461ffff1661ffff1681548110611a6657611a666125cd565b90600052602060002090600a91828204019190066003026101000a81548162ffffff021916908362ffffff1602179055508460000160149054906101000a900461ffff1660028262ffffff1681548110611ac257611ac26125cd565b9060005260206000200160000160146101000a81548161ffff021916908361ffff160217905550505b8154829080611afc57611afc612923565b60019003818190600052602060002090600a91828204019190066003026101000a81549062ffffff0219169055905560006001600160a01b0316866001600160a01b031614611bb2576001600160a01b038616600090815260036020818152604083208054885461ffff60a01b1916600160a01b61ffff9092169190910217885580546001810182559084529220600a8084049091018054919093069091026101000a62ffffff81810219909216918816021790555b83546001600160a01b038088166001600160a01b03199283168117875560008881526004602052604080822080549095169094559251889391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050505050565b600254819081108015611c5e575060006001600160a01b031660028281548110611c4657611c466125cd565b6000918252602090912001546001600160a01b031614155b611c7a5760405162461bcd60e51b8152600401610683906125e3565b600082815260046020526040812080546001600160a01b0319169055611ca09083611996565b600560008154611caf906128f6565b909155505050565b60008060005b600a811015611d3557690d1999998d0d0682828160b11b8160208110611ce557611ce56125cd565b1a60ff85161015611cf857809150611d35565b690d1999998d0d0682828160b11b8160208110611d1757611d176125cd565b611d2391901a85612939565b9350611d2e816128f6565b9050611cbd565b5060006008720c803e807d027103a984e2075309c40c350fff60631b611d5c8460026128b5565b60208110611d6c57611d6c6125cd565b1a61ffff16901b9050720c803e807d027103a984e2075309c40c350fff60631b611d978360026128b5565b611da2906001612655565b60208110611db257611db26125cd565b611dbe91901a82612952565b949350505050565b611de0828260405180602001604052806000815250611fff565b5050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b15611f2c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611e7a90339089908890889060040161296d565b6020604051808303816000875af1925050508015611eb5575060408051601f3d908101601f19168201909252611eb2918101906129a0565b60015b611f12573d808015611ee3576040519150601f19603f3d011682016040523d82523d6000602084013e611ee8565b606091505b508051600003611f0a5760405162461bcd60e51b81526004016106839061279c565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611dbe565b506001949350505050565b60008151604114611f8a5760405162461bcd60e51b815260206004820152601e60248201527f4c656e677468206f66207369676e6174757265206d75737420626520363500006044820152606401610683565b602082810151604080850151606080870151835160008082529681018086528a9052951a928501839052840183905260808401819052909260019060a0016020604051602081039080840390855afa158015611fea573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006002805490509050600060036000866001600160a01b03166001600160a01b0316815260200190815260200160002060000180549050905060026040518060600160405280876001600160a01b031681526020018361ffff168152602001866001600160501b03168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a8154816001600160501b0302191690836001600160501b03160217905550505060036000866001600160a01b03166001600160a01b031681526020019081526020016000206000018290806001815401808255809150506001900390600052602060002090600a91828204019190066003029091909190916101000a81548162ffffff021916908362ffffff1602179055508162ffffff16856001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46121db6000868462ffffff1686611e36565b610aab5760405162461bcd60e51b81526004016106839061279c565b6001600160e01b03198116811461193957600080fd5b60006020828403121561221f57600080fd5b813561222a816121f7565b9392505050565b60005b8381101561224c578181015183820152602001612234565b50506000910152565b6000815180845261226d816020860160208601612231565b601f01601f19169290920160200192915050565b60208152600061222a6020830184612255565b6000602082840312156122a657600080fd5b5035919050565b80356001600160a01b03811681146122c457600080fd5b919050565b600080604083850312156122dc57600080fd5b6122e5836122ad565b946020939093013593505050565b60008060006060848603121561230857600080fd5b612311846122ad565b925061231f602085016122ad565b9150604084013590509250925092565b60006020828403121561234157600080fd5b61222a826122ad565b6000806040838503121561235d57600080fd5b8235915061236d602084016122ad565b90509250929050565b6020808252825182820181905260009190848201906040850190845b818110156123b357835162ffffff1683529284019291840191600101612392565b50909695505050505050565b600080604083850312156123d257600080fd5b6123db836122ad565b9150602083013580151581146123f057600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561243a5761243a6123fb565b604052919050565b600067ffffffffffffffff82111561245c5761245c6123fb565b50601f01601f191660200190565b600082601f83011261247b57600080fd5b813561248e61248982612442565b612411565b8181528460208386010111156124a357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080608085870312156124d657600080fd5b6124df856122ad565b93506124ed602086016122ad565b925060408501359150606085013567ffffffffffffffff81111561251057600080fd5b61251c8782880161246a565b91505092959194509250565b6000806040838503121561253b57600080fd5b612544836122ad565b915061236d602084016122ad565b6000806040838503121561256557600080fd5b82359150602083013567ffffffffffffffff81111561258357600080fd5b61258f8582860161246a565b9150509250929050565b600181811c908216806125ad57607f821691505b6020821081036106a757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60208082526029908201527f4552433732313a20546f6b656e2077697468207468697320494420646f6573206040820152681b9bdd08195e1a5cdd60ba1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561058c5761058c61262c565b8082018082111561058c5761058c61262c565b6020808252603c908201527f4552433732313a2053656e646572206e6f74206f776e6572206f72206170707260408201527f6f766564206f70657261746f7220666f72207468697320746f6b656e00000000606082015260800190565b60208082526036908201527f4552433732313a205f66726f6d20706172616d65746572206973206e6f74207460408201527534329037bbb732b91037b3103a3434b9903a37b5b2b760511b606082015260800190565b60208082526027908201527f455243373231456e756d657261626c653a20496e76616c6964206f776e6572206040820152666164647265737360c81b606082015260800190565b62ffffff81811683821601908082111561277e5761277e61262c565b5092915050565b6000816127945761279461262c565b506000190190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60006020828403121561280057600080fd5b815167ffffffffffffffff81111561281757600080fd5b8201601f8101841361282857600080fd5b805161283661248982612442565b81815285602083850101111561284b57600080fd5b61285c826020830160208601612231565b95945050505050565b60018060a01b03851681528360208201528260408201526080606082015260006128926080830184612255565b9695505050505050565b6000602082840312156128ae57600080fd5b5051919050565b808202811582820484141761058c5761058c61262c565b634e487b7160e01b600052601260045260246000fd5b6000826128f1576128f16128cc565b500490565b6000600182016129085761290861262c565b5060010190565b60008261291e5761291e6128cc565b500690565b634e487b7160e01b600052603160045260246000fd5b60ff828116828216039081111561058c5761058c61262c565b61ffff81811683821601908082111561277e5761277e61262c565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061289290830184612255565b6000602082840312156129b257600080fd5b815161222a816121f756fea264697066735822122047082ee072ea47773af03c17deb69717821bda263ea33adb35f23d7990a7ff9364736f6c63430008130033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061021c5760003560e01c8063624ae7ae11610125578063a22cb465116100ad578063e5187f431161007c578063e5187f4314610493578063e985e9c5146104a6578063ed565234146104e6578063f2824b53146104f9578063f2fde38b1461052d57600080fd5b8063a22cb46514610447578063a3106b951461045a578063b88d4fde1461046d578063c87b56dd1461048057600080fd5b806370a08231116100f457806370a08231146103f3578063715018a6146104065780638462151c1461040e5780638da5cb5b1461042e57806395d89b411461043f57600080fd5b8063624ae7ae1461039757806362bdfceb146103aa5780636352211e146103bd5780636717e41c146103d057600080fd5b80632cb9b2ac116101a857806342842e0e1161017757806342842e0e1461034257806342966c68146103555780635143b4d61461036857806354d259de146103715780635b74bb491461038457600080fd5b80632cb9b2ac146102ec5780632f745c59146102f557806334d722c91461031c578063352098211461032f57600080fd5b8063095ea7b3116101ef578063095ea7b3146102a057806318160ddd146102b557806319d1997a146102bd5780631e7427e7146102c657806323b872dd146102d957600080fd5b806301ffc9a714610221578063044ad6221461024957806306fdde0314610260578063081812fc14610275575b600080fd5b61023461022f36600461220d565b610540565b60405190151581526020015b60405180910390f35b610252600a5481565b604051908152602001610240565b610268610592565b6040516102409190612281565b610288610283366004612294565b610620565b6040516001600160a01b039091168152602001610240565b6102b36102ae3660046122c9565b6106ad565b005b61025261084d565b610252600b5481565b6102b36102d4366004612294565b610872565b6102b36102e73660046122f3565b610973565b610252600c5481565b6103086103033660046122c9565b610ab2565b60405162ffffff9091168152602001610240565b600854610288906001600160a01b031681565b600754610288906001600160a01b031681565b6102b36103503660046122f3565b610b98565b6102b3610363366004612294565b610bb8565b61025260095481565b6102b361037f366004612294565b610c88565b6102b3610392366004612294565b610cf4565b6102b36103a536600461232f565b610d61565b6102b36103b836600461234a565b610d8b565b6102886103cb366004612294565b610f65565b6102346103de366004612294565b600d6020526000908152604090205460ff1681565b61025261040136600461232f565b610ff7565b6102b3611063565b61042161041c36600461232f565b611077565b6040516102409190612376565b6006546001600160a01b0316610288565b610268611133565b6102b36104553660046123bf565b611140565b6102b361046836600461232f565b6111b0565b6102b361047b3660046124c0565b6111da565b61026861048e366004612294565b611343565b6102b36104a136600461232f565b6113b5565b6102346104b4366004612528565b6001600160a01b0391821660009081526003602090815260408083209390941682526001909201909152205460ff1690565b6102b36104f4366004612552565b6113df565b61050c610507366004612294565b6117fa565b60408051825161ffff16815260209283015115159281019290925201610240565b6102b361053b36600461232f565b6118c3565b60006301ffc9a760e01b6001600160e01b03198316148061057157506380ac58cd60e01b6001600160e01b03198316145b8061058c5750635b5e139f60e01b6001600160e01b03198316145b92915050565b6000805461059f90612599565b80601f01602080910402602001604051908101604052809291908181526020018280546105cb90612599565b80156106185780601f106105ed57610100808354040283529160200191610618565b820191906000526020600020905b8154815290600101906020018083116105fb57829003601f168201915b505050505081565b600254600090829081108015610667575060006001600160a01b03166002828154811061064f5761064f6125cd565b6000918252602090912001546001600160a01b031614155b61068c5760405162461bcd60e51b8152600401610683906125e3565b60405180910390fd5b6000838152600460205260409020546001600160a01b031691505b50919050565b6002548190811080156106f1575060006001600160a01b0316600282815481106106d9576106d96125cd565b6000918252602090912001546001600160a01b031614155b61070d5760405162461bcd60e51b8152600401610683906125e3565b600060028381548110610722576107226125cd565b6000918252602090912001546001600160a01b031690503381148061076d57506001600160a01b038116600090815260036020908152604080832033845260010190915290205460ff165b6107c85760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2053656e64657220646f6573206e6f74206f776e2074686973604482015265103a37b5b2b760d11b6064820152608401610683565b600083815260046020526040902080546001600160a01b0319166001600160a01b03861690811790915560028054859291908390811061080a5761080a6125cd565b60009182526020822001546040516001600160a01b03909116917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b6005546002546000916001916108639190612642565b61086d9190612642565b905090565b61087a61193c565b600a5460095461088a9190612655565b4211156108f75760405162461bcd60e51b815260206004820152603560248201527f44726f7020656e6465642c20696e6372656173696e6720737570706c79206c696044820152741b5a5d081b9bc81b1bdb99d95c88185b1b1bddd959605a1b6064820152608401610683565b600b54811161096e5760405162461bcd60e51b815260206004820152603b60248201527f4e657720737570706c79206c696d6974206d757374206265206772656174657260448201527f207468616e2070726576696f757320737570706c79206c696d697400000000006064820152608401610683565b600b55565b6002548190811080156109b7575060006001600160a01b03166002828154811061099f5761099f6125cd565b6000918252602090912001546001600160a01b031614155b6109d35760405162461bcd60e51b8152600401610683906125e3565b6000600283815481106109e8576109e86125cd565b6000918252602090912001546001600160a01b0316905033811480610a2357506000838152600460205260409020546001600160a01b031633145b80610a5457506001600160a01b038116600090815260036020908152604080832033845260010190915290205460ff165b610a705760405162461bcd60e51b815260040161068390612668565b806001600160a01b0316856001600160a01b031614610aa15760405162461bcd60e51b8152600401610683906126c5565b610aab8484611996565b5050505050565b60006001600160a01b038316610ada5760405162461bcd60e51b81526004016106839061271b565b6001600160a01b0383166000908152600360205260409020548210610b415760405162461bcd60e51b815260206004820152601f60248201527f455243373231456e756d657261626c653a20496e76616c696420696e646578006044820152606401610683565b6001600160a01b0383166000908152600360205260409020805483908110610b6b57610b6b6125cd565b90600052602060002090600a91828204019190066003029054906101000a900462ffffff16905092915050565b610bb3838383604051806020016040528060008152506111da565b505050565b60028181548110610bcb57610bcb6125cd565b6000918252602090912001546001600160a01b03163314610c2e5760405162461bcd60e51b815260206004820152601d60248201527f53656e646572206d757374206f776e20746f6b656e20746f206275726e0000006044820152606401610683565b6000610c39826117fa565b8051909150610c4783611c1a565b6040805184815261ffff831660208201527fa02a1adcdf79c09fc7fa0260c243670fdcf57eb0ce227002b0e5a68ebf0fd8bc910160405180910390a1505050565b610c9061193c565b42811015610cef5760405162461bcd60e51b815260206004820152602660248201527f44726f702073746172742074696d65206d757374206265206c61746572207468604482015265616e206e6f7760d01b6064820152608401610683565b600955565b610cfc61193c565b60008111610d5c5760405162461bcd60e51b815260206004820152602760248201527f44726f70206475726174696f6e206d7573742062652067726561746572207468604482015266616e207a65726f60c81b6064820152608401610683565b600a55565b610d6961193c565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b03163314610de55760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206d696e746572416464726573732063616e206d696e7400000000006044820152606401610683565b6000600c5411610e375760405162461bcd60e51b815260206004820152601960248201527f4e6f206d6f726520746f6b656e7320696e2072657365727665000000000000006044820152606401610683565b6000828152600d602052604090205460ff1615610e8b5760405162461bcd60e51b8152602060048201526012602482015271139bdb98d948185b1c9958591e481d5cd95960721b6044820152606401610683565b600254604051600091610ec7914291859160200192835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b60408051601f19818403018152919052805160209091012090506000610eef82825b1a611cb7565b9050600d600183901a10600081610f07576000610f0a565b60015b610f209060ff1662ffff00600886901b16612762565b6000878152600d60205260409020805460ff1916600117905562ffffff169050610f4a8582611dc6565b600c60008154610f5990612785565b90915550505050505050565b600254600090829081108015610fac575060006001600160a01b031660028281548110610f9457610f946125cd565b6000918252602090912001546001600160a01b031614155b610fc85760405162461bcd60e51b8152600401610683906125e3565b60028381548110610fdb57610fdb6125cd565b6000918252602090912001546001600160a01b03169392505050565b60006001600160a01b0382166110475760405162461bcd60e51b8152602060048201526015602482015274496e76616c69642062616c616e636520717565727960581b6044820152606401610683565b506001600160a01b031660009081526003602052604090205490565b61106b61193c565b6110756000611de4565b565b60606001600160a01b03821661109f5760405162461bcd60e51b81526004016106839061271b565b6001600160a01b0382166000908152600360209081526040918290208054835181840281018401909452808452909183018282801561112757602002820191906000526020600020906000905b82829054906101000a900462ffffff1662ffffff16815260200190600301906020826002010492830192600103820291508084116110ec5790505b50505050509050919050565b6001805461059f90612599565b3360008181526003602090815260408083206001600160a01b0387168085526001909101835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6111b861193c565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b60025482908110801561121e575060006001600160a01b031660028281548110611206576112066125cd565b6000918252602090912001546001600160a01b031614155b61123a5760405162461bcd60e51b8152600401610683906125e3565b60006002848154811061124f5761124f6125cd565b6000918252602090912001546001600160a01b031690503381148061128a57506000848152600460205260409020546001600160a01b031633145b806112bb57506001600160a01b038116600090815260036020908152604080832033845260010190915290205460ff165b6112d75760405162461bcd60e51b815260040161068390612668565b806001600160a01b0316866001600160a01b0316146113085760405162461bcd60e51b8152600401610683906126c5565b6113128585611996565b61131f6000868686611e36565b61133b5760405162461bcd60e51b81526004016106839061279c565b505050505050565b60075460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd90602401600060405180830381865afa15801561138d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261058c91908101906127ee565b6113bd61193c565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6009544210156114245760405162461bcd60e51b815260206004820152601060248201526f111c9bdc081b9bdd081cdd185c9d195960821b6044820152606401610683565b600a546009546114349190612655565b4211156114705760405162461bcd60e51b815260206004820152600a602482015269111c9bdc08195b99195960b21b6044820152606401610683565b3233146114ca5760405162461bcd60e51b815260206004820152602260248201527f5472616e73616374696f6e206f726967696e206e6f742066726f6d2073656e6460448201526132b960f11b6064820152608401610683565b600c54600b546114da9190612642565b6002546114e990600190612642565b106115365760405162461bcd60e51b815260206004820152601960248201527f436f6c6c656374696f6e20686173206d696e746564206f7574000000000000006044820152606401610683565b6000828152600d602052604090205460ff161561158a5760405162461bcd60e51b8152602060048201526012602482015271139bdb98d948185b1c9958591e481d5cd95960721b6044820152606401610683565b6040805133606090811b6bffffffffffffffffffffffff19908116602080850191909152603484018790523090921b166054830152825160488184030181526068830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000608884015260a4808401919091528351808403909101815260c490920190925280519101206008546001600160a01b03166116318284611f37565b6001600160a01b0316146116875760405162461bcd60e51b815260206004820152601760248201527f5369676e65722061646472657373206d69736d617463680000000000000000006044820152606401610683565b600e54600280546000926001600160a01b031691639b84229891339188916116b190600190612642565b815481106116c1576116c16125cd565b60009182526020909120015460405160e085901b6001600160e01b0319168152611702939291600160b01b90046001600160501b0316908990600401612865565b602060405180830381865afa15801561171f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611743919061289c565b905060006117518282610ee9565b90506000600d8360011a1080156117845750610100600b54600d61177591906128b5565b61177f91906128e2565b600f54105b905080156117a057600f6000815461179b906128f6565b909155505b6000816117ae5760006117b1565b60015b6117c79060ff1662ffff00600886901b16612762565b6000888152600d60205260409020805460ff1916600117905562ffffff1690506117f13382611dc6565b50505050505050565b6040805180820190915260008082526020820152600254829081108015611852575060006001600160a01b03166002828154811061183a5761183a6125cd565b6000918252602090912001546001600160a01b031614155b61186e5760405162461bcd60e51b8152600401610683906125e3565b600060028481548110611883576118836125cd565b600091825260209091200154600160b01b90046001600160501b031690506118ac60028261290f565b600114602084015260081c61ffff16825250919050565b6118cb61193c565b6001600160a01b0381166119305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610683565b61193981611de4565b50565b6006546001600160a01b031633146110755760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610683565b6000600282815481106119ab576119ab6125cd565b6000918252602080832090910180546001600160a01b031680845260039092526040909220805492935090916119e2600182612642565b8454600160a01b900461ffff161015611aeb57600082611a03600184612642565b81548110611a1357611a136125cd565b90600052602060002090600a91828204019190066003029054906101000a900462ffffff16905080836000018660000160149054906101000a900461ffff1661ffff1681548110611a6657611a666125cd565b90600052602060002090600a91828204019190066003026101000a81548162ffffff021916908362ffffff1602179055508460000160149054906101000a900461ffff1660028262ffffff1681548110611ac257611ac26125cd565b9060005260206000200160000160146101000a81548161ffff021916908361ffff160217905550505b8154829080611afc57611afc612923565b60019003818190600052602060002090600a91828204019190066003026101000a81549062ffffff0219169055905560006001600160a01b0316866001600160a01b031614611bb2576001600160a01b038616600090815260036020818152604083208054885461ffff60a01b1916600160a01b61ffff9092169190910217885580546001810182559084529220600a8084049091018054919093069091026101000a62ffffff81810219909216918816021790555b83546001600160a01b038088166001600160a01b03199283168117875560008881526004602052604080822080549095169094559251889391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050505050565b600254819081108015611c5e575060006001600160a01b031660028281548110611c4657611c466125cd565b6000918252602090912001546001600160a01b031614155b611c7a5760405162461bcd60e51b8152600401610683906125e3565b600082815260046020526040812080546001600160a01b0319169055611ca09083611996565b600560008154611caf906128f6565b909155505050565b60008060005b600a811015611d3557690d1999998d0d0682828160b11b8160208110611ce557611ce56125cd565b1a60ff85161015611cf857809150611d35565b690d1999998d0d0682828160b11b8160208110611d1757611d176125cd565b611d2391901a85612939565b9350611d2e816128f6565b9050611cbd565b5060006008720c803e807d027103a984e2075309c40c350fff60631b611d5c8460026128b5565b60208110611d6c57611d6c6125cd565b1a61ffff16901b9050720c803e807d027103a984e2075309c40c350fff60631b611d978360026128b5565b611da2906001612655565b60208110611db257611db26125cd565b611dbe91901a82612952565b949350505050565b611de0828260405180602001604052806000815250611fff565b5050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b15611f2c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611e7a90339089908890889060040161296d565b6020604051808303816000875af1925050508015611eb5575060408051601f3d908101601f19168201909252611eb2918101906129a0565b60015b611f12573d808015611ee3576040519150601f19603f3d011682016040523d82523d6000602084013e611ee8565b606091505b508051600003611f0a5760405162461bcd60e51b81526004016106839061279c565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611dbe565b506001949350505050565b60008151604114611f8a5760405162461bcd60e51b815260206004820152601e60248201527f4c656e677468206f66207369676e6174757265206d75737420626520363500006044820152606401610683565b602082810151604080850151606080870151835160008082529681018086528a9052951a928501839052840183905260808401819052909260019060a0016020604051602081039080840390855afa158015611fea573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006002805490509050600060036000866001600160a01b03166001600160a01b0316815260200190815260200160002060000180549050905060026040518060600160405280876001600160a01b031681526020018361ffff168152602001866001600160501b03168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a8154816001600160501b0302191690836001600160501b03160217905550505060036000866001600160a01b03166001600160a01b031681526020019081526020016000206000018290806001815401808255809150506001900390600052602060002090600a91828204019190066003029091909190916101000a81548162ffffff021916908362ffffff1602179055508162ffffff16856001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46121db6000868462ffffff1686611e36565b610aab5760405162461bcd60e51b81526004016106839061279c565b6001600160e01b03198116811461193957600080fd5b60006020828403121561221f57600080fd5b813561222a816121f7565b9392505050565b60005b8381101561224c578181015183820152602001612234565b50506000910152565b6000815180845261226d816020860160208601612231565b601f01601f19169290920160200192915050565b60208152600061222a6020830184612255565b6000602082840312156122a657600080fd5b5035919050565b80356001600160a01b03811681146122c457600080fd5b919050565b600080604083850312156122dc57600080fd5b6122e5836122ad565b946020939093013593505050565b60008060006060848603121561230857600080fd5b612311846122ad565b925061231f602085016122ad565b9150604084013590509250925092565b60006020828403121561234157600080fd5b61222a826122ad565b6000806040838503121561235d57600080fd5b8235915061236d602084016122ad565b90509250929050565b6020808252825182820181905260009190848201906040850190845b818110156123b357835162ffffff1683529284019291840191600101612392565b50909695505050505050565b600080604083850312156123d257600080fd5b6123db836122ad565b9150602083013580151581146123f057600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561243a5761243a6123fb565b604052919050565b600067ffffffffffffffff82111561245c5761245c6123fb565b50601f01601f191660200190565b600082601f83011261247b57600080fd5b813561248e61248982612442565b612411565b8181528460208386010111156124a357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080608085870312156124d657600080fd5b6124df856122ad565b93506124ed602086016122ad565b925060408501359150606085013567ffffffffffffffff81111561251057600080fd5b61251c8782880161246a565b91505092959194509250565b6000806040838503121561253b57600080fd5b612544836122ad565b915061236d602084016122ad565b6000806040838503121561256557600080fd5b82359150602083013567ffffffffffffffff81111561258357600080fd5b61258f8582860161246a565b9150509250929050565b600181811c908216806125ad57607f821691505b6020821081036106a757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60208082526029908201527f4552433732313a20546f6b656e2077697468207468697320494420646f6573206040820152681b9bdd08195e1a5cdd60ba1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561058c5761058c61262c565b8082018082111561058c5761058c61262c565b6020808252603c908201527f4552433732313a2053656e646572206e6f74206f776e6572206f72206170707260408201527f6f766564206f70657261746f7220666f72207468697320746f6b656e00000000606082015260800190565b60208082526036908201527f4552433732313a205f66726f6d20706172616d65746572206973206e6f74207460408201527534329037bbb732b91037b3103a3434b9903a37b5b2b760511b606082015260800190565b60208082526027908201527f455243373231456e756d657261626c653a20496e76616c6964206f776e6572206040820152666164647265737360c81b606082015260800190565b62ffffff81811683821601908082111561277e5761277e61262c565b5092915050565b6000816127945761279461262c565b506000190190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60006020828403121561280057600080fd5b815167ffffffffffffffff81111561281757600080fd5b8201601f8101841361282857600080fd5b805161283661248982612442565b81815285602083850101111561284b57600080fd5b61285c826020830160208601612231565b95945050505050565b60018060a01b03851681528360208201528260408201526080606082015260006128926080830184612255565b9695505050505050565b6000602082840312156128ae57600080fd5b5051919050565b808202811582820484141761058c5761058c61262c565b634e487b7160e01b600052601260045260246000fd5b6000826128f1576128f16128cc565b500490565b6000600182016129085761290861262c565b5060010190565b60008261291e5761291e6128cc565b500690565b634e487b7160e01b600052603160045260246000fd5b60ff828116828216039081111561058c5761058c61262c565b61ffff81811683821601908082111561277e5761277e61262c565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061289290830184612255565b6000602082840312156129b257600080fd5b815161222a816121f756fea264697066735822122047082ee072ea47773af03c17deb69717821bda263ea33adb35f23d7990a7ff9364736f6c63430008130033

Deployed Bytecode Sourcemap

27442:13300:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11693:275;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;11693:275:0;;;;;;;;28447:40;;;;;;;;;738:25:1;;;726:2;711:18;28447:40:0;592:177:1;2709:18:0;;;:::i;:::-;;;;;;;:::i;16324:177::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1879:32:1;;;1861:51;;1849:2;1834:18;16324:177:0;1715:203:1;9879:490:0;;;;;;:::i;:::-;;:::i;:::-;;12589:115;;;:::i;28496:33::-;;;;;;32286:434;;;;;;:::i;:::-;;:::i;6682:624::-;;;;;;:::i;:::-;;:::i;28536:34::-;;;;;;14601:448;;;;;;:::i;:::-;;:::i;:::-;;;2867:8:1;2855:21;;;2837:40;;2825:2;2810:18;14601:448:0;2693:190:1;28255:73:0;;;;;-1:-1:-1;;;;;28255:73:0;;;28147:99;;;;;-1:-1:-1;;;;;28147:99:0;;;7318:153;;;;;;:::i;:::-;;:::i;36832:380::-;;;;;;:::i;:::-;;:::i;28373:41::-;;;;;;31084:250;;;;;;:::i;:::-;;:::i;31679:195::-;;;;;;:::i;:::-;;:::i;30589:146::-;;;;;;:::i;:::-;;:::i;35539:898::-;;;;;;:::i;:::-;;:::i;13139:179::-;;;;;;:::i;:::-;;:::i;28760:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;13815:193;;;;;;:::i;:::-;;:::i;25959:103::-;;;:::i;15579:288::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;25311:87::-;25384:6;;-1:-1:-1;;;;;25384:6:0;25311:87;;2755:20;;;:::i;10934:217::-;;;;;;:::i;:::-;;:::i;29604:110::-;;;;;;:::i;:::-;;:::i;8487:860::-;;;;;;:::i;:::-;;:::i;38114:180::-;;;;;;:::i;:::-;;:::i;30092:144::-;;;;;;:::i;:::-;;:::i;16958:195::-;;;;;;:::i;:::-;-1:-1:-1;;;;;17098:18:0;;;17069:4;17098:18;;;:10;:18;;;;;;;;:47;;;;;;:36;;;;:47;;;;;;;;16958:195;33344:1613;;;;;;:::i;:::-;;:::i;37490:394::-;;;;;;:::i;:::-;;:::i;:::-;;;;7074:13:1;;7089:6;7070:26;7052:45;;7167:4;7155:17;;;7149:24;7142:32;7135:40;7113:20;;;7106:70;;;;7025:18;37490:394:0;6840:342:1;26217:201:0;;;;;;:::i;:::-;;:::i;11693:275::-;11763:4;-1:-1:-1;;;;;;;;;11802:25:0;;;;:77;;-1:-1:-1;;;;;;;;;;11854:25:0;;;11802:77;:129;;;-1:-1:-1;;;;;;;;;;11906:25:0;;;11802:129;11780:180;11693:275;-1:-1:-1;;11693:275:0:o;2709:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16324:177::-;5087:10;:17;16436:7;;16408:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;;;;;;;;;16468:25:::1;::::0;;;:15:::1;:25;::::0;;;;;-1:-1:-1;;;;;16468:25:0::1;::::0;-1:-1:-1;5247:1:0::1;16324:177:::0;;;;:::o;9879:490::-;5087:10;:17;9965:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;9991:18:::1;10012:10;10023:8;10012:20;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:31:::0;-1:-1:-1;;;;;10012:31:0::1;::::0;-1:-1:-1;10076:10:0::1;:24:::0;::::1;::::0;:93:::1;;-1:-1:-1::0;;;;;;10117:22:0;::::1;;::::0;;;:10:::1;:22;::::0;;;;;;;10158:10:::1;10117:52:::0;;:40:::1;;:52:::0;;;;;;::::1;;10076:93;10054:181;;;::::0;-1:-1:-1;;;10054:181:0;;8316:2:1;10054:181:0::1;::::0;::::1;8298:21:1::0;8355:2;8335:18;;;8328:30;8394:34;8374:18;;;8367:62;-1:-1:-1;;;8445:18:1;;;8438:36;8491:19;;10054:181:0::1;8114:402:1::0;10054:181:0::1;10246:25;::::0;;;:15:::1;:25;::::0;;;;:37;;-1:-1:-1;;;;;;10246:37:0::1;-1:-1:-1::0;;;;;10246:37:0;::::1;::::0;;::::1;::::0;;;10308:10:::1;:20:::0;;10246:25;;:37;10308:10;10246:25;;10308:20;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;:31:::0;10299:62:::1;::::0;-1:-1:-1;;;;;10308:31:0;;::::1;::::0;10299:62:::1;::::0;::::1;9980:389;9879:490:::0;;;:::o;12589:115::-;12679:13;;12659:10;:17;12635:4;;12695:1;;12659:33;;12679:13;12659:33;:::i;:::-;:37;;;;:::i;:::-;12652:44;;12589:115;:::o;32286:434::-;25197:13;:11;:13::i;:::-;32428:12:::1;;32412:13;;:28;;;;:::i;:::-;32393:15;:47;;32370:151;;;::::0;-1:-1:-1;;;32370:151:0;;9118:2:1;32370:151:0::1;::::0;::::1;9100:21:1::0;9157:2;9137:18;;;9130:30;9196:34;9176:18;;;9169:62;-1:-1:-1;;;9247:18:1;;;9240:51;9308:19;;32370:151:0::1;8916:417:1::0;32370:151:0::1;32573:11;;32555:15;:29;32532:140;;;::::0;-1:-1:-1;;;32532:140:0;;9540:2:1;32532:140:0::1;::::0;::::1;9522:21:1::0;9579:2;9559:18;;;9552:30;9618:34;9598:18;;;9591:62;9689:29;9669:18;;;9662:57;9736:19;;32532:140:0::1;9338:423:1::0;32532:140:0::1;32683:11;:29:::0;32286:434::o;6682:624::-;5087:10;:17;6779:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;6805:18:::1;6826:10;6837:8;6826:20;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:31:::0;-1:-1:-1;;;;;6826:31:0::1;::::0;-1:-1:-1;6890:10:0::1;:24:::0;::::1;::::0;:80:::1;;-1:-1:-1::0;6945:25:0::1;::::0;;;:15:::1;:25;::::0;;;;;-1:-1:-1;;;;;6945:25:0::1;6931:10;:39;6890:80;:149;;;-1:-1:-1::0;;;;;;6987:22:0;::::1;;::::0;;;:10:::1;:22;::::0;;;;;;;7028:10:::1;6987:52:::0;;:40:::1;;:52:::0;;;;;;::::1;;6890:149;6868:259;;;;-1:-1:-1::0;;;6868:259:0::1;;;;;;;:::i;:::-;7169:10;-1:-1:-1::0;;;;;7160:19:0::1;:5;-1:-1:-1::0;;;;;7160:19:0::1;;7138:123;;;;-1:-1:-1::0;;;7138:123:0::1;;;;;;;:::i;:::-;7274:24;7284:3;7289:8;7274:9;:24::i;:::-;6794:512;6682:624:::0;;;;:::o;14601:448::-;14712:6;-1:-1:-1;;;;;14759:20:0;;14736:110;;;;-1:-1:-1;;;14736:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;14889:18:0;;;;;;:10;:18;;;;;:37;14880:46;;14857:128;;;;-1:-1:-1;;;14857:128:0;;11228:2:1;14857:128:0;;;11210:21:1;11267:2;11247:18;;;11240:30;11306:33;11286:18;;;11279:61;11357:18;;14857:128:0;11026:355:1;14857:128:0;-1:-1:-1;;;;;15003:18:0;;;;;;:10;:18;;;;;:38;;15034:6;;15003:38;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;14996:45;;14601:448;;;;:::o;7318:153::-;7421:42;7438:5;7445:3;7450:8;7421:42;;;;;;;;;;;;:16;:42::i;:::-;7318:153;;;:::o;36832:380::-;36918:10;36929:8;36918:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;36918:31:0;36904:10;:45;36881:125;;;;-1:-1:-1;;;36881:125:0;;11588:2:1;36881:125:0;;;11570:21:1;11627:2;11607:18;;;11600:30;11666:31;11646:18;;;11639:59;11715:18;;36881:125:0;11386:353:1;36881:125:0;37019:33;37055:25;37071:8;37055:15;:25::i;:::-;37115:13;;37019:61;;-1:-1:-1;37141:15:0;37147:8;37141:5;:15::i;:::-;37174:30;;;11916:25:1;;;11989:6;11977:19;;11972:2;11957:18;;11950:47;37174:30:0;;11889:18:1;37174:30:0;;;;;;;36870:342;;36832:380;:::o;31084:250::-;25197:13;:11;:13::i;:::-;31204:15:::1;31186:14;:33;;31164:121;;;::::0;-1:-1:-1;;;31164:121:0;;12210:2:1;31164:121:0::1;::::0;::::1;12192:21:1::0;12249:2;12229:18;;;12222:30;12288:34;12268:18;;;12261:62;-1:-1:-1;;;12339:18:1;;;12332:36;12385:19;;31164:121:0::1;12008:402:1::0;31164:121:0::1;31296:13;:30:::0;31084:250::o;31679:195::-;25197:13;:11;:13::i;:::-;31782:1:::1;31766:13;:17;31757:70;;;::::0;-1:-1:-1;;;31757:70:0;;12617:2:1;31757:70:0::1;::::0;::::1;12599:21:1::0;12656:2;12636:18;;;12629:30;12695:34;12675:18;;;12668:62;-1:-1:-1;;;12746:18:1;;;12739:37;12793:19;;31757:70:0::1;12415:403:1::0;31757:70:0::1;31838:12;:28:::0;31679:195::o;30589:146::-;25197:13;:11;:13::i;:::-;30676:19:::1;:51:::0;;-1:-1:-1;;;;;;30676:51:0::1;-1:-1:-1::0;;;;;30676:51:0;;;::::1;::::0;;;::::1;::::0;;30589:146::o;35539:898::-;35628:13;;-1:-1:-1;;;;;35628:13:0;35614:10;:27;35606:67;;;;-1:-1:-1;;;35606:67:0;;13025:2:1;35606:67:0;;;13007:21:1;13064:2;13044:18;;;13037:30;13103:29;13083:18;;;13076:57;13150:18;;35606:67:0;12823:351:1;35606:67:0;35708:1;35692:13;;:17;35684:55;;;;-1:-1:-1;;;35684:55:0;;13381:2:1;35684:55:0;;;13363:21:1;13420:2;13400:18;;;13393:30;13459:27;13439:18;;;13432:55;13504:18;;35684:55:0;13179:349:1;35684:55:0;35759:18;;;;:10;:18;;;;;;;;35758:19;35750:50;;;;-1:-1:-1;;;35750:50:0;;13735:2:1;35750:50:0;;;13717:21:1;13774:2;13754:18;;;13747:30;-1:-1:-1;;;13793:18:1;;;13786:48;13851:18;;35750:50:0;13533:342:1;35750:50:0;35982:10;:17;35891:123;;35846:18;;35891:123;;35926:15;;35960:3;;35891:123;;14065:19:1;;;14122:2;14118:15;;;;-1:-1:-1;;14114:53:1;14109:2;14100:12;;14093:75;14193:2;14184:12;;14177:28;14230:2;14221:12;;13880:359;35891:123:0;;;;-1:-1:-1;;35891:123:0;;;;;;;;;35867:158;;35891:123;35867:158;;;;;-1:-1:-1;36066:14:0;36083:39;35867:158;36066:14;36107:13;;36083:17;:39::i;:::-;36066:56;-1:-1:-1;28136:2:0;36174:1;36163:13;;;36157:44;36133:21;36157:44;36264:24;;36287:1;36264:24;;;36283:1;36264:24;36238:51;;;;36239:20;36258:1;36239:20;;;;36238:51;:::i;:::-;36333:18;;;;:10;:18;;;;;:25;;-1:-1:-1;;36333:25:0;36354:4;36333:25;;;36212:77;;;-1:-1:-1;36369:32:0;36379:3;36212:77;36369:9;:32::i;:::-;36416:13;;36414:15;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;35539:898:0:o;13139:179::-;5087:10;:17;13247:7;;13219:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;13279:10:::1;13290:8;13279:20;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:31:::0;-1:-1:-1;;;;;13279:31:0::1;::::0;13139:179;-1:-1:-1;;;13139:179:0:o;13815:193::-;13873:4;-1:-1:-1;;;;;13899:20:0;;13890:55;;;;-1:-1:-1;;;13890:55:0;;14762:2:1;13890:55:0;;;14744:21:1;14801:2;14781:18;;;14774:30;-1:-1:-1;;;14820:18:1;;;14813:51;14881:18;;13890:55:0;14560:345:1;13890:55:0;-1:-1:-1;;;;;;13963:18:0;;;;;:10;:18;;;;;:37;;13815:193::o;25959:103::-;25197:13;:11;:13::i;:::-;26024:30:::1;26051:1;26024:18;:30::i;:::-;25959:103::o:0;15579:288::-;15668:15;-1:-1:-1;;;;;15724:20:0;;15701:110;;;;-1:-1:-1;;;15701:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;15829:18:0;;;;;;:10;:18;;;;;;;;;15822:37;;;;;;;;;;;;;;;;;15829:18;;15822:37;;15829:18;15822:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15579:288;;;:::o;2755:20::-;;;;;;;:::i;10934:217::-;11027:10;11016:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;11016:51:0;;;;;:40;;;;:51;;;;;;:63;;-1:-1:-1;;11016:63:0;;;;;;;;;;11095:48;;540:41:1;;;11016:51:0;;11027:10;11095:48;;513:18:1;11095:48:0;;;;;;;10934:217;;:::o;29604:110::-;25197:13;:11;:13::i;:::-;29680::::1;:26:::0;;-1:-1:-1;;;;;;29680:26:0::1;-1:-1:-1::0;;;;;29680:26:0;;;::::1;::::0;;;::::1;::::0;;29604:110::o;8487:860::-;5087:10;:17;8651:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;8677:18:::1;8698:10;8709:8;8698:20;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:31:::0;-1:-1:-1;;;;;8698:31:0::1;::::0;-1:-1:-1;8762:10:0::1;:24:::0;::::1;::::0;:80:::1;;-1:-1:-1::0;8817:25:0::1;::::0;;;:15:::1;:25;::::0;;;;;-1:-1:-1;;;;;8817:25:0::1;8803:10;:39;8762:80;:149;;;-1:-1:-1::0;;;;;;8859:22:0;::::1;;::::0;;;:10:::1;:22;::::0;;;;;;;8900:10:::1;8859:52:::0;;:40:::1;;:52:::0;;;;;;::::1;;8762:149;8740:259;;;;-1:-1:-1::0;;;8740:259:0::1;;;;;;;:::i;:::-;9041:10;-1:-1:-1::0;;;;;9032:19:0::1;:5;-1:-1:-1::0;;;;;9032:19:0::1;;9010:123;;;;-1:-1:-1::0;;;9010:123:0::1;;;;;;;:::i;:::-;9146:24;9156:3;9161:8;9146:9;:24::i;:::-;9205:56;9236:1;9240:3;9245:8;9255:5;9205:22;:56::i;:::-;9183:156;;;;-1:-1:-1::0;;;9183:156:0::1;;;;;;;:::i;:::-;8666:681;8487:860:::0;;;;;:::o;38114:180::-;38251:16;;:35;;-1:-1:-1;;;38251:35:0;;;;;738:25:1;;;38213:13:0;;-1:-1:-1;;;;;38251:16:0;;:25;;711:18:1;;38251:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;38251:35:0;;;;;;;;;;;;:::i;30092:144::-;25197:13;:11;:13::i;:::-;30177:16:::1;:51:::0;;-1:-1:-1;;;;;;30177:51:0::1;-1:-1:-1::0;;;;;30177:51:0;;;::::1;::::0;;;::::1;::::0;;30092:144::o;33344:1613::-;33444:13;;33425:15;:32;;33417:61;;;;-1:-1:-1;;;33417:61:0;;16184:2:1;33417:61:0;;;16166:21:1;16223:2;16203:18;;;16196:30;-1:-1:-1;;;16242:18:1;;;16235:46;16298:18;;33417:61:0;15982:340:1;33417:61:0;33532:12;;33516:13;;:28;;;;:::i;:::-;33497:15;:47;;33489:70;;;;-1:-1:-1;;;33489:70:0;;16529:2:1;33489:70:0;;;16511:21:1;16568:2;16548:18;;;16541:30;-1:-1:-1;;;16587:18:1;;;16580:40;16637:18;;33489:70:0;16327:334:1;33489:70:0;33578:9;33591:10;33578:23;33570:70;;;;-1:-1:-1;;;33570:70:0;;16868:2:1;33570:70:0;;;16850:21:1;16907:2;16887:18;;;16880:30;16946:34;16926:18;;;16919:62;-1:-1:-1;;;16997:18:1;;;16990:32;17039:19;;33570:70:0;16666:398:1;33570:70:0;33711:13;;33697:11;;:27;;;;:::i;:::-;33673:10;:17;:21;;33693:1;;33673:21;:::i;:::-;:51;33651:126;;;;-1:-1:-1;;;33651:126:0;;17271:2:1;33651:126:0;;;17253:21:1;17310:2;17290:18;;;17283:30;17349:27;17329:18;;;17322:55;17394:18;;33651:126:0;17069:349:1;33651:126:0;33797:18;;;;:10;:18;;;;;;;;33796:19;33788:50;;;;-1:-1:-1;;;33788:50:0;;13735:2:1;33788:50:0;;;13717:21:1;13774:2;13754:18;;;13747:30;-1:-1:-1;;;13793:18:1;;;13786:48;13851:18;;33788:50:0;13533:342:1;33788:50:0;40593:44;;;33915:10;21347:2:1;21343:15;;;-1:-1:-1;;21339:24:1;;;40593:44:0;;;;21327:37:1;;;;21380:12;;;21373:28;;;33943:4:0;21435:15:1;;;21431:24;21417:12;;;21410:46;40593:44:0;;;;;;;;;21472:12:1;;;40593:44:0;;40583:55;;;;;;21737:66:1;40669:61:0;;;21725:79:1;21820:12;;;;21813:28;;;;40669:61:0;;;;;;;;;;21857:12:1;;;;40669:61:0;;;40659:72;;;;;34015:13;;-1:-1:-1;;;;;34015:13:0;33982:29;40659:72;34006:4;33982:14;:29::i;:::-;-1:-1:-1;;;;;33982:46:0;;33960:119;;;;-1:-1:-1;;;33960:119:0;;17625:2:1;33960:119:0;;;17607:21:1;17664:2;17644:18;;;17637:30;17703:25;17683:18;;;17676:53;17746:18;;33960:119:0;17423:347:1;33960:119:0;34146:19;;34248:10;34259:17;;34125:18;;-1:-1:-1;;;;;34146:19:0;;:33;;34194:10;;34219:6;;34259:21;;34146:19;;34259:21;:::i;:::-;34248:33;;;;;;;;:::i;:::-;;;;;;;;;;:43;34146:176;;;;;;-1:-1:-1;;;;;;34146:176:0;;;;;;;-1:-1:-1;;;34248:43:0;;-1:-1:-1;;;;;34248:43:0;;34307:4;;34146:176;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34125:197;-1:-1:-1;34363:14:0;34380:39;34125:197;34363:14;34404:13;;34380:39;34363:56;-1:-1:-1;34511:21:0;28136:2;34556:10;34567:1;34556:13;34550:44;:102;;;;;34649:3;34630:11;;34644:2;34630:16;;;;:::i;:::-;:22;;;;:::i;:::-;34611:16;;:41;34550:102;34511:152;;34678:16;34674:67;;;34713:16;;34711:18;;;;;:::i;:::-;;;;-1:-1:-1;34674:67:0;34753:23;34805:16;:24;;34828:1;34805:24;;;34824:1;34805:24;34779:51;;;;34780:20;34799:1;34780:20;;;;34779:51;:::i;:::-;34874:18;;;;:10;:18;;;;;:25;;-1:-1:-1;;34874:25:0;34895:4;34874:25;;;34753:77;;;-1:-1:-1;34910:39:0;34920:10;34753:77;34910:9;:39::i;:::-;33406:1551;;;;;33344:1613;;:::o;37490:394::-;-1:-1:-1;;;;;;;;;;;;;;;;;5087:10:0;:17;37577:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;37655:14:::1;37672:10;37683:8;37672:20;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:30:::0;-1:-1:-1;;;37672:30:0;::::1;-1:-1:-1::0;;;;;37672:30:0::1;::::0;-1:-1:-1;37809:13:0::1;37821:1;37672:30:::0;37809:13:::1;:::i;:::-;37826:1;37809:18;37779:27;::::0;::::1;:48:::0;37874:1:::1;37861:14;37838:38;;::::0;;-1:-1:-1;37779:27:0;:10;-1:-1:-1;37490:394:0:o;26217:201::-;25197:13;:11;:13::i;:::-;-1:-1:-1;;;;;26306:22:0;::::1;26298:73;;;::::0;-1:-1:-1;;;26298:73:0;;19317:2:1;26298:73:0::1;::::0;::::1;19299:21:1::0;19356:2;19336:18;;;19329:30;19395:34;19375:18;;;19368:62;-1:-1:-1;;;19446:18:1;;;19439:36;19492:19;;26298:73:0::1;19115:402:1::0;26298:73:0::1;26382:28;26401:8;26382:18;:28::i;:::-;26217:201:::0;:::o;25476:132::-;25384:6;;-1:-1:-1;;;;;25384:6:0;23942:10;25540:23;25532:68;;;;-1:-1:-1;;;25532:68:0;;19724:2:1;25532:68:0;;;19706:21:1;;;19743:18;;;19736:30;19802:34;19782:18;;;19775:62;19854:18;;25532:68:0;19522:356:1;17893:1471:0;17959:27;17989:10;18000:8;17989:20;;;;;;;;:::i;:::-;;;;;;;;;;;;18035;;-1:-1:-1;;;;;18035:20:0;18143:16;;;:10;:16;;;;;;;18197:28;;17989:20;;-1:-1:-1;18035:20:0;;18263:23;18035:20;18197:28;18263:23;:::i;:::-;18240:20;;-1:-1:-1;;;18240:20:0;;;;:46;18236:446;;;18303:21;18327:9;18349:23;18371:1;18349:19;:23;:::i;:::-;18327:46;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;18303:70;;18514:14;18468:9;:21;;18490:9;:20;;;;;;;;;;;;18468:43;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;18650:9;:20;;;;;;;;;;;;18610:10;18621:14;18610:26;;;;;;;;;;:::i;:::-;;;;;;;;:37;;;:60;;;;;;;;;;;;;;;;;;18288:394;18236:446;18730:27;;:9;;:27;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18824:1;-1:-1:-1;;;;;18809:17:0;:3;-1:-1:-1;;;;;18809:17:0;;18805:305;;-1:-1:-1;;;;;18939:15:0;;;;;;:10;:15;;;;;;;:34;;18909:65;;-1:-1:-1;;;;18909:65:0;-1:-1:-1;;;18909:65:0;;;;;;;;;;;19048:50;;-1:-1:-1;19048:50:0;;;;;;;;;;;;;;;;;;;;;;;;;18909:65;19048:50;;;;;;;;;;;;;;;;18805:305;19173:26;;-1:-1:-1;;;;;19173:26:0;;;-1:-1:-1;;;;;;19173:26:0;;;;;;;:20;19239:25;;;:15;:25;;;;;;:38;;;;;;;;19327:29;;19255:8;;19173:26;;19327:29;;;;;;17948:1416;;;;17893:1471;;:::o;21490:181::-;5087:10;:17;21536:8;;5076:28;;:91;;;;;5165:1;-1:-1:-1;;;;;5122:45:0;:10;5133:8;5122:20;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;;;;;5122:31:0;:45;;5076:91;5054:182;;;;-1:-1:-1;;;5054:182:0;;;;;;;:::i;:::-;21593:1:::1;21557:25:::0;;;:15:::1;:25;::::0;;;;:38;;-1:-1:-1;;;;;;21557:38:0::1;::::0;;21606:31:::1;::::0;21573:8;21606:9:::1;:31::i;:::-;21650:13;;21648:15;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;21490:181:0:o;38532:618::-;38621:6;38689:10;38715:6;38710:234;27626:2;38727:1;:18;38710:234;;;-1:-1:-1;;;38806:1:0;38785:23;;;;;;;:::i;:::-;;38779:30;38771:38;;;38767:112;;;38838:1;38830:9;;38858:5;;38767:112;-1:-1:-1;;;38929:1:0;38908:23;;;;;;;:::i;:::-;38893:39;;38908:23;;38893:39;;:::i;:::-;;-1:-1:-1;38747:3:0;;;:::i;:::-;;;38710:234;;;-1:-1:-1;39003:14:0;39060:1;-1:-1:-1;;;39044:9:0;:5;39052:1;39044:9;:::i;:::-;39033:21;;;;;;;:::i;:::-;;39020:41;;;;;-1:-1:-1;;;;39100:9:0;:5;39108:1;39100:9;:::i;:::-;:13;;39112:1;39100:13;:::i;:::-;39089:25;;;;;;;:::i;:::-;39072:43;;39089:25;;39072:43;;:::i;:::-;;38532:618;-1:-1:-1;;;;38532:618:0:o;20890:109::-;20961:30;20971:3;20976:10;20961:30;;;;;;;;;;;;:9;:30::i;:::-;20890:109;;:::o;26578:191::-;26671:6;;;-1:-1:-1;;;;;26688:17:0;;;-1:-1:-1;;;;;;26688:17:0;;;;;;;26721:40;;26671:6;;;26688:17;26671:6;;26721:40;;26652:16;;26721:40;26641:128;26578:191;:::o;22315:863::-;22473:4;-1:-1:-1;;;;;22494:15:0;;;:19;22490:681;;22534:73;;-1:-1:-1;;;22534:73:0;;-1:-1:-1;;;;;22534:37:0;;;;;:73;;22572:10;;22584:5;;22591:8;;22601:5;;22534:73;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22534:73:0;;;;;;;;-1:-1:-1;;22534:73:0;;;;;;;;;;;;:::i;:::-;;;22530:586;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22777:6;:13;22794:1;22777:18;22773:328;;22820:60;;-1:-1:-1;;;22820:60:0;;;;;;;:::i;22773:328::-;23051:6;23045:13;23036:6;23032:2;23028:15;23021:38;22530:586;-1:-1:-1;;;;;;22658:51:0;-1:-1:-1;;;22658:51:0;;-1:-1:-1;22651:58:0;;22490:681;-1:-1:-1;23155:4:0;22315:863;;;;;;:::o;39391:757::-;39501:7;39534:4;:11;39549:2;39534:17;39526:60;;;;-1:-1:-1;;;39526:60:0;;22082:2:1;39526:60:0;;;22064:21:1;22121:2;22101:18;;;22094:30;22160:32;22140:18;;;22133:60;22210:18;;39526:60:0;21880:354:1;39526:60:0;39786:2;39776:13;;;39770:20;39857:2;39847:13;;;39841:20;39965:2;39955:13;;;39949:20;40112:28;;39627:7;40112:28;;;;;;;;;22466:25:1;;;39941:29:0;;22507:18:1;;;22500:45;;;22561:18;;22554:34;;;22604:18;;;22597:34;;;39941:29:0;;40112:28;;22438:19:1;;40112:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;40112:28:0;;-1:-1:-1;;40112:28:0;;;39391:757;-1:-1:-1;;;;;;;39391:757:0:o;20002:655::-;20107:14;20131:10;:17;;;;20107:42;;20160:17;20187:10;:15;20198:3;-1:-1:-1;;;;;20187:15:0;-1:-1:-1;;;;;20187:15:0;;;;;;;;;;;;:27;;:34;;;;20160:62;;20233:10;20249:38;;;;;;;;20259:3;-1:-1:-1;;;;;20249:38:0;;;;;20264:10;20249:38;;;;;;20276:10;-1:-1:-1;;;;;20249:38:0;;;;20233:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20233:55:0;;;;;-1:-1:-1;;;;;20233:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20233:55:0;;;;;-1:-1:-1;;;;;20233:55:0;;;;;;;;20356:10;:15;20367:3;-1:-1:-1;;;;;20356:15:0;-1:-1:-1;;;;;20356:15:0;;;;;;;;;;;;:27;;20389:7;20356:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20473:7;20447:34;;20468:3;-1:-1:-1;;;;;20447:34:0;20464:1;-1:-1:-1;;;;;20447:34:0;;;;;;;;;;;20516:55;20547:1;20551:3;20556:7;20516:55;;20565:5;20516:22;:55::i;:::-;20494:155;;;;-1:-1:-1;;;20494:155:0;;;;;;;:::i;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;774:250::-;859:1;869:113;883:6;880:1;877:13;869:113;;;959:11;;;953:18;940:11;;;933:39;905:2;898:10;869:113;;;-1:-1:-1;;1016:1:1;998:16;;991:27;774:250::o;1029:271::-;1071:3;1109:5;1103:12;1136:6;1131:3;1124:19;1152:76;1221:6;1214:4;1209:3;1205:14;1198:4;1191:5;1187:16;1152:76;:::i;:::-;1282:2;1261:15;-1:-1:-1;;1257:29:1;1248:39;;;;1289:4;1244:50;;1029:271;-1:-1:-1;;1029:271:1:o;1305:220::-;1454:2;1443:9;1436:21;1417:4;1474:45;1515:2;1504:9;1500:18;1492:6;1474:45;:::i;1530:180::-;1589:6;1642:2;1630:9;1621:7;1617:23;1613:32;1610:52;;;1658:1;1655;1648:12;1610:52;-1:-1:-1;1681:23:1;;1530:180;-1:-1:-1;1530:180:1:o;1923:173::-;1991:20;;-1:-1:-1;;;;;2040:31:1;;2030:42;;2020:70;;2086:1;2083;2076:12;2020:70;1923:173;;;:::o;2101:254::-;2169:6;2177;2230:2;2218:9;2209:7;2205:23;2201:32;2198:52;;;2246:1;2243;2236:12;2198:52;2269:29;2288:9;2269:29;:::i;:::-;2259:39;2345:2;2330:18;;;;2317:32;;-1:-1:-1;;;2101:254:1:o;2360:328::-;2437:6;2445;2453;2506:2;2494:9;2485:7;2481:23;2477:32;2474:52;;;2522:1;2519;2512:12;2474:52;2545:29;2564:9;2545:29;:::i;:::-;2535:39;;2593:38;2627:2;2616:9;2612:18;2593:38;:::i;:::-;2583:48;;2678:2;2667:9;2663:18;2650:32;2640:42;;2360:328;;;;;:::o;3118:186::-;3177:6;3230:2;3218:9;3209:7;3205:23;3201:32;3198:52;;;3246:1;3243;3236:12;3198:52;3269:29;3288:9;3269:29;:::i;3309:254::-;3377:6;3385;3438:2;3426:9;3417:7;3413:23;3409:32;3406:52;;;3454:1;3451;3444:12;3406:52;3490:9;3477:23;3467:33;;3519:38;3553:2;3542:9;3538:18;3519:38;:::i;:::-;3509:48;;3309:254;;;;;:::o;3568:645::-;3737:2;3789:21;;;3859:13;;3762:18;;;3881:22;;;3708:4;;3737:2;3960:15;;;;3934:2;3919:18;;;3708:4;4003:184;4017:6;4014:1;4011:13;4003:184;;;4082:13;;4097:8;4078:28;4066:41;;4162:15;;;;4127:12;;;;4039:1;4032:9;4003:184;;;-1:-1:-1;4204:3:1;;3568:645;-1:-1:-1;;;;;;3568:645:1:o;4218:347::-;4283:6;4291;4344:2;4332:9;4323:7;4319:23;4315:32;4312:52;;;4360:1;4357;4350:12;4312:52;4383:29;4402:9;4383:29;:::i;:::-;4373:39;;4462:2;4451:9;4447:18;4434:32;4509:5;4502:13;4495:21;4488:5;4485:32;4475:60;;4531:1;4528;4521:12;4475:60;4554:5;4544:15;;;4218:347;;;;;:::o;4570:127::-;4631:10;4626:3;4622:20;4619:1;4612:31;4662:4;4659:1;4652:15;4686:4;4683:1;4676:15;4702:275;4773:2;4767:9;4838:2;4819:13;;-1:-1:-1;;4815:27:1;4803:40;;4873:18;4858:34;;4894:22;;;4855:62;4852:88;;;4920:18;;:::i;:::-;4956:2;4949:22;4702:275;;-1:-1:-1;4702:275:1:o;4982:186::-;5030:4;5063:18;5055:6;5052:30;5049:56;;;5085:18;;:::i;:::-;-1:-1:-1;5151:2:1;5130:15;-1:-1:-1;;5126:29:1;5157:4;5122:40;;4982:186::o;5173:462::-;5215:5;5268:3;5261:4;5253:6;5249:17;5245:27;5235:55;;5286:1;5283;5276:12;5235:55;5322:6;5309:20;5353:48;5369:31;5397:2;5369:31;:::i;:::-;5353:48;:::i;:::-;5426:2;5417:7;5410:19;5472:3;5465:4;5460:2;5452:6;5448:15;5444:26;5441:35;5438:55;;;5489:1;5486;5479:12;5438:55;5554:2;5547:4;5539:6;5535:17;5528:4;5519:7;5515:18;5502:55;5602:1;5577:16;;;5595:4;5573:27;5566:38;;;;5581:7;5173:462;-1:-1:-1;;;5173:462:1:o;5640:537::-;5735:6;5743;5751;5759;5812:3;5800:9;5791:7;5787:23;5783:33;5780:53;;;5829:1;5826;5819:12;5780:53;5852:29;5871:9;5852:29;:::i;:::-;5842:39;;5900:38;5934:2;5923:9;5919:18;5900:38;:::i;:::-;5890:48;;5985:2;5974:9;5970:18;5957:32;5947:42;;6040:2;6029:9;6025:18;6012:32;6067:18;6059:6;6056:30;6053:50;;;6099:1;6096;6089:12;6053:50;6122:49;6163:7;6154:6;6143:9;6139:22;6122:49;:::i;:::-;6112:59;;;5640:537;;;;;;;:::o;6182:260::-;6250:6;6258;6311:2;6299:9;6290:7;6286:23;6282:32;6279:52;;;6327:1;6324;6317:12;6279:52;6350:29;6369:9;6350:29;:::i;:::-;6340:39;;6398:38;6432:2;6421:9;6417:18;6398:38;:::i;6447:388::-;6524:6;6532;6585:2;6573:9;6564:7;6560:23;6556:32;6553:52;;;6601:1;6598;6591:12;6553:52;6637:9;6624:23;6614:33;;6698:2;6687:9;6683:18;6670:32;6725:18;6717:6;6714:30;6711:50;;;6757:1;6754;6747:12;6711:50;6780:49;6821:7;6812:6;6801:9;6797:22;6780:49;:::i;:::-;6770:59;;;6447:388;;;;;:::o;7187:380::-;7266:1;7262:12;;;;7309;;;7330:61;;7384:4;7376:6;7372:17;7362:27;;7330:61;7437:2;7429:6;7426:14;7406:18;7403:38;7400:161;;7483:10;7478:3;7474:20;7471:1;7464:31;7518:4;7515:1;7508:15;7546:4;7543:1;7536:15;7572:127;7633:10;7628:3;7624:20;7621:1;7614:31;7664:4;7661:1;7654:15;7688:4;7685:1;7678:15;7704:405;7906:2;7888:21;;;7945:2;7925:18;;;7918:30;7984:34;7979:2;7964:18;;7957:62;-1:-1:-1;;;8050:2:1;8035:18;;8028:39;8099:3;8084:19;;7704:405::o;8521:127::-;8582:10;8577:3;8573:20;8570:1;8563:31;8613:4;8610:1;8603:15;8637:4;8634:1;8627:15;8653:128;8720:9;;;8741:11;;;8738:37;;;8755:18;;:::i;8786:125::-;8851:9;;;8872:10;;;8869:36;;;8885:18;;:::i;9766:424::-;9968:2;9950:21;;;10007:2;9987:18;;;9980:30;10046:34;10041:2;10026:18;;10019:62;10117:30;10112:2;10097:18;;10090:58;10180:3;10165:19;;9766:424::o;10195:418::-;10397:2;10379:21;;;10436:2;10416:18;;;10409:30;10475:34;10470:2;10455:18;;10448:62;-1:-1:-1;;;10541:2:1;10526:18;;10519:52;10603:3;10588:19;;10195:418::o;10618:403::-;10820:2;10802:21;;;10859:2;10839:18;;;10832:30;10898:34;10893:2;10878:18;;10871:62;-1:-1:-1;;;10964:2:1;10949:18;;10942:37;11011:3;10996:19;;10618:403::o;14244:170::-;14311:8;14339:10;;;14351;;;14335:27;;14374:11;;;14371:37;;;14388:18;;:::i;:::-;14371:37;14244:170;;;;:::o;14419:136::-;14458:3;14486:5;14476:39;;14495:18;;:::i;:::-;-1:-1:-1;;;14531:18:1;;14419:136::o;14910:414::-;15112:2;15094:21;;;15151:2;15131:18;;;15124:30;15190:34;15185:2;15170:18;;15163:62;-1:-1:-1;;;15256:2:1;15241:18;;15234:48;15314:3;15299:19;;14910:414::o;15329:648::-;15409:6;15462:2;15450:9;15441:7;15437:23;15433:32;15430:52;;;15478:1;15475;15468:12;15430:52;15511:9;15505:16;15544:18;15536:6;15533:30;15530:50;;;15576:1;15573;15566:12;15530:50;15599:22;;15652:4;15644:13;;15640:27;-1:-1:-1;15630:55:1;;15681:1;15678;15671:12;15630:55;15710:2;15704:9;15735:48;15751:31;15779:2;15751:31;:::i;15735:48::-;15806:2;15799:5;15792:17;15846:7;15841:2;15836;15832;15828:11;15824:20;15821:33;15818:53;;;15867:1;15864;15857:12;15818:53;15880:67;15944:2;15939;15932:5;15928:14;15923:2;15919;15915:11;15880:67;:::i;:::-;15966:5;15329:648;-1:-1:-1;;;;;15329:648:1:o;17775:459::-;18035:1;18031;18026:3;18022:11;18018:19;18010:6;18006:32;17995:9;17988:51;18075:6;18070:2;18059:9;18055:18;18048:34;18118:6;18113:2;18102:9;18098:18;18091:34;18161:3;18156:2;18145:9;18141:18;18134:31;17969:4;18182:46;18223:3;18212:9;18208:19;18200:6;18182:46;:::i;:::-;18174:54;17775:459;-1:-1:-1;;;;;;17775:459:1:o;18239:184::-;18309:6;18362:2;18350:9;18341:7;18337:23;18333:32;18330:52;;;18378:1;18375;18368:12;18330:52;-1:-1:-1;18401:16:1;;18239:184;-1:-1:-1;18239:184:1:o;18428:168::-;18501:9;;;18532;;18549:15;;;18543:22;;18529:37;18519:71;;18570:18;;:::i;18601:127::-;18662:10;18657:3;18653:20;18650:1;18643:31;18693:4;18690:1;18683:15;18717:4;18714:1;18707:15;18733:120;18773:1;18799;18789:35;;18804:18;;:::i;:::-;-1:-1:-1;18838:9:1;;18733:120::o;18858:135::-;18897:3;18918:17;;;18915:43;;18938:18;;:::i;:::-;-1:-1:-1;18985:1:1;18974:13;;18858:135::o;18998:112::-;19030:1;19056;19046:35;;19061:18;;:::i;:::-;-1:-1:-1;19095:9:1;;18998:112::o;19883:127::-;19944:10;19939:3;19935:20;19932:1;19925:31;19975:4;19972:1;19965:15;19999:4;19996:1;19989:15;20015:151;20105:4;20098:12;;;20084;;;20080:31;;20123:14;;20120:40;;;20140:18;;:::i;20171:168::-;20238:6;20264:10;;;20276;;;20260:27;;20299:11;;;20296:37;;;20313:18;;:::i;20344:489::-;-1:-1:-1;;;;;20613:15:1;;;20595:34;;20665:15;;20660:2;20645:18;;20638:43;20712:2;20697:18;;20690:34;;;20760:3;20755:2;20740:18;;20733:31;;;20538:4;;20781:46;;20807:19;;20799:6;20781:46;:::i;20838:249::-;20907:6;20960:2;20948:9;20939:7;20935:23;20931:32;20928:52;;;20976:1;20973;20966:12;20928:52;21008:9;21002:16;21027:30;21051:5;21027:30;:::i

Swarm Source

ipfs://47082ee072ea47773af03c17deb69717821bda263ea33adb35f23d7990a7ff93
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.