ETH Price: $3,522.65 (+5.01%)

Token

ForgeToken (FORGE)
 

Overview

Max Total Supply

3,292 FORGE

Holders

1,741

Market

Volume (24H)

0.009 ETH

Min Price (24H)

$31.70 @ 0.009000 ETH

Max Price (24H)

$31.70 @ 0.009000 ETH
Filtered by Token Holder
*rosé.eth
Balance
18 FORGE
0x9c01b839c6091e519fd4749efa8b81e190c6d892
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.