ETH Price: $3,259.20 (-0.28%)
Gas: 1 Gwei

Token

Giraffles (Giraffles)
 

Overview

Max Total Supply

1,519 Giraffles

Holders

319

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
broskiduder.eth
Balance
2 Giraffles
0x575353AFd7e6F37A42F808959e34A6F2d01957A9
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Giraffles

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity Multiple files format)

File 6 of 17: Giraffles.sol
// SPDX-License-Identifier: GPL-3.0
// Giraffles x MysteryMints 2022 - The Ultimate NFT Prize Draw
// Huge thanks to ToyBoogers & Pagzi Tech for the optimised ERC721 (goodbye high gas fees)
pragma solidity ^0.8.11;
import "./ERC721Enum.sol";
import "./Ownable.sol";
import "./Strings.sol";
import "./ReentrancyGuard.sol";
import "./VRFConsumerBase.sol";

contract Giraffles is ERC721Enum, Ownable, ReentrancyGuard, VRFConsumerBase {
    using Strings for uint256;
    string public baseURI;
    
    // Chainlink VRF
    bytes32 public keyHash = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445;
    uint256 public fee = 2 * 10 ** 18; // 2 LINK
    
    // prize blocknumbers (4 draws per month)
    uint256 public constant SALE_START_BLOCK = 14019615;        // 16th Jan 2022 ~6PM EST
    uint256 public draw_block_1 = SALE_START_BLOCK + 25928;     // 20th Jan 2022 ~5PM EST
    uint256 public draw_block_2 = SALE_START_BLOCK + 58680;     // 25th Jan 2022 ~5PM EST
    uint256 public draw_block_3 = SALE_START_BLOCK + 91432;     // 30th Jan 2022 ~5PM EST
    
    // current draw number (so that we can assign the randomness result to the correct draw)
    uint256 public currentDrawNumber = 0;
    
    // draw randomness results (set from Chainlink)
    uint256 public randomness_testing = 0;
    uint256 public randomness_draw_1 = 0;
    uint256 public randomness_draw_2 = 0;
    uint256 public randomness_draw_3 = 0;
    
    //sale settings
    uint256 public constant SALE_START_TIMESTAMP = 1642374000; // Sunday, January 16th 2022 11:00:00 PM (GMT)
    uint256 public price = 0.05 ether;
    uint256 public whitelistPrice = 0.02 ether;
    uint256 public whitelistMaxSupply = 1200;
    uint256 public whitelistMinted = 0;
    uint256 public maxSupply = 5000;
    uint256 public reserved = 80; // NFTs reserved for giveaways etc
    uint256 public maxMint = 20;
    bool public salePaused = false;

    // whitelist
    address public constant WHITELIST_SIGNER = 0x8430e0B7be3315735C303b82E4471D59AC152Aa5;
    
    string _name = "Giraffles";
    string _symbol = "Giraffles";
    string _initBaseURI = "https://mysterymints.io:7776/api/opensea/1/";
    
    constructor() ERC721P(_name, _symbol) VRFConsumerBase(
            0xf0d54349aDdcf704F77AE15b96510dEA15cb7952, // VRF Coordinator
            0x514910771AF9Ca656af840dff83E8264EcF986CA  // LINK Token
        ){
        setBaseURI(_initBaseURI);
    }

    /** 
     * Requests true on-chain randomness so we can test everything is working correctly
     */
    function randomnessTest() public onlyOwner {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract");
        
        // set current draw number to 0 (testing) so we can assign the randomness result
        currentDrawNumber = 0;
        
        // request randomness via Chainlink VRF
        requestRandomness(keyHash, fee);
    }
    
    /** 
     * Returns the randomness result for a given draw (0 if draw has not occured yet)
     */
    function randomnessForDraw(uint256 drawNumber) public view returns (uint256) {
        if(drawNumber == 1) {
            return randomness_draw_1;
        }
        else if(drawNumber == 2) {
            return randomness_draw_2;
        }
        else if(drawNumber == 3) {
            return randomness_draw_3;
        }
        else {
            return randomness_testing;
        }
    }
    
    /** 
     * For a given draw, returns the block number which must be reached before the draw can be executed
     */
    function blockThresholdForDraw(uint256 drawNumber) public view returns (uint256) {
        require(drawNumber > 0 && drawNumber <= 3, "Invalid drawNumber: must be 1-3");
        if(drawNumber == 1) {
            return draw_block_1;
        }
        else if(drawNumber == 2) {
            return draw_block_2;
        }
        else if(drawNumber == 3) {
            return draw_block_3;
        }
        return 0;
    }
    
    /** 
     * Requests true on-chain randomness for a given draw so that winners can be fairly chosen
     * Randomness can only be requested and set once for a given draw
     */
    function prizeDraw(uint256 drawNumber) public onlyOwner {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract");
        require(drawNumber > 0 && drawNumber <= 3, "Invalid drawNumber: must be 1-3");
        require(blockThresholdForDraw(drawNumber) <= block.number, "Prize block not reached yet");
        require(randomnessForDraw(drawNumber) == 0, "Randomness already generated for this draw");
        
        // set current draw number so we can correctly assign the randomness result
        currentDrawNumber = drawNumber;
        
        // request randomness via Chainlink VRF
        requestRandomness(keyHash, fee);
    }
    
    /**
     * Callback function used by VRF Coordinator
     * Sets the randomness result to a given draw, which is then used to determine the winners
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
        if(currentDrawNumber == 1) {
            randomness_draw_1 = randomness;
        }
        else if(currentDrawNumber == 2) {
            randomness_draw_2 = randomness;
        }
        else if(currentDrawNumber == 3) {
            randomness_draw_3 = randomness;
        }
        else {
            randomness_testing = randomness;
        }
    }

    // internal
    function _baseURI() internal view virtual returns (string memory) {
        return baseURI;
    }
    
    function mintingHasStarted() public view returns (bool) {
        return block.timestamp >= SALE_START_TIMESTAMP;
    }

    function getWhitelistMinted() public view returns (uint256) {
        return whitelistMinted;
    }

    function whitelistCanMint() public view returns (bool) {
        return whitelistMinted < whitelistMaxSupply;
    }
    
    /**
     * @dev Gets current NFT Price
     */
    function getNFTPrice() public view returns (uint256) {
        return price;
    }

    /**
     * @dev Gets current NFT Price (whitelist)
     */
    function getWhitelistNFTPrice() public view returns (uint256) {
        return whitelistPrice;
    }
    
    /* whitelist */
    function isWhitelisted(address user, bytes memory signature) public pure returns (bool) {
        bytes32 messageHash = keccak256(abi.encodePacked(user));
        bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash));
        return recoverSigner(ethSignedMessageHash, signature) == WHITELIST_SIGNER;
    }
    
    function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) private pure returns (address) {
        (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);
        return ecrecover(_ethSignedMessageHash, v, r, s);
    }
    
    function splitSignature(bytes memory sig) private pure returns (bytes32 r, bytes32 s, uint8 v) {
        require(sig.length == 65, "invalid signature length");
        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }
    }

    // public minting
    function mintNFT(uint256 numberOfNfts, bytes memory signature, bool whitelist) public payable nonReentrant {
        require(block.timestamp >= SALE_START_TIMESTAMP, "Sale has not started");
        uint256 s = totalSupply();
        require(!salePaused, "Sale Paused");
        require(numberOfNfts > 0 && numberOfNfts <= maxMint, "Invalid numberOfNfts");
        require((s + numberOfNfts) <= (maxSupply - reserved), "Exceeds Max Supply");
        
        // user requesting cheaper mint price - verify they are whitelisted
        if(whitelist) {
            require(whitelistMinted < whitelistMaxSupply);
            require(msg.value >= whitelistPrice * numberOfNfts, "Not Enough ETH");
            require(isWhitelisted(msg.sender, signature), "Address not whitelisted");
            whitelistMinted += numberOfNfts;
        }
        // user requesting regular mint price
        else {
            require(msg.value >= price * numberOfNfts, "Not Enough ETH");
        }
        for (uint256 i = 0; i < numberOfNfts; ++i) {
            _safeMint(msg.sender, s + i, "");
        }
        delete s;
    }

    // admin minting for reserved NFTs
    function giftNFT(uint256[] calldata quantity, address[] calldata recipient) external onlyOwner {
        require(quantity.length == recipient.length, "Invalid quantities and recipients (length mismatch)");
        uint256 totalQuantity = 0;
        uint256 s = totalSupply();
        for (uint256 i = 0; i < quantity.length; ++i) {
            totalQuantity += quantity[i];
        }
        require(s + totalQuantity <= maxSupply, "Exceeds Max Supply");
        require(totalQuantity <= reserved, "Exceeds Max Reserved");

        // update remaining reserved count
        reserved -= totalQuantity;

        delete totalQuantity;
        for (uint256 i = 0; i < recipient.length; ++i) {
            for (uint256 j = 0; j < quantity[i]; ++j) {
                _safeMint(recipient[i], s++, "");
            }
        }
        delete s;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: Nonexistent token");
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString())) : "";
    }

    /** 
     * Set the block number which must be reached before a given draw can be executed (callable by Owner only)
     */
    function setDrawBlock(uint256 drawNumber, uint256 blockNumber) public onlyOwner {
        require(drawNumber > 0 && drawNumber <= 3, "Invalid drawNumber: must be 1-3");
        if(drawNumber == 1) {
            draw_block_1 = blockNumber;
        }
        else if(drawNumber == 2) {
            draw_block_2 = blockNumber;
        }
        else if(drawNumber == 3) {
            draw_block_3 = blockNumber;
        }
    }

    function setPrice(uint256 _newPrice) public onlyOwner {
        price = _newPrice;
    }

    function setWhitelistPrice(uint256 _newPrice) public onlyOwner {
        whitelistPrice = _newPrice;
    }

    function setMaxMintAmount(uint256 _newMaxMintAmount) public onlyOwner {
        maxMint = _newMaxMintAmount;
    }

    function setMaxSupply(uint256 _newMaxSupply) public onlyOwner {
        maxSupply = _newMaxSupply;
    }

    function setWhitelistMaxSupply(uint256 _newMaxSupply) public onlyOwner {
        whitelistMaxSupply = _newMaxSupply;
    }

    function setReserved(uint256 _newReserved) public onlyOwner {
        reserved = _newReserved;
    }

    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }

    function setSalePaused(bool _salePaused) public onlyOwner {
        salePaused = _salePaused;
    }

    // the following function were added for transparency regarding ETH raised and prize pool calculations
    uint256 totalWithdrawn = 0;

    function getTotalWithdrawn() public view returns (uint256) {
        return totalWithdrawn;
    }

    function getTotalBalance() public view returns (uint256) {
        return address(this).balance;
    }

    function getTotalRaised() public view returns (uint256) {
        return getTotalWithdrawn() + getTotalBalance();
    }

    /**
     * Withdraw ETH from the contract (callable by Owner only)
     */
    function withdraw() public payable onlyOwner {
        uint256 val = address(this).balance;
        (bool success, ) = payable(msg.sender).call{
            value: val
        }("");
        require(success);
        totalWithdrawn += val;
        delete val;
    }

    /**
     * Withdraw LINK tokens from the contract (callable by Owner only)
     */
    function withdrawLINK() public onlyOwner {
        require(LINK.transfer(msg.sender, LINK.balanceOf(address(this))), "Unable to transfer");
    }
}

File 1 of 17: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)

pragma solidity ^0.8.0;

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

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

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

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

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

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

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

File 2 of 17: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (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 3 of 17: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 4 of 17: ERC721Enum.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.11;
import "./ERC721P.sol";
import "./IERC721Enumerable.sol";

abstract contract ERC721Enum is ERC721P, IERC721Enumerable {
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(IERC165, ERC721P)
        returns (bool)
    {
        return
            interfaceId == type(IERC721Enumerable).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function tokenOfOwnerByIndex(address owner, uint256 index)
        public
        view
        override
        returns (uint256 tokenId)
    {
        require(index < ERC721P.balanceOf(owner), "ERC721Enum: owner ioob");
        uint256 count;
        for (uint256 i; i < _owners.length; ++i) {
            if (owner == _owners[i]) {
                if (count == index) return i;
                else ++count;
            }
        }
        require(false, "ERC721Enum: owner ioob");
    }

    function tokensOfOwner(address owner)
        public
        view
        returns (uint256[] memory)
    {
        require(0 < ERC721P.balanceOf(owner), "ERC721Enum: owner ioob");
        uint256 tokenCount = balanceOf(owner);
        uint256[] memory tokenIds = new uint256[](tokenCount);
        for (uint256 i = 0; i < tokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(owner, i);
        }
        return tokenIds;
    }

    function totalSupply() public view virtual override returns (uint256) {
        return _owners.length;
    }

    function tokenByIndex(uint256 index)
        public
        view
        virtual
        override
        returns (uint256)
    {
        require(index < ERC721Enum.totalSupply(), "ERC721Enum: global ioob");
        return index;
    }
}

File 5 of 17: ERC721P.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.11;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./ERC165.sol";

abstract contract ERC721P is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    string private _name;
    string private _symbol;
    address[] internal _owners;
    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }
    
    function getOwners() external view returns (address[] memory) {
        return _owners;
    }

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

    function balanceOf(address owner)
        public
        view
        virtual
        override
        returns (uint256)
    {
        require(
            owner != address(0),
            "ERC721: balance query for the zero address"
        );
        uint256 count = 0;
        uint256 length = _owners.length;
        for (uint256 i = 0; i < length; ++i) {
            if (owner == _owners[i]) {
                ++count;
            }
        }
        delete length;
        return count;
    }

    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        address owner = _owners[tokenId];
        require(
            owner != address(0),
            "ERC721: owner query for nonexistent token"
        );
        return owner;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721P.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(operator != _msgSender(), "ERC721: approve to caller");

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

    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        _safeTransfer(from, to, tokenId, _data);
    }

    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return tokenId < _owners.length && _owners[tokenId] != address(0);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        virtual
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ERC721P.ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);
        _owners.push(to);

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

    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721P.ownerOf(tokenId);

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

        // Clear approvals
        _approve(address(0), tokenId);
        _owners[tokenId] = address(0);

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

    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(
            ERC721P.ownerOf(tokenId) == from,
            "ERC721: transfer of token that is not own"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721P.ownerOf(tokenId), to, tokenId);
    }

    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try
                IERC721Receiver(to).onERC721Received(
                    _msgSender(),
                    from,
                    tokenId,
                    _data
                )
            returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert(
                        "ERC721: transfer to non ERC721Receiver implementer"
                    );
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 7 of 17: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 8 of 17: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 9 of 17: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 10 of 17: IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 11 of 17: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 12 of 17: LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {

  function allowance(
    address owner,
    address spender
  )
    external
    view
    returns (
      uint256 remaining
    );

  function approve(
    address spender,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function balanceOf(
    address owner
  )
    external
    view
    returns (
      uint256 balance
    );

  function decimals()
    external
    view
    returns (
      uint8 decimalPlaces
    );

  function decreaseApproval(
    address spender,
    uint256 addedValue
  )
    external
    returns (
      bool success
    );

  function increaseApproval(
    address spender,
    uint256 subtractedValue
  ) external;

  function name()
    external
    view
    returns (
      string memory tokenName
    );

  function symbol()
    external
    view
    returns (
      string memory tokenSymbol
    );

  function totalSupply()
    external
    view
    returns (
      uint256 totalTokensIssued
    );

  function transfer(
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  )
    external
    returns (
      bool success
    );

  function transferFrom(
    address from,
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

}

File 13 of 17: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

/**
 * @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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _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 14 of 17: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 15 of 17: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

File 16 of 17: VRFConsumerBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./LinkTokenInterface.sol";

import "./VRFRequestIDBase.sol";

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {

  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBase expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(
    bytes32 requestId,
    uint256 randomness
  )
    internal
    virtual;

  /**
   * @dev In order to keep backwards compatibility we have kept the user
   * seed field around. We remove the use of it because given that the blockhash
   * enters later, it overrides whatever randomness the used seed provides.
   * Given that it adds no security, and can easily lead to misunderstandings,
   * we have removed it from usage and can now provide a simpler API.
   */
  uint256 constant private USER_SEED_PLACEHOLDER = 0;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @dev The _seed parameter is vestigial, and is kept only for API
   * @dev compatibility with older versions. It can't *hurt* to mix in some of
   * @dev your own randomness, here, but it's not necessary because the VRF
   * @dev oracle will mix the hash of the block containing your request into the
   * @dev VRF seed it ultimately uses.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(
    bytes32 _keyHash,
    uint256 _fee
  )
    internal
    returns (
      bytes32 requestId
    )
  {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed  = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input seed,
    // which would result in a predictable/duplicate output, if multiple such
    // requests appeared in the same block.
    nonces[_keyHash] = nonces[_keyHash] + 1;
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface immutable internal LINK;
  address immutable private vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   * @param _link address of LINK token contract
   *
   * @dev https://docs.chain.link/docs/link-token-contracts
   */
  constructor(
    address _vrfCoordinator,
    address _link
  ) {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(
    bytes32 requestId,
    uint256 randomness
  )
    external
  {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

File 17 of 17: VRFRequestIDBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract VRFRequestIDBase {

  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(
    bytes32 _keyHash,
    uint256 _userSeed,
    address _requester,
    uint256 _nonce
  )
    internal
    pure
    returns (
      uint256
    )
  {
    return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(
    bytes32 _keyHash,
    uint256 _vRFInputSeed
  )
    internal
    pure
    returns (
      bytes32
    )
  {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"SALE_START_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SALE_START_TIMESTAMP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELIST_SIGNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"drawNumber","type":"uint256"}],"name":"blockThresholdForDraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentDrawNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"draw_block_1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"draw_block_2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"draw_block_3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","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":[],"name":"getNFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistNFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"quantity","type":"uint256[]"},{"internalType":"address[]","name":"recipient","type":"address[]"}],"name":"giftNFT","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":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"keyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfNfts","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bool","name":"whitelist","type":"bool"}],"name":"mintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintingHasStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"drawNumber","type":"uint256"}],"name":"prizeDraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"drawNumber","type":"uint256"}],"name":"randomnessForDraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomnessTest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"randomness_draw_1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomness_draw_2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomness_draw_3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomness_testing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserved","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":"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":[],"name":"salePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"drawNumber","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"setDrawBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxMintAmount","type":"uint256"}],"name":"setMaxMintAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newReserved","type":"uint256"}],"name":"setReserved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_salePaused","type":"bool"}],"name":"setSalePaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxSupply","type":"uint256"}],"name":"setWhitelistMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setWhitelistPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistCanMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMaxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawLINK","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040527faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445600955671bc16d674ec80000600a556200004562d5ec1f6165486200053b565b600b556200005962d5ec1f61e5386200053b565b600c556200006e62d5ec1f620165286200053b565b600d556000600e819055600f81905560108190556011819055601281905566b1a2bc2ec5000060135566470de4df82000060149081556104b06015556016919091556113886017556050601855601955601a805460ff19169055604080518082019091526009808252684769726166666c657360b81b6020909201918252620000fa91601b9162000495565b50604080518082019091526009808252684769726166666c657360b81b60209092019182526200012d91601c9162000495565b506040518060600160405280602b8152602001620049a5602b913980516200015e91601d9160209091019062000495565b506000601e553480156200017157600080fd5b5073f0d54349addcf704f77ae15b96510dea15cb795273514910771af9ca656af840dff83e8264ecf986ca601b8054620001ab9062000562565b80601f0160208091040260200160405190810160405280929190818152602001828054620001d99062000562565b80156200022a5780601f10620001fe576101008083540402835291602001916200022a565b820191906000526020600020905b8154815290600101906020018083116200020c57829003601f168201915b5050505050601c80546200023e9062000562565b80601f01602080910402602001604051908101604052809291908181526020018280546200026c9062000562565b8015620002bd5780601f106200029157610100808354040283529160200191620002bd565b820191906000526020600020905b8154815290600101906020018083116200029f57829003601f168201915b50508451620002d793506000925060208601915062000495565b508051620002ed90600190602084019062000495565b5050506200030a62000304620003c760201b60201c565b620003cb565b60016006556001600160a01b0391821660a05216608052601d8054620003c19190620003369062000562565b80601f0160208091040260200160405190810160405280929190818152602001828054620003649062000562565b8015620003b55780601f106200038957610100808354040283529160200191620003b5565b820191906000526020600020905b8154815290600101906020018083116200039757829003601f168201915b50506200041d92505050565b6200059f565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6005546001600160a01b031633146200047c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b80516200049190600890602084019062000495565b5050565b828054620004a39062000562565b90600052602060002090601f016020900481019282620004c7576000855562000512565b82601f10620004e257805160ff191683800117855562000512565b8280016001018555821562000512579182015b8281111562000512578251825591602001919060010190620004f5565b506200052092915062000524565b5090565b5b8082111562000520576000815560010162000525565b600082198211156200055d57634e487b7160e01b600052601160045260246000fd5b500190565b600181811c908216806200057757607f821691505b602082108114156200059957634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a0516143c4620005e1600039600081816121d20152613387015260008181611da80152818161246d01528181612769015261334b01526143c46000f3fe6080604052600436106104655760003560e01c80638462151c11610243578063b2c2c5ed11610143578063d57e4eae116100bb578063e985e9c51161008a578063fb107a4f1161006f578063fb107a4f14610c10578063fc1a1c3614610c25578063fe60d12c14610c3b57600080fd5b8063e985e9c514610b9a578063f2fde38b14610bf057600080fd5b8063d57e4eae14610b43578063d5abeb0114610b58578063ddca3f4314610b6e578063e5a3044014610b8457600080fd5b8063c18fdebb11610112578063c5e446cd116100f7578063c5e446cd14610af8578063c87b56dd14610b0d578063d22f974314610b2d57600080fd5b8063c18fdebb14610ac3578063c29af27414610ad857600080fd5b8063b2c2c5ed14610a56578063b48db6ad14610a6d578063b677dd0b14610a83578063b88d4fde14610aa357600080fd5b806394985ddd116101d65780639f550293116101a5578063a0e67e2b1161018a578063a0e67e2b146109ff578063a22cb46514610a21578063adc2112f14610a4157600080fd5b80639f550293146109d4578063a035b1fe146109e957600080fd5b806394985ddd1461097357806395d89b41146109935780639a333f58146109a85780639ba72376146109be57600080fd5b80638d92becd116102125780638d92becd146108f05780638da5cb5b1461091057806391b7f5ed1461093b578063946807fd1461095b57600080fd5b80638462151c1461088257806388f620d4146108af57806389404a79146108c55780638990694f146108da57600080fd5b806342842e0e116103695780636c0360eb116102e157806370a08231116102b0578063717d57d311610295578063717d57d31461082c5780637501f7411461084c57806383f9f4d21461086257600080fd5b806370a08231146107f7578063715018a61461081757600080fd5b80636c0360eb146107825780636f8b44b0146107975780636fbb8364146107b75780636fd9bed0146107d757600080fd5b806358f46285116103385780635d08c1ae1161031d5780635d08c1ae1461073257806361728f391461074c5780636352211e1461076257600080fd5b806358f46285146107065780635abf4ee81461071c57600080fd5b806342842e0e1461068c5780634f6ccce7146106ac57806354964d27146106cc57806355f804b3146106e657600080fd5b8063221fd0ff116103fc5780632d6e71b6116103cb578063308b8706116103b0578063308b87061461063c5780633ccfd60b1461065c578063417b94831461066457600080fd5b80632d6e71b6146105fc5780632f745c591461061c57600080fd5b8063221fd0ff1461059a57806323b872dd146105b057806324f18ab6146105d057806328cfab11146105e957600080fd5b8063095ea7b311610438578063095ea7b31461052857806312b583491461054857806318160ddd146105655780631f0a8fa71461057a57600080fd5b806301ffc9a71461046a57806306fdde031461049f578063081812fc146104c1578063088a4ed014610506575b600080fd5b34801561047657600080fd5b5061048a610485366004613b35565b610c51565b60405190151581526020015b60405180910390f35b3480156104ab57600080fd5b506104b4610cad565b6040516104969190613bc8565b3480156104cd57600080fd5b506104e16104dc366004613bdb565b610d3f565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610496565b34801561051257600080fd5b50610526610521366004613bdb565b610dea565b005b34801561053457600080fd5b50610526610543366004613c18565b610e56565b34801561055457600080fd5b50475b604051908152602001610496565b34801561057157600080fd5b50600254610557565b34801561058657600080fd5b5061048a610595366004613d25565b610faf565b3480156105a657600080fd5b50610557600f5481565b3480156105bc57600080fd5b506105266105cb366004613d73565b611081565b3480156105dc57600080fd5b506015546016541061048a565b6105266105f7366004613dbd565b611108565b34801561060857600080fd5b50610526610617366004613bdb565b611468565b34801561062857600080fd5b50610557610637366004613c18565b6114d4565b34801561064857600080fd5b50610526610657366004613e18565b6115f0565b6105266116e5565b34801561067057600080fd5b506104e1738430e0b7be3315735c303b82e4471d59ac152aa581565b34801561069857600080fd5b506105266106a7366004613d73565b6117be565b3480156106b857600080fd5b506105576106c7366004613bdb565b6117d9565b3480156106d857600080fd5b506361e4a37042101561048a565b3480156106f257600080fd5b50610526610701366004613e3a565b611836565b34801561071257600080fd5b5061055760155481565b34801561072857600080fd5b50610557600b5481565b34801561073e57600080fd5b50601a5461048a9060ff1681565b34801561075857600080fd5b5061055760095481565b34801561076e57600080fd5b506104e161077d366004613bdb565b6118b0565b34801561078e57600080fd5b506104b461195d565b3480156107a357600080fd5b506105266107b2366004613bdb565b6119eb565b3480156107c357600080fd5b506105576107d2366004613bdb565b611a57565b3480156107e357600080fd5b506105576107f2366004613bdb565b611af0565b34801561080357600080fd5b50610557610812366004613e83565b611b32565b34801561082357600080fd5b50610526611c31565b34801561083857600080fd5b50610526610847366004613bdb565b611ca4565b34801561085857600080fd5b5061055760195481565b34801561086e57600080fd5b5061052661087d366004613bdb565b611d10565b34801561088e57600080fd5b506108a261089d366004613e83565b611fbc565b6040516104969190613e9e565b3480156108bb57600080fd5b5061055760125481565b3480156108d157600080fd5b50601e54610557565b3480156108e657600080fd5b5061055760165481565b3480156108fc57600080fd5b5061052661090b366004613ee2565b6120b6565b34801561091c57600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff166104e1565b34801561094757600080fd5b50610526610956366004613bdb565b61214e565b34801561096757600080fd5b506105576361e4a37081565b34801561097f57600080fd5b5061052661098e366004613e18565b6121ba565b34801561099f57600080fd5b506104b4612249565b3480156109b457600080fd5b50610557600d5481565b3480156109ca57600080fd5b50610557600e5481565b3480156109e057600080fd5b50610557612258565b3480156109f557600080fd5b5061055760135481565b348015610a0b57600080fd5b50610a1461226d565b6040516104969190613eff565b348015610a2d57600080fd5b50610526610a3c366004613f4d565b6122db565b348015610a4d57600080fd5b506105266123d8565b348015610a6257600080fd5b5061055762d5ec1f81565b348015610a7957600080fd5b5061055760115481565b348015610a8f57600080fd5b50610526610a9e366004613bdb565b6125d7565b348015610aaf57600080fd5b50610526610abe366004613f84565b612643565b348015610acf57600080fd5b506105266126d1565b348015610ae457600080fd5b50610526610af3366004614038565b61284f565b348015610b0457600080fd5b50601454610557565b348015610b1957600080fd5b506104b4610b28366004613bdb565b612ae6565b348015610b3957600080fd5b50610557600c5481565b348015610b4f57600080fd5b50601654610557565b348015610b6457600080fd5b5061055760175481565b348015610b7a57600080fd5b50610557600a5481565b348015610b9057600080fd5b5061055760105481565b348015610ba657600080fd5b5061048a610bb53660046140a4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260046020908152604080832093909416825291909152205460ff1690565b348015610bfc57600080fd5b50610526610c0b366004613e83565b612bbf565b348015610c1c57600080fd5b50601354610557565b348015610c3157600080fd5b5061055760145481565b348015610c4757600080fd5b5061055760185481565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610ca75750610ca782612cb8565b92915050565b606060008054610cbc906140d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610ce8906140d7565b8015610d355780601f10610d0a57610100808354040283529160200191610d35565b820191906000526020600020905b815481529060010190602001808311610d1857829003601f168201915b5050505050905090565b6000610d4a82612d9b565b610dc15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601955565b6000610e61826118b0565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f055760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610db8565b3373ffffffffffffffffffffffffffffffffffffffff82161480610f2e5750610f2e8133610bb5565b610fa05760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610db8565b610faa8383612dff565b505050565b604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b16602080830191909152825180830360140181526034830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060548401526070808401829052845180850390910181526090909301909352815191012060009190738430e0b7be3315735c303b82e4471d59ac152aa56110618286612e9f565b73ffffffffffffffffffffffffffffffffffffffff161495945050505050565b61108b3382612f3c565b6110fd5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610db8565b610faa838383613078565b6002600654141561115b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610db8565b60026006556361e4a3704210156111b45760405162461bcd60e51b815260206004820152601460248201527f53616c6520686173206e6f7420737461727465640000000000000000000000006044820152606401610db8565b60006111bf60025490565b601a5490915060ff16156112155760405162461bcd60e51b815260206004820152600b60248201527f53616c65205061757365640000000000000000000000000000000000000000006044820152606401610db8565b60008411801561122757506019548411155b6112735760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206e756d6265724f664e6674730000000000000000000000006044820152606401610db8565b601854601754611283919061415a565b61128d8583614171565b11156112db5760405162461bcd60e51b815260206004820152601260248201527f45786365656473204d617820537570706c7900000000000000000000000000006044820152606401610db8565b81156113c157601554601654106112f157600080fd5b836014546112ff9190614189565b34101561134e5760405162461bcd60e51b815260206004820152600e60248201527f4e6f7420456e6f756768204554480000000000000000000000000000000000006044820152606401610db8565b6113583384610faf565b6113a45760405162461bcd60e51b815260206004820152601760248201527f41646472657373206e6f742077686974656c69737465640000000000000000006044820152606401610db8565b83601660008282546113b69190614171565b9091555061141e9050565b836013546113cf9190614189565b34101561141e5760405162461bcd60e51b815260206004820152600e60248201527f4e6f7420456e6f756768204554480000000000000000000000000000000000006044820152606401610db8565b60005b8481101561145c5761144c336114378385614171565b60405180602001604052806000815250613247565b611455816141c6565b9050611421565b50506001600655505050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146114cf5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601855565b60006114df83611b32565b821061152d5760405162461bcd60e51b815260206004820152601660248201527f455243373231456e756d3a206f776e657220696f6f62000000000000000000006044820152606401610db8565b6000805b6002548110156115a7576002818154811061154e5761154e6141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff86811691161415611597578382141561158b579150610ca79050565b611594826141c6565b91505b6115a0816141c6565b9050611531565b5060405162461bcd60e51b815260206004820152601660248201527f455243373231456e756d3a206f776e657220696f6f62000000000000000000006044820152606401610db8565b60055473ffffffffffffffffffffffffffffffffffffffff1633146116575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b600082118015611668575060038211155b6116b45760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420647261774e756d6265723a206d75737420626520312d33006044820152606401610db8565b81600114156116c357600b5550565b81600214156116d257600c5550565b81600314156116e157600d8190555b5050565b60055473ffffffffffffffffffffffffffffffffffffffff16331461174c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b6040514790600090339083908381818185875af1925050503d8060008114611790576040519150601f19603f3d011682016040523d82523d6000602084013e611795565b606091505b50509050806117a357600080fd5b81601e60008282546117b59190614171565b90915550505050565b610faa83838360405180602001604052806000815250612643565b60006117e460025490565b82106118325760405162461bcd60e51b815260206004820152601760248201527f455243373231456e756d3a20676c6f62616c20696f6f620000000000000000006044820152606401610db8565b5090565b60055473ffffffffffffffffffffffffffffffffffffffff16331461189d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b80516116e1906008906020840190613a77565b600080600283815481106118c6576118c66141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080610ca75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610db8565b6008805461196a906140d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611996906140d7565b80156119e35780601f106119b8576101008083540402835291602001916119e3565b820191906000526020600020905b8154815290600101906020018083116119c657829003601f168201915b505050505081565b60055473ffffffffffffffffffffffffffffffffffffffff163314611a525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601755565b60008082118015611a69575060038211155b611ab55760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420647261774e756d6265723a206d75737420626520312d33006044820152606401610db8565b8160011415611ac6575050600b5490565b8160021415611ad7575050600c5490565b8160031415611ae8575050600d5490565b506000919050565b60008160011415611b0357505060105490565b8160021415611b1457505060115490565b8160031415611b2557505060125490565b5050600f5490565b919050565b600073ffffffffffffffffffffffffffffffffffffffff8216611bbd5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610db8565b600254600090815b81811015611c285760028181548110611be057611be06141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff86811691161415611c1857611c15836141c6565b92505b611c21816141c6565b9050611bc5565b50909392505050565b60055473ffffffffffffffffffffffffffffffffffffffff163314611c985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b611ca260006132d0565b565b60055473ffffffffffffffffffffffffffffffffffffffff163314611d0b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601455565b60055473ffffffffffffffffffffffffffffffffffffffff163314611d775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b600a546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e28919061422e565b1015611e765760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e7472616374006044820152606401610db8565b600081118015611e87575060038111155b611ed35760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420647261774e756d6265723a206d75737420626520312d33006044820152606401610db8565b43611edd82611a57565b1115611f2b5760405162461bcd60e51b815260206004820152601b60248201527f5072697a6520626c6f636b206e6f7420726561636865642079657400000000006044820152606401610db8565b611f3481611af0565b15611fa75760405162461bcd60e51b815260206004820152602a60248201527f52616e646f6d6e65737320616c72656164792067656e65726174656420666f7260448201527f20746869732064726177000000000000000000000000000000000000000000006064820152608401610db8565b80600e819055506116e1600954600a54613347565b6060611fc782611b32565b6000106120165760405162461bcd60e51b815260206004820152601660248201527f455243373231456e756d3a206f776e657220696f6f62000000000000000000006044820152606401610db8565b600061202183611b32565b905060008167ffffffffffffffff81111561203e5761203e613c42565b604051908082528060200260200182016040528015612067578160200160208202803683370190505b50905060005b828110156120ae5761207f85826114d4565b828281518110612091576120916141ff565b6020908102919091010152806120a6816141c6565b91505061206d565b509392505050565b60055473ffffffffffffffffffffffffffffffffffffffff16331461211d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60055473ffffffffffffffffffffffffffffffffffffffff1633146121b55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601355565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461223f5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610db8565b6116e182826134d0565b606060018054610cbc906140d7565b600047601e546122689190614171565b905090565b60606002805480602002602001604051908101604052809291908181526020018280548015610d3557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116122a7575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff82163314156123415760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610db8565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff16331461243f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb90339083906370a0823190602401602060405180830381865afa1580156124d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f7919061422e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff909216600483015260248201526044016020604051808303816000875af1158015612567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258b9190614247565b611ca25760405162461bcd60e51b815260206004820152601260248201527f556e61626c6520746f207472616e7366657200000000000000000000000000006044820152606401610db8565b60055473ffffffffffffffffffffffffffffffffffffffff16331461263e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601555565b61264d3383612f3c565b6126bf5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610db8565b6126cb84848484613509565b50505050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146127385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b600a546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e9919061422e565b10156128375760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e7472616374006044820152606401610db8565b6000600e55600954600a5461284c9190613347565b50565b60055473ffffffffffffffffffffffffffffffffffffffff1633146128b65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b82811461292b5760405162461bcd60e51b815260206004820152603360248201527f496e76616c6964207175616e74697469657320616e6420726563697069656e7460448201527f7320286c656e677468206d69736d6174636829000000000000000000000000006064820152608401610db8565b60008061293760025490565b905060005b8581101561297a57868682818110612956576129566141ff565b90506020020135836129689190614171565b9250612973816141c6565b905061293c565b506017546129888383614171565b11156129d65760405162461bcd60e51b815260206004820152601260248201527f45786365656473204d617820537570706c7900000000000000000000000000006044820152606401610db8565b601854821115612a285760405162461bcd60e51b815260206004820152601460248201527f45786365656473204d61782052657365727665640000000000000000000000006044820152606401610db8565b8160186000828254612a3a919061415a565b90915550600092508290505b83811015612add5760005b878783818110612a6357612a636141ff565b90506020020135811015612acc57612abc868684818110612a8657612a866141ff565b9050602002016020810190612a9b9190613e83565b84612aa5816141c6565b955060405180602001604052806000815250613247565b612ac5816141c6565b9050612a51565b50612ad6816141c6565b9050612a46565b50505050505050565b6060612af182612d9b565b612b635760405162461bcd60e51b815260206004820152602160248201527f4552433732314d657461646174613a204e6f6e6578697374656e7420746f6b6560448201527f6e000000000000000000000000000000000000000000000000000000000000006064820152608401610db8565b6000612b6d613592565b90506000815111612b8d5760405180602001604052806000815250612bb8565b80612b97846135a1565b604051602001612ba8929190614264565b6040516020818303038152906040525b9392505050565b60055473ffffffffffffffffffffffffffffffffffffffff163314612c265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b73ffffffffffffffffffffffffffffffffffffffff8116612caf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610db8565b61284c816132d0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480612d4b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610ca757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610ca7565b60025460009082108015610ca75750600073ffffffffffffffffffffffffffffffffffffffff1660028381548110612dd557612dd56141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141592915050565b600081815260036020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190612e59826118b0565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080600080612eae856136d3565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015612f09573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b6000612f4782612d9b565b612fb95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610db8565b6000612fc4836118b0565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061303357508373ffffffffffffffffffffffffffffffffffffffff1661301b84610d3f565b73ffffffffffffffffffffffffffffffffffffffff16145b80613070575073ffffffffffffffffffffffffffffffffffffffff80821660009081526004602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16613098826118b0565b73ffffffffffffffffffffffffffffffffffffffff16146131215760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610db8565b73ffffffffffffffffffffffffffffffffffffffff82166131a95760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610db8565b6131b4600082612dff565b81600282815481106131c8576131c86141ff565b6000918252602082200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff938416179055604051839285811692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a4505050565b6132518383613747565b61325e60008484846138a1565b610faa5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610db8565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f0000000000000000000000000000000000000000000000000000000000000000848660006040516020016133c4929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016133f193929190614293565b6020604051808303816000875af1158015613410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134349190614247565b50600083815260076020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052613490906001614171565b6000858152600760205260409020556130708482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600e54600114156134e15760105550565b600e54600214156134f25760115550565b600e54600314156135035760125550565b600f5550565b613514848484613078565b613520848484846138a1565b6126cb5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610db8565b606060088054610cbc906140d7565b6060816135e157505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561360b57806135f5816141c6565b91506136049050600a83614300565b91506135e5565b60008167ffffffffffffffff81111561362657613626613c42565b6040519080825280601f01601f191660200182016040528015613650576020820181803683370190505b5090505b84156130705761366560018361415a565b9150613672600a86614314565b61367d906030614171565b60f81b818381518110613692576136926141ff565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506136cc600a86614300565b9450613654565b600080600083516041146137295760405162461bcd60e51b815260206004820152601860248201527f696e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610db8565b50505060208101516040820151606090920151909260009190911a90565b73ffffffffffffffffffffffffffffffffffffffff82166137aa5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610db8565b6137b381612d9b565b156138005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610db8565b6002805460018101825560009182527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600073ffffffffffffffffffffffffffffffffffffffff84163b15613a6c576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290613918903390899088908890600401614328565b6020604051808303816000875af1925050508015613971575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261396e91810190614371565b60015b613a21573d80801561399f576040519150601f19603f3d011682016040523d82523d6000602084013e6139a4565b606091505b508051613a195760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610db8565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050613070565b506001949350505050565b828054613a83906140d7565b90600052602060002090601f016020900481019282613aa55760008555613aeb565b82601f10613abe57805160ff1916838001178555613aeb565b82800160010185558215613aeb579182015b82811115613aeb578251825591602001919060010190613ad0565b506118329291505b808211156118325760008155600101613af3565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461284c57600080fd5b600060208284031215613b4757600080fd5b8135612bb881613b07565b60005b83811015613b6d578181015183820152602001613b55565b838111156126cb5750506000910152565b60008151808452613b96816020860160208601613b52565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612bb86020830184613b7e565b600060208284031215613bed57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b2d57600080fd5b60008060408385031215613c2b57600080fd5b613c3483613bf4565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115613c8c57613c8c613c42565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613cd257613cd2613c42565b81604052809350858152868686011115613ceb57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112613d1657600080fd5b612bb883833560208501613c71565b60008060408385031215613d3857600080fd5b613d4183613bf4565b9150602083013567ffffffffffffffff811115613d5d57600080fd5b613d6985828601613d05565b9150509250929050565b600080600060608486031215613d8857600080fd5b613d9184613bf4565b9250613d9f60208501613bf4565b9150604084013590509250925092565b801515811461284c57600080fd5b600080600060608486031215613dd257600080fd5b83359250602084013567ffffffffffffffff811115613df057600080fd5b613dfc86828701613d05565b9250506040840135613e0d81613daf565b809150509250925092565b60008060408385031215613e2b57600080fd5b50508035926020909101359150565b600060208284031215613e4c57600080fd5b813567ffffffffffffffff811115613e6357600080fd5b8201601f81018413613e7457600080fd5b61307084823560208401613c71565b600060208284031215613e9557600080fd5b612bb882613bf4565b6020808252825182820181905260009190848201906040850190845b81811015613ed657835183529284019291840191600101613eba565b50909695505050505050565b600060208284031215613ef457600080fd5b8135612bb881613daf565b6020808252825182820181905260009190848201906040850190845b81811015613ed657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613f1b565b60008060408385031215613f6057600080fd5b613f6983613bf4565b91506020830135613f7981613daf565b809150509250929050565b60008060008060808587031215613f9a57600080fd5b613fa385613bf4565b9350613fb160208601613bf4565b925060408501359150606085013567ffffffffffffffff811115613fd457600080fd5b613fe087828801613d05565b91505092959194509250565b60008083601f840112613ffe57600080fd5b50813567ffffffffffffffff81111561401657600080fd5b6020830191508360208260051b850101111561403157600080fd5b9250929050565b6000806000806040858703121561404e57600080fd5b843567ffffffffffffffff8082111561406657600080fd5b61407288838901613fec565b9096509450602087013591508082111561408b57600080fd5b5061409887828801613fec565b95989497509550505050565b600080604083850312156140b757600080fd5b6140c083613bf4565b91506140ce60208401613bf4565b90509250929050565b600181811c908216806140eb57607f821691505b60208210811415614125577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561416c5761416c61412b565b500390565b600082198211156141845761418461412b565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141c1576141c161412b565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156141f8576141f861412b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561424057600080fd5b5051919050565b60006020828403121561425957600080fd5b8151612bb881613daf565b60008351614276818460208801613b52565b83519083019061428a818360208801613b52565b01949350505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006142c86060830184613b7e565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261430f5761430f6142d1565b500490565b600082614323576143236142d1565b500690565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526143676080830184613b7e565b9695505050505050565b60006020828403121561438357600080fd5b8151612bb881613b0756fea2646970667358221220d989eba8ac61668c370c69a1da2341d2a7d7acb99197910b02453e2096ff7c6d64736f6c634300080b003368747470733a2f2f6d7973746572796d696e74732e696f3a373737362f6170692f6f70656e7365612f312f

Deployed Bytecode

0x6080604052600436106104655760003560e01c80638462151c11610243578063b2c2c5ed11610143578063d57e4eae116100bb578063e985e9c51161008a578063fb107a4f1161006f578063fb107a4f14610c10578063fc1a1c3614610c25578063fe60d12c14610c3b57600080fd5b8063e985e9c514610b9a578063f2fde38b14610bf057600080fd5b8063d57e4eae14610b43578063d5abeb0114610b58578063ddca3f4314610b6e578063e5a3044014610b8457600080fd5b8063c18fdebb11610112578063c5e446cd116100f7578063c5e446cd14610af8578063c87b56dd14610b0d578063d22f974314610b2d57600080fd5b8063c18fdebb14610ac3578063c29af27414610ad857600080fd5b8063b2c2c5ed14610a56578063b48db6ad14610a6d578063b677dd0b14610a83578063b88d4fde14610aa357600080fd5b806394985ddd116101d65780639f550293116101a5578063a0e67e2b1161018a578063a0e67e2b146109ff578063a22cb46514610a21578063adc2112f14610a4157600080fd5b80639f550293146109d4578063a035b1fe146109e957600080fd5b806394985ddd1461097357806395d89b41146109935780639a333f58146109a85780639ba72376146109be57600080fd5b80638d92becd116102125780638d92becd146108f05780638da5cb5b1461091057806391b7f5ed1461093b578063946807fd1461095b57600080fd5b80638462151c1461088257806388f620d4146108af57806389404a79146108c55780638990694f146108da57600080fd5b806342842e0e116103695780636c0360eb116102e157806370a08231116102b0578063717d57d311610295578063717d57d31461082c5780637501f7411461084c57806383f9f4d21461086257600080fd5b806370a08231146107f7578063715018a61461081757600080fd5b80636c0360eb146107825780636f8b44b0146107975780636fbb8364146107b75780636fd9bed0146107d757600080fd5b806358f46285116103385780635d08c1ae1161031d5780635d08c1ae1461073257806361728f391461074c5780636352211e1461076257600080fd5b806358f46285146107065780635abf4ee81461071c57600080fd5b806342842e0e1461068c5780634f6ccce7146106ac57806354964d27146106cc57806355f804b3146106e657600080fd5b8063221fd0ff116103fc5780632d6e71b6116103cb578063308b8706116103b0578063308b87061461063c5780633ccfd60b1461065c578063417b94831461066457600080fd5b80632d6e71b6146105fc5780632f745c591461061c57600080fd5b8063221fd0ff1461059a57806323b872dd146105b057806324f18ab6146105d057806328cfab11146105e957600080fd5b8063095ea7b311610438578063095ea7b31461052857806312b583491461054857806318160ddd146105655780631f0a8fa71461057a57600080fd5b806301ffc9a71461046a57806306fdde031461049f578063081812fc146104c1578063088a4ed014610506575b600080fd5b34801561047657600080fd5b5061048a610485366004613b35565b610c51565b60405190151581526020015b60405180910390f35b3480156104ab57600080fd5b506104b4610cad565b6040516104969190613bc8565b3480156104cd57600080fd5b506104e16104dc366004613bdb565b610d3f565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610496565b34801561051257600080fd5b50610526610521366004613bdb565b610dea565b005b34801561053457600080fd5b50610526610543366004613c18565b610e56565b34801561055457600080fd5b50475b604051908152602001610496565b34801561057157600080fd5b50600254610557565b34801561058657600080fd5b5061048a610595366004613d25565b610faf565b3480156105a657600080fd5b50610557600f5481565b3480156105bc57600080fd5b506105266105cb366004613d73565b611081565b3480156105dc57600080fd5b506015546016541061048a565b6105266105f7366004613dbd565b611108565b34801561060857600080fd5b50610526610617366004613bdb565b611468565b34801561062857600080fd5b50610557610637366004613c18565b6114d4565b34801561064857600080fd5b50610526610657366004613e18565b6115f0565b6105266116e5565b34801561067057600080fd5b506104e1738430e0b7be3315735c303b82e4471d59ac152aa581565b34801561069857600080fd5b506105266106a7366004613d73565b6117be565b3480156106b857600080fd5b506105576106c7366004613bdb565b6117d9565b3480156106d857600080fd5b506361e4a37042101561048a565b3480156106f257600080fd5b50610526610701366004613e3a565b611836565b34801561071257600080fd5b5061055760155481565b34801561072857600080fd5b50610557600b5481565b34801561073e57600080fd5b50601a5461048a9060ff1681565b34801561075857600080fd5b5061055760095481565b34801561076e57600080fd5b506104e161077d366004613bdb565b6118b0565b34801561078e57600080fd5b506104b461195d565b3480156107a357600080fd5b506105266107b2366004613bdb565b6119eb565b3480156107c357600080fd5b506105576107d2366004613bdb565b611a57565b3480156107e357600080fd5b506105576107f2366004613bdb565b611af0565b34801561080357600080fd5b50610557610812366004613e83565b611b32565b34801561082357600080fd5b50610526611c31565b34801561083857600080fd5b50610526610847366004613bdb565b611ca4565b34801561085857600080fd5b5061055760195481565b34801561086e57600080fd5b5061052661087d366004613bdb565b611d10565b34801561088e57600080fd5b506108a261089d366004613e83565b611fbc565b6040516104969190613e9e565b3480156108bb57600080fd5b5061055760125481565b3480156108d157600080fd5b50601e54610557565b3480156108e657600080fd5b5061055760165481565b3480156108fc57600080fd5b5061052661090b366004613ee2565b6120b6565b34801561091c57600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff166104e1565b34801561094757600080fd5b50610526610956366004613bdb565b61214e565b34801561096757600080fd5b506105576361e4a37081565b34801561097f57600080fd5b5061052661098e366004613e18565b6121ba565b34801561099f57600080fd5b506104b4612249565b3480156109b457600080fd5b50610557600d5481565b3480156109ca57600080fd5b50610557600e5481565b3480156109e057600080fd5b50610557612258565b3480156109f557600080fd5b5061055760135481565b348015610a0b57600080fd5b50610a1461226d565b6040516104969190613eff565b348015610a2d57600080fd5b50610526610a3c366004613f4d565b6122db565b348015610a4d57600080fd5b506105266123d8565b348015610a6257600080fd5b5061055762d5ec1f81565b348015610a7957600080fd5b5061055760115481565b348015610a8f57600080fd5b50610526610a9e366004613bdb565b6125d7565b348015610aaf57600080fd5b50610526610abe366004613f84565b612643565b348015610acf57600080fd5b506105266126d1565b348015610ae457600080fd5b50610526610af3366004614038565b61284f565b348015610b0457600080fd5b50601454610557565b348015610b1957600080fd5b506104b4610b28366004613bdb565b612ae6565b348015610b3957600080fd5b50610557600c5481565b348015610b4f57600080fd5b50601654610557565b348015610b6457600080fd5b5061055760175481565b348015610b7a57600080fd5b50610557600a5481565b348015610b9057600080fd5b5061055760105481565b348015610ba657600080fd5b5061048a610bb53660046140a4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260046020908152604080832093909416825291909152205460ff1690565b348015610bfc57600080fd5b50610526610c0b366004613e83565b612bbf565b348015610c1c57600080fd5b50601354610557565b348015610c3157600080fd5b5061055760145481565b348015610c4757600080fd5b5061055760185481565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610ca75750610ca782612cb8565b92915050565b606060008054610cbc906140d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610ce8906140d7565b8015610d355780601f10610d0a57610100808354040283529160200191610d35565b820191906000526020600020905b815481529060010190602001808311610d1857829003601f168201915b5050505050905090565b6000610d4a82612d9b565b610dc15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601955565b6000610e61826118b0565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f055760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610db8565b3373ffffffffffffffffffffffffffffffffffffffff82161480610f2e5750610f2e8133610bb5565b610fa05760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610db8565b610faa8383612dff565b505050565b604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b16602080830191909152825180830360140181526034830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060548401526070808401829052845180850390910181526090909301909352815191012060009190738430e0b7be3315735c303b82e4471d59ac152aa56110618286612e9f565b73ffffffffffffffffffffffffffffffffffffffff161495945050505050565b61108b3382612f3c565b6110fd5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610db8565b610faa838383613078565b6002600654141561115b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610db8565b60026006556361e4a3704210156111b45760405162461bcd60e51b815260206004820152601460248201527f53616c6520686173206e6f7420737461727465640000000000000000000000006044820152606401610db8565b60006111bf60025490565b601a5490915060ff16156112155760405162461bcd60e51b815260206004820152600b60248201527f53616c65205061757365640000000000000000000000000000000000000000006044820152606401610db8565b60008411801561122757506019548411155b6112735760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206e756d6265724f664e6674730000000000000000000000006044820152606401610db8565b601854601754611283919061415a565b61128d8583614171565b11156112db5760405162461bcd60e51b815260206004820152601260248201527f45786365656473204d617820537570706c7900000000000000000000000000006044820152606401610db8565b81156113c157601554601654106112f157600080fd5b836014546112ff9190614189565b34101561134e5760405162461bcd60e51b815260206004820152600e60248201527f4e6f7420456e6f756768204554480000000000000000000000000000000000006044820152606401610db8565b6113583384610faf565b6113a45760405162461bcd60e51b815260206004820152601760248201527f41646472657373206e6f742077686974656c69737465640000000000000000006044820152606401610db8565b83601660008282546113b69190614171565b9091555061141e9050565b836013546113cf9190614189565b34101561141e5760405162461bcd60e51b815260206004820152600e60248201527f4e6f7420456e6f756768204554480000000000000000000000000000000000006044820152606401610db8565b60005b8481101561145c5761144c336114378385614171565b60405180602001604052806000815250613247565b611455816141c6565b9050611421565b50506001600655505050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146114cf5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601855565b60006114df83611b32565b821061152d5760405162461bcd60e51b815260206004820152601660248201527f455243373231456e756d3a206f776e657220696f6f62000000000000000000006044820152606401610db8565b6000805b6002548110156115a7576002818154811061154e5761154e6141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff86811691161415611597578382141561158b579150610ca79050565b611594826141c6565b91505b6115a0816141c6565b9050611531565b5060405162461bcd60e51b815260206004820152601660248201527f455243373231456e756d3a206f776e657220696f6f62000000000000000000006044820152606401610db8565b60055473ffffffffffffffffffffffffffffffffffffffff1633146116575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b600082118015611668575060038211155b6116b45760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420647261774e756d6265723a206d75737420626520312d33006044820152606401610db8565b81600114156116c357600b5550565b81600214156116d257600c5550565b81600314156116e157600d8190555b5050565b60055473ffffffffffffffffffffffffffffffffffffffff16331461174c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b6040514790600090339083908381818185875af1925050503d8060008114611790576040519150601f19603f3d011682016040523d82523d6000602084013e611795565b606091505b50509050806117a357600080fd5b81601e60008282546117b59190614171565b90915550505050565b610faa83838360405180602001604052806000815250612643565b60006117e460025490565b82106118325760405162461bcd60e51b815260206004820152601760248201527f455243373231456e756d3a20676c6f62616c20696f6f620000000000000000006044820152606401610db8565b5090565b60055473ffffffffffffffffffffffffffffffffffffffff16331461189d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b80516116e1906008906020840190613a77565b600080600283815481106118c6576118c66141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080610ca75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610db8565b6008805461196a906140d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611996906140d7565b80156119e35780601f106119b8576101008083540402835291602001916119e3565b820191906000526020600020905b8154815290600101906020018083116119c657829003601f168201915b505050505081565b60055473ffffffffffffffffffffffffffffffffffffffff163314611a525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601755565b60008082118015611a69575060038211155b611ab55760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420647261774e756d6265723a206d75737420626520312d33006044820152606401610db8565b8160011415611ac6575050600b5490565b8160021415611ad7575050600c5490565b8160031415611ae8575050600d5490565b506000919050565b60008160011415611b0357505060105490565b8160021415611b1457505060115490565b8160031415611b2557505060125490565b5050600f5490565b919050565b600073ffffffffffffffffffffffffffffffffffffffff8216611bbd5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610db8565b600254600090815b81811015611c285760028181548110611be057611be06141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff86811691161415611c1857611c15836141c6565b92505b611c21816141c6565b9050611bc5565b50909392505050565b60055473ffffffffffffffffffffffffffffffffffffffff163314611c985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b611ca260006132d0565b565b60055473ffffffffffffffffffffffffffffffffffffffff163314611d0b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601455565b60055473ffffffffffffffffffffffffffffffffffffffff163314611d775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b600a546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca73ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e28919061422e565b1015611e765760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e7472616374006044820152606401610db8565b600081118015611e87575060038111155b611ed35760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420647261774e756d6265723a206d75737420626520312d33006044820152606401610db8565b43611edd82611a57565b1115611f2b5760405162461bcd60e51b815260206004820152601b60248201527f5072697a6520626c6f636b206e6f7420726561636865642079657400000000006044820152606401610db8565b611f3481611af0565b15611fa75760405162461bcd60e51b815260206004820152602a60248201527f52616e646f6d6e65737320616c72656164792067656e65726174656420666f7260448201527f20746869732064726177000000000000000000000000000000000000000000006064820152608401610db8565b80600e819055506116e1600954600a54613347565b6060611fc782611b32565b6000106120165760405162461bcd60e51b815260206004820152601660248201527f455243373231456e756d3a206f776e657220696f6f62000000000000000000006044820152606401610db8565b600061202183611b32565b905060008167ffffffffffffffff81111561203e5761203e613c42565b604051908082528060200260200182016040528015612067578160200160208202803683370190505b50905060005b828110156120ae5761207f85826114d4565b828281518110612091576120916141ff565b6020908102919091010152806120a6816141c6565b91505061206d565b509392505050565b60055473ffffffffffffffffffffffffffffffffffffffff16331461211d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60055473ffffffffffffffffffffffffffffffffffffffff1633146121b55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601355565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952161461223f5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610db8565b6116e182826134d0565b606060018054610cbc906140d7565b600047601e546122689190614171565b905090565b60606002805480602002602001604051908101604052809291908181526020018280548015610d3557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116122a7575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff82163314156123415760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610db8565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff16331461243f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca73ffffffffffffffffffffffffffffffffffffffff169063a9059cbb90339083906370a0823190602401602060405180830381865afa1580156124d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f7919061422e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff909216600483015260248201526044016020604051808303816000875af1158015612567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258b9190614247565b611ca25760405162461bcd60e51b815260206004820152601260248201527f556e61626c6520746f207472616e7366657200000000000000000000000000006044820152606401610db8565b60055473ffffffffffffffffffffffffffffffffffffffff16331461263e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b601555565b61264d3383612f3c565b6126bf5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610db8565b6126cb84848484613509565b50505050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146127385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b600a546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca73ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e9919061422e565b10156128375760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e7472616374006044820152606401610db8565b6000600e55600954600a5461284c9190613347565b50565b60055473ffffffffffffffffffffffffffffffffffffffff1633146128b65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b82811461292b5760405162461bcd60e51b815260206004820152603360248201527f496e76616c6964207175616e74697469657320616e6420726563697069656e7460448201527f7320286c656e677468206d69736d6174636829000000000000000000000000006064820152608401610db8565b60008061293760025490565b905060005b8581101561297a57868682818110612956576129566141ff565b90506020020135836129689190614171565b9250612973816141c6565b905061293c565b506017546129888383614171565b11156129d65760405162461bcd60e51b815260206004820152601260248201527f45786365656473204d617820537570706c7900000000000000000000000000006044820152606401610db8565b601854821115612a285760405162461bcd60e51b815260206004820152601460248201527f45786365656473204d61782052657365727665640000000000000000000000006044820152606401610db8565b8160186000828254612a3a919061415a565b90915550600092508290505b83811015612add5760005b878783818110612a6357612a636141ff565b90506020020135811015612acc57612abc868684818110612a8657612a866141ff565b9050602002016020810190612a9b9190613e83565b84612aa5816141c6565b955060405180602001604052806000815250613247565b612ac5816141c6565b9050612a51565b50612ad6816141c6565b9050612a46565b50505050505050565b6060612af182612d9b565b612b635760405162461bcd60e51b815260206004820152602160248201527f4552433732314d657461646174613a204e6f6e6578697374656e7420746f6b6560448201527f6e000000000000000000000000000000000000000000000000000000000000006064820152608401610db8565b6000612b6d613592565b90506000815111612b8d5760405180602001604052806000815250612bb8565b80612b97846135a1565b604051602001612ba8929190614264565b6040516020818303038152906040525b9392505050565b60055473ffffffffffffffffffffffffffffffffffffffff163314612c265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db8565b73ffffffffffffffffffffffffffffffffffffffff8116612caf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610db8565b61284c816132d0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480612d4b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610ca757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610ca7565b60025460009082108015610ca75750600073ffffffffffffffffffffffffffffffffffffffff1660028381548110612dd557612dd56141ff565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141592915050565b600081815260036020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190612e59826118b0565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080600080612eae856136d3565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015612f09573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b6000612f4782612d9b565b612fb95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610db8565b6000612fc4836118b0565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061303357508373ffffffffffffffffffffffffffffffffffffffff1661301b84610d3f565b73ffffffffffffffffffffffffffffffffffffffff16145b80613070575073ffffffffffffffffffffffffffffffffffffffff80821660009081526004602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16613098826118b0565b73ffffffffffffffffffffffffffffffffffffffff16146131215760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610db8565b73ffffffffffffffffffffffffffffffffffffffff82166131a95760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610db8565b6131b4600082612dff565b81600282815481106131c8576131c86141ff565b6000918252602082200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff938416179055604051839285811692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a4505050565b6132518383613747565b61325e60008484846138a1565b610faa5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610db8565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca73ffffffffffffffffffffffffffffffffffffffff16634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952848660006040516020016133c4929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016133f193929190614293565b6020604051808303816000875af1158015613410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134349190614247565b50600083815260076020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052613490906001614171565b6000858152600760205260409020556130708482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600e54600114156134e15760105550565b600e54600214156134f25760115550565b600e54600314156135035760125550565b600f5550565b613514848484613078565b613520848484846138a1565b6126cb5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610db8565b606060088054610cbc906140d7565b6060816135e157505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561360b57806135f5816141c6565b91506136049050600a83614300565b91506135e5565b60008167ffffffffffffffff81111561362657613626613c42565b6040519080825280601f01601f191660200182016040528015613650576020820181803683370190505b5090505b84156130705761366560018361415a565b9150613672600a86614314565b61367d906030614171565b60f81b818381518110613692576136926141ff565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506136cc600a86614300565b9450613654565b600080600083516041146137295760405162461bcd60e51b815260206004820152601860248201527f696e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610db8565b50505060208101516040820151606090920151909260009190911a90565b73ffffffffffffffffffffffffffffffffffffffff82166137aa5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610db8565b6137b381612d9b565b156138005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610db8565b6002805460018101825560009182527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600073ffffffffffffffffffffffffffffffffffffffff84163b15613a6c576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290613918903390899088908890600401614328565b6020604051808303816000875af1925050508015613971575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261396e91810190614371565b60015b613a21573d80801561399f576040519150601f19603f3d011682016040523d82523d6000602084013e6139a4565b606091505b508051613a195760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610db8565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050613070565b506001949350505050565b828054613a83906140d7565b90600052602060002090601f016020900481019282613aa55760008555613aeb565b82601f10613abe57805160ff1916838001178555613aeb565b82800160010185558215613aeb579182015b82811115613aeb578251825591602001919060010190613ad0565b506118329291505b808211156118325760008155600101613af3565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461284c57600080fd5b600060208284031215613b4757600080fd5b8135612bb881613b07565b60005b83811015613b6d578181015183820152602001613b55565b838111156126cb5750506000910152565b60008151808452613b96816020860160208601613b52565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612bb86020830184613b7e565b600060208284031215613bed57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b2d57600080fd5b60008060408385031215613c2b57600080fd5b613c3483613bf4565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115613c8c57613c8c613c42565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613cd257613cd2613c42565b81604052809350858152868686011115613ceb57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112613d1657600080fd5b612bb883833560208501613c71565b60008060408385031215613d3857600080fd5b613d4183613bf4565b9150602083013567ffffffffffffffff811115613d5d57600080fd5b613d6985828601613d05565b9150509250929050565b600080600060608486031215613d8857600080fd5b613d9184613bf4565b9250613d9f60208501613bf4565b9150604084013590509250925092565b801515811461284c57600080fd5b600080600060608486031215613dd257600080fd5b83359250602084013567ffffffffffffffff811115613df057600080fd5b613dfc86828701613d05565b9250506040840135613e0d81613daf565b809150509250925092565b60008060408385031215613e2b57600080fd5b50508035926020909101359150565b600060208284031215613e4c57600080fd5b813567ffffffffffffffff811115613e6357600080fd5b8201601f81018413613e7457600080fd5b61307084823560208401613c71565b600060208284031215613e9557600080fd5b612bb882613bf4565b6020808252825182820181905260009190848201906040850190845b81811015613ed657835183529284019291840191600101613eba565b50909695505050505050565b600060208284031215613ef457600080fd5b8135612bb881613daf565b6020808252825182820181905260009190848201906040850190845b81811015613ed657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613f1b565b60008060408385031215613f6057600080fd5b613f6983613bf4565b91506020830135613f7981613daf565b809150509250929050565b60008060008060808587031215613f9a57600080fd5b613fa385613bf4565b9350613fb160208601613bf4565b925060408501359150606085013567ffffffffffffffff811115613fd457600080fd5b613fe087828801613d05565b91505092959194509250565b60008083601f840112613ffe57600080fd5b50813567ffffffffffffffff81111561401657600080fd5b6020830191508360208260051b850101111561403157600080fd5b9250929050565b6000806000806040858703121561404e57600080fd5b843567ffffffffffffffff8082111561406657600080fd5b61407288838901613fec565b9096509450602087013591508082111561408b57600080fd5b5061409887828801613fec565b95989497509550505050565b600080604083850312156140b757600080fd5b6140c083613bf4565b91506140ce60208401613bf4565b90509250929050565b600181811c908216806140eb57607f821691505b60208210811415614125577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561416c5761416c61412b565b500390565b600082198211156141845761418461412b565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141c1576141c161412b565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156141f8576141f861412b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561424057600080fd5b5051919050565b60006020828403121561425957600080fd5b8151612bb881613daf565b60008351614276818460208801613b52565b83519083019061428a818360208801613b52565b01949350505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006142c86060830184613b7e565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261430f5761430f6142d1565b500490565b600082614323576143236142d1565b500690565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526143676080830184613b7e565b9695505050505050565b60006020828403121561438357600080fd5b8151612bb881613b0756fea2646970667358221220d989eba8ac61668c370c69a1da2341d2a7d7acb99197910b02453e2096ff7c6d64736f6c634300080b0033

Deployed Bytecode Sourcemap

365:12041:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;191:301:3;;;;;;;;;;-1:-1:-1;191:301:3;;;;;:::i;:::-;;:::i;:::-;;;611:14:17;;604:22;586:41;;574:2;559:18;191:301:3;;;;;;;;2021:100:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;2661:308::-;;;;;;;;;;-1:-1:-1;2661:308:4;;;;;:::i;:::-;;:::i;:::-;;;1809:42:17;1797:55;;;1779:74;;1767:2;1752:18;2661:308:4;1633:226:17;10611:116:5;;;;;;;;;;-1:-1:-1;10611:116:5;;;;;:::i;:::-;;:::i;:::-;;2241:412:4;;;;;;;;;;-1:-1:-1;2241:412:4;;;;;:::i;:::-;;:::i;11562:104:5:-;;;;;;;;;;-1:-1:-1;11637:21:5;11562:104;;;2470:25:17;;;2458:2;2443:18;11562:104:5;2324:177:17;1470:110:3;;;;;;;;;;-1:-1:-1;1558:7:3;:14;1470:110;;6436:364:5;;;;;;;;;;-1:-1:-1;6436:364:5;;;;;:::i;:::-;;:::i;1303:37::-;;;;;;;;;;;;;;;;3534:376:4;;;;;;;;;;-1:-1:-1;3534:376:4;;;;;:::i;:::-;;:::i;5960:117:5:-;;;;;;;;;;-1:-1:-1;6051:18:5;;6033:15;;:36;5960:117;;7424:1133;;;;;;:::i;:::-;;:::i;10981:102::-;;;;;;;;;;-1:-1:-1;10981:102:5;;;;;:::i;:::-;;:::i;500:504:3:-;;;;;;;;;;-1:-1:-1;500:504:3;;;;;:::i;:::-;;:::i;9954:435:5:-;;;;;;;;;;-1:-1:-1;9954:435:5;;;;;:::i;:::-;;:::i;11885:273::-;;;:::i;1990:85::-;;;;;;;;;;;;2033:42;1990:85;;3918:185:4;;;;;;;;;;-1:-1:-1;3918:185:4;;;;;:::i;:::-;;:::i;1588:244:3:-;;;;;;;;;;-1:-1:-1;1588:244:3;;;;;:::i;:::-;;:::i;5722:121:5:-;;;;;;;;;;-1:-1:-1;1550:10:5;5796:15;:39;;5722:121;;11091:104;;;;;;;;;;-1:-1:-1;11091:104:5;;;;;:::i;:::-;;:::i;1703:40::-;;;;;;;;;;;;;;;;828:54;;;;;;;;;;;;;;;;1933:30;;;;;;;;;;-1:-1:-1;1933:30:5;;;;;;;;536:91;;;;;;;;;;;;;;;;1687:326:4;;;;;;;;;;-1:-1:-1;1687:326:4;;;;;:::i;:::-;;:::i;480:21:5:-;;;;;;;;;;;;;:::i;10735:106::-;;;;;;;;;;-1:-1:-1;10735:106:5;;;;;:::i;:::-;;:::i;3641:434::-;;;;;;;;;;-1:-1:-1;3641:434:5;;;;;:::i;:::-;;:::i;3100:405::-;;;;;;;;;;-1:-1:-1;3100:405:5;;;;;:::i;:::-;;:::i;1161:518:4:-;;;;;;;;;;-1:-1:-1;1161:518:4;;;;;:::i;:::-;;:::i;1661:101:12:-;;;;;;;;;;;;;:::i;10495:108:5:-;;;;;;;;;;-1:-1:-1;10495:108:5;;;;;:::i;:::-;;:::i;1899:27::-;;;;;;;;;;;;;;;;4273:680;;;;;;;;;;-1:-1:-1;4273:680:5;;;;;:::i;:::-;;:::i;1012:450:3:-;;;;;;;;;;-1:-1:-1;1012:450:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1433:36:5:-;;;;;;;;;;;;;;;;11455:99;;;;;;;;;;-1:-1:-1;11532:14:5;;11455:99;;1750:34;;;;;;;;;;;;;;;;11203:101;;;;;;;;;;-1:-1:-1;11203:101:5;;;;;:::i;:::-;;:::i;1029:85:12:-;;;;;;;;;;-1:-1:-1;1101:6:12;;;;1029:85;;10397:90:5;;;;;;;;;;-1:-1:-1;10397:90:5;;;;;:::i;:::-;;:::i;1503:57::-;;;;;;;;;;;;1550:10;1503:57;;9628:225:15;;;;;;;;;;-1:-1:-1;9628:225:15;;;;;:::i;:::-;;:::i;2129:104:4:-;;;;;;;;;;;;;:::i;1010:54:5:-;;;;;;;;;;;;;;;;1201:36;;;;;;;;;;;;;;;;11674:121;;;;;;;;;;;;;:::i;1614:33::-;;;;;;;;;;;;;;;;695:95:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;2977:327::-;;;;;;;;;;-1:-1:-1;2977:327:4;;;;;:::i;:::-;;:::i;12256:147:5:-;;;;;;;;;;;;;:::i;737:51::-;;;;;;;;;;;;780:8;737:51;;1390:36;;;;;;;;;;;;;;;;10849:124;;;;;;;;;;-1:-1:-1;10849:124:5;;;;;:::i;:::-;;:::i;4111:365:4:-;;;;;;;;;;-1:-1:-1;4111:365:4;;;;;:::i;:::-;;:::i;2607:375:5:-;;;;;;;;;;;;;:::i;8605:863::-;;;;;;;;;;-1:-1:-1;8605:863:5;;;;;:::i;:::-;;:::i;6301:102::-;;;;;;;;;;-1:-1:-1;6381:14:5;;6301:102;;9476:339;;;;;;;;;;-1:-1:-1;9476:339:5;;;;;:::i;:::-;;:::i;919:54::-;;;;;;;;;;;;;;;;5851:101;;;;;;;;;;-1:-1:-1;5929:15:5;;5851:101;;1791:31;;;;;;;;;;;;;;;;634:33;;;;;;;;;;;;;;;;1347:36;;;;;;;;;;;;;;;;3312:214:4;;;;;;;;;;-1:-1:-1;3312:214:4;;;;;:::i;:::-;3483:25;;;;3454:4;3483:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;3312:214;1911:198:12;;;;;;;;;;-1:-1:-1;1911:198:12;;;;;:::i;:::-;;:::i;6143:84:5:-;;;;;;;;;;-1:-1:-1;6214:5:5;;6143:84;;1654:42;;;;;;;;;;;;;;;;1829:28;;;;;;;;;;;;;;;;191:301:3;339:4;381:50;;;396:35;381:50;;:103;;;448:36;472:11;448:23;:36::i;:::-;361:123;191:301;-1:-1:-1;;191:301:3:o;2021:100:4:-;2075:13;2108:5;2101:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2021:100;:::o;2661:308::-;2782:7;2829:16;2837:7;2829;:16::i;:::-;2807:110;;;;-1:-1:-1;;;2807:110:4;;10816:2:17;2807:110:4;;;10798:21:17;10855:2;10835:18;;;10828:30;10894:34;10874:18;;;10867:62;10965:14;10945:18;;;10938:42;10997:19;;2807:110:4;;;;;;;;;-1:-1:-1;2937:24:4;;;;:15;:24;;;;;;;;;2661:308::o;10611:116:5:-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;10692:7:5::1;:27:::0;10611:116::o;2241:412:4:-;2322:13;2338:24;2354:7;2338:15;:24::i;:::-;2322:40;;2387:5;2381:11;;:2;:11;;;;2373:57;;;;-1:-1:-1;;;2373:57:4;;11590:2:17;2373:57:4;;;11572:21:17;11629:2;11609:18;;;11602:30;11668:34;11648:18;;;11641:62;11739:3;11719:18;;;11712:31;11760:19;;2373:57:4;11388:397:17;2373:57:4;719:10:1;2465:21:4;;;;;:62;;-1:-1:-1;2490:37:4;2507:5;719:10:1;3312:214:4;:::i;2490:37::-;2443:168;;;;-1:-1:-1;;;2443:168:4;;11992:2:17;2443:168:4;;;11974:21:17;12031:2;12011:18;;;12004:30;12070:34;12050:18;;;12043:62;12141:26;12121:18;;;12114:54;12185:19;;2443:168:4;11790:420:17;2443:168:4;2624:21;2633:2;2637:7;2624:8;:21::i;:::-;2311:342;2241:412;;:::o;6436:364:5:-;6567:22;;;12377:66:17;12364:2;12360:15;;;12356:88;6567:22:5;;;;12344:101:17;;;;6567:22:5;;;;;;;;;12461:12:17;;;6567:22:5;;6557:33;;;;;;12726:66:17;6642:65:5;;;12714:79:17;12809:12;;;;12802:28;;;6642:65:5;;;;;;;;;;12846:12:17;;;;6642:65:5;;;6632:76;;;;;-1:-1:-1;;6557:33:5;2033:42;6726:46;6632:76;6762:9;6726:13;:46::i;:::-;:66;;;;6436:364;-1:-1:-1;;;;;6436:364:5:o;3534:376:4:-;3743:41;719:10:1;3776:7:4;3743:18;:41::i;:::-;3721:140;;;;-1:-1:-1;;;3721:140:4;;13071:2:17;3721:140:4;;;13053:21:17;13110:2;13090:18;;;13083:30;13149:34;13129:18;;;13122:62;13220:19;13200:18;;;13193:47;13257:19;;3721:140:4;12869:413:17;3721:140:4;3874:28;3884:4;3890:2;3894:7;3874:9;:28::i;7424:1133:5:-;1744:1:13;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:13;;13489:2:17;2317:63:13;;;13471:21:17;13528:2;13508:18;;;13501:30;13567:33;13547:18;;;13540:61;13618:18;;2317:63:13;13287:355:17;2317:63:13;1744:1;2455:7;:18;1550:10:5::1;7550:15;:39;;7542:72;;;::::0;-1:-1:-1;;;7542:72:5;;13849:2:17;7542:72:5::1;::::0;::::1;13831:21:17::0;13888:2;13868:18;;;13861:30;13927:22;13907:18;;;13900:50;13967:18;;7542:72:5::1;13647:344:17::0;7542:72:5::1;7625:9;7637:13;1558:7:3::0;:14;;1470:110;7637:13:5::1;7670:10;::::0;7625:25;;-1:-1:-1;7670:10:5::1;;7669:11;7661:35;;;::::0;-1:-1:-1;;;7661:35:5;;14198:2:17;7661:35:5::1;::::0;::::1;14180:21:17::0;14237:2;14217:18;;;14210:30;14276:13;14256:18;;;14249:41;14307:18;;7661:35:5::1;13996:335:17::0;7661:35:5::1;7730:1;7715:12;:16;:43;;;;;7751:7;;7735:12;:23;;7715:43;7707:76;;;::::0;-1:-1:-1;;;7707:76:5;;14538:2:17;7707:76:5::1;::::0;::::1;14520:21:17::0;14577:2;14557:18;;;14550:30;14616:22;14596:18;;;14589:50;14656:18;;7707:76:5::1;14336:344:17::0;7707:76:5::1;7837:8;;7825:9;;:20;;;;:::i;:::-;7803:16;7807:12:::0;7803:1;:16:::1;:::i;:::-;7802:44;;7794:75;;;::::0;-1:-1:-1;;;7794:75:5;;15339:2:17;7794:75:5::1;::::0;::::1;15321:21:17::0;15378:2;15358:18;;;15351:30;15417:20;15397:18;;;15390:48;15455:18;;7794:75:5::1;15137:342:17::0;7794:75:5::1;7970:9;7967:452;;;8022:18;;8004:15;;:36;7996:45;;;::::0;::::1;;8094:12;8077:14;;:29;;;;:::i;:::-;8064:9;:42;;8056:69;;;::::0;-1:-1:-1;;;8056:69:5;;15919:2:17;8056:69:5::1;::::0;::::1;15901:21:17::0;15958:2;15938:18;;;15931:30;15997:16;15977:18;;;15970:44;16031:18;;8056:69:5::1;15717:338:17::0;8056:69:5::1;8148:36;8162:10;8174:9;8148:13;:36::i;:::-;8140:72;;;::::0;-1:-1:-1;;;8140:72:5;;16262:2:17;8140:72:5::1;::::0;::::1;16244:21:17::0;16301:2;16281:18;;;16274:30;16340:25;16320:18;;;16313:53;16383:18;;8140:72:5::1;16060:347:17::0;8140:72:5::1;8246:12;8227:15;;:31;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;7967:452:5::1;::::0;-1:-1:-1;7967:452:5::1;;8376:12;8368:5;;:20;;;;:::i;:::-;8355:9;:33;;8347:60;;;::::0;-1:-1:-1;;;8347:60:5;;15919:2:17;8347:60:5::1;::::0;::::1;15901:21:17::0;15958:2;15938:18;;;15931:30;15997:16;15977:18;;;15970:44;16031:18;;8347:60:5::1;15717:338:17::0;8347:60:5::1;8434:9;8429:102;8453:12;8449:1;:16;8429:102;;;8487:32;8497:10;8509:5;8513:1:::0;8509;:5:::1;:::i;:::-;8487:32;;;;;;;;;;;::::0;:9:::1;:32::i;:::-;8467:3;::::0;::::1;:::i;:::-;;;8429:102;;;-1:-1:-1::0;;1701:1:13;2628:7;:22;-1:-1:-1;;;7424:1133:5:o;10981:102::-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;11052:8:5::1;:23:::0;10981:102::o;500:504:3:-;625:15;674:24;692:5;674:17;:24::i;:::-;666:5;:32;658:67;;;;-1:-1:-1;;;658:67:3;;16814:2:17;658:67:3;;;16796:21:17;16853:2;16833:18;;;16826:30;16892:24;16872:18;;;16865:52;16934:18;;658:67:3;16612:346:17;658:67:3;736:13;765:9;760:186;780:7;:14;776:18;;760:186;;;829:7;837:1;829:10;;;;;;;;:::i;:::-;;;;;;;;;;;;820:19;;;829:10;;820:19;816:119;;;873:5;864;:14;860:59;;;887:1;-1:-1:-1;880:8:3;;-1:-1:-1;880:8:3;860:59;912:7;;;:::i;:::-;;;860:59;796:3;;;:::i;:::-;;;760:186;;;-1:-1:-1;956:40:3;;-1:-1:-1;;;956:40:3;;16814:2:17;956:40:3;;;16796:21:17;16853:2;16833:18;;;16826:30;16892:24;16872:18;;;16865:52;16934:18;;956:40:3;16612:346:17;9954:435:5;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;10066:1:5::1;10053:10;:14;:33;;;;;10085:1;10071:10;:15;;10053:33;10045:77;;;::::0;-1:-1:-1;;;10045:77:5;;17354:2:17;10045:77:5::1;::::0;::::1;17336:21:17::0;17393:2;17373:18;;;17366:30;17432:33;17412:18;;;17405:61;17483:18;;10045:77:5::1;17152:355:17::0;10045:77:5::1;10136:10;10150:1;10136:15;10133:249;;;10168:12;:26:::0;-1:-1:-1;9954:435:5:o;10133:249::-:1;10224:10;10238:1;10224:15;10221:161;;;10256:12;:26:::0;-1:-1:-1;9954:435:5:o;10221:161::-:1;10312:10;10326:1;10312:15;10309:73;;;10344:12;:26:::0;;;10309:73:::1;9954:435:::0;;:::o;11885:273::-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;12006:64:5::1;::::0;11955:21:::1;::::0;11941:11:::1;::::0;12014:10:::1;::::0;11955:21;;11941:11;12006:64;11941:11;12006:64;11955:21;12014:10;12006:64:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11987:83;;;12089:7;12081:16;;;::::0;::::1;;12126:3;12108:14;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;11885:273:5:o;3918:185:4:-;4056:39;4073:4;4079:2;4083:7;4056:39;;;;;;;;;;;;:16;:39::i;1588:244:3:-;1708:7;1749:24;1558:7;:14;;1470:110;1749:24;1741:5;:32;1733:68;;;;-1:-1:-1;;;1733:68:3;;17924:2:17;1733:68:3;;;17906:21:17;17963:2;17943:18;;;17936:30;18002:25;17982:18;;;17975:53;18045:18;;1733:68:3;17722:347:17;1733:68:3;-1:-1:-1;1819:5:3;1588:244::o;11091:104:5:-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;11166:21:5;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;1687:326:4:-:0;1804:7;1829:13;1845:7;1853;1845:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;1894:19:4;1872:110;;;;-1:-1:-1;;;1872:110:4;;18276:2:17;1872:110:4;;;18258:21:17;18315:2;18295:18;;;18288:30;18354:34;18334:18;;;18327:62;18425:11;18405:18;;;18398:39;18454:19;;1872:110:4;18074:405:17;480:21:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;10735:106::-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;10808:9:5::1;:25:::0;10735:106::o;3641:434::-;3713:7;3754:1;3741:10;:14;:33;;;;;3773:1;3759:10;:15;;3741:33;3733:77;;;;-1:-1:-1;;;3733:77:5;;17354:2:17;3733:77:5;;;17336:21:17;17393:2;17373:18;;;17366:30;17432:33;17412:18;;;17405:61;17483:18;;3733:77:5;17152:355:17;3733:77:5;3824:10;3838:1;3824:15;3821:228;;;-1:-1:-1;;3863:12:5;;;3641:434::o;3821:228::-;3905:10;3919:1;3905:15;3902:147;;;-1:-1:-1;;3944:12:5;;;3641:434::o;3902:147::-;3986:10;4000:1;3986:15;3983:66;;;-1:-1:-1;;4025:12:5;;;3641:434::o;3983:66::-;-1:-1:-1;4066:1:5;;3641:434;-1:-1:-1;3641:434:5:o;3100:405::-;3168:7;3191:10;3205:1;3191:15;3188:310;;;-1:-1:-1;;3230:17:5;;;3100:405::o;3188:310::-;3277:10;3291:1;3277:15;3274:224;;;-1:-1:-1;;3316:17:5;;;3100:405::o;3274:224::-;3363:10;3377:1;3363:15;3360:138;;;-1:-1:-1;;3402:17:5;;;3100:405::o;3360:138::-;-1:-1:-1;;3468:18:5;;;3100:405::o;3360:138::-;3100:405;;;:::o;1161:518:4:-;1278:7;1325:19;;;1303:111;;;;-1:-1:-1;;;1303:111:4;;18686:2:17;1303:111:4;;;18668:21:17;18725:2;18705:18;;;18698:30;18764:34;18744:18;;;18737:62;18835:12;18815:18;;;18808:40;18865:19;;1303:111:4;18484:406:17;1303:111:4;1470:7;:14;1425:13;;;1495:130;1519:6;1515:1;:10;1495:130;;;1560:7;1568:1;1560:10;;;;;;;;:::i;:::-;;;;;;;;;;;;1551:19;;;1560:10;;1551:19;1547:67;;;1591:7;;;:::i;:::-;;;1547:67;1527:3;;;:::i;:::-;;;1495:130;;;-1:-1:-1;1666:5:4;;1161:518;-1:-1:-1;;;1161:518:4:o;1661:101:12:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;1725:30:::1;1752:1;1725:18;:30::i;:::-;1661:101::o:0;10495:108:5:-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;10569:14:5::1;:26:::0;10495:108::o;4273:680::-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;4381:3:5::1;::::0;4348:29:::1;::::0;;;;4371:4:::1;4348:29;::::0;::::1;1779:74:17::0;4348:4:5::1;:14;;::::0;::::1;::::0;1752:18:17;;4348:29:5::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;4340:80;;;::::0;-1:-1:-1;;;4340:80:5;;19286:2:17;4340:80:5::1;::::0;::::1;19268:21:17::0;19325:2;19305:18;;;19298:30;19364:33;19344:18;;;19337:61;19415:18;;4340:80:5::1;19084:355:17::0;4340:80:5::1;4452:1;4439:10;:14;:33;;;;;4471:1;4457:10;:15;;4439:33;4431:77;;;::::0;-1:-1:-1;;;4431:77:5;;17354:2:17;4431:77:5::1;::::0;::::1;17336:21:17::0;17393:2;17373:18;;;17366:30;17432:33;17412:18;;;17405:61;17483:18;;4431:77:5::1;17152:355:17::0;4431:77:5::1;4564:12;4527:33;4549:10;4527:21;:33::i;:::-;:49;;4519:89;;;::::0;-1:-1:-1;;;4519:89:5;;19646:2:17;4519:89:5::1;::::0;::::1;19628:21:17::0;19685:2;19665:18;;;19658:30;19724:29;19704:18;;;19697:57;19771:18;;4519:89:5::1;19444:351:17::0;4519:89:5::1;4627:29;4645:10;4627:17;:29::i;:::-;:34:::0;4619:89:::1;;;::::0;-1:-1:-1;;;4619:89:5;;20002:2:17;4619:89:5::1;::::0;::::1;19984:21:17::0;20041:2;20021:18;;;20014:30;20080:34;20060:18;;;20053:62;20151:12;20131:18;;;20124:40;20181:19;;4619:89:5::1;19800:406:17::0;4619:89:5::1;4834:10;4814:17;:30;;;;4914:31;4932:7;;4941:3;;4914:17;:31::i;1012:450:3:-:0;1098:16;1144:24;1162:5;1144:17;:24::i;:::-;1140:1;:28;1132:63;;;;-1:-1:-1;;;1132:63:3;;16814:2:17;1132:63:3;;;16796:21:17;16853:2;16833:18;;;16826:30;16892:24;16872:18;;;16865:52;16934:18;;1132:63:3;16612:346:17;1132:63:3;1206:18;1227:16;1237:5;1227:9;:16::i;:::-;1206:37;;1254:25;1296:10;1282:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1282:25:3;;1254:53;;1323:9;1318:111;1342:10;1338:1;:14;1318:111;;;1388:29;1408:5;1415:1;1388:19;:29::i;:::-;1374:8;1383:1;1374:11;;;;;;;;:::i;:::-;;;;;;;;;;:43;1354:3;;;;:::i;:::-;;;;1318:111;;;-1:-1:-1;1446:8:3;1012:450;-1:-1:-1;;;1012:450:3:o;11203:101:5:-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;11272:10:5::1;:24:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;11203:101::o;10397:90::-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;10462:5:5::1;:17:::0;10397:90::o;9628:225:15:-;9738:10;:28;9752:14;9738:28;;9730:72;;;;-1:-1:-1;;;9730:72:15;;20413:2:17;9730:72:15;;;20395:21:17;20452:2;20432:18;;;20425:30;20491:33;20471:18;;;20464:61;20542:18;;9730:72:15;20211:355:17;9730:72:15;9808:40;9826:9;9837:10;9808:17;:40::i;2129:104:4:-;2185:13;2218:7;2211:14;;;;;:::i;11674:121:5:-;11721:7;11637:21;11532:14;;11748:39;;;;:::i;:::-;11741:46;;11674:121;:::o;695:95:4:-;739:16;775:7;768:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;695:95;:::o;2977:327::-;3112:24;;;719:10:1;3112:24:4;;3104:62;;;;-1:-1:-1;;;3104:62:4;;20773:2:17;3104:62:4;;;20755:21:17;20812:2;20792:18;;;20785:30;20851:27;20831:18;;;20824:55;20896:18;;3104:62:4;20571:349:17;3104:62:4;719:10:1;3179:32:4;;;;:18;:32;;;;;;;;;:42;;;;;;;;;;;;:53;;;;;;;;;;;;;3248:48;;586:41:17;;;3179:42:4;;719:10:1;3248:48:4;;559:18:17;3248:48:4;;;;;;;2977:327;;:::o;12256:147:5:-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;12342:29:5::1;::::0;;;;12365:4:::1;12342:29;::::0;::::1;1779:74:17::0;12316:4:5::1;:13;;::::0;::::1;::::0;12330:10:::1;::::0;12316:13;;12342:14:::1;::::0;1752:18:17;;12342:29:5::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12316:56;::::0;;::::1;::::0;;;;;;21129:42:17;21117:55;;;12316:56:5::1;::::0;::::1;21099:74:17::0;21189:18;;;21182:34;21072:18;;12316:56:5::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12308:87;;;::::0;-1:-1:-1;;;12308:87:5;;21679:2:17;12308:87:5::1;::::0;::::1;21661:21:17::0;21718:2;21698:18;;;21691:30;21757:20;21737:18;;;21730:48;21795:18;;12308:87:5::1;21477:342:17::0;10849:124:5;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;10931:18:5::1;:34:::0;10849:124::o;4111:365:4:-;4300:41;719:10:1;4333:7:4;4300:18;:41::i;:::-;4278:140;;;;-1:-1:-1;;;4278:140:4;;13071:2:17;4278:140:4;;;13053:21:17;13110:2;13090:18;;;13083:30;13149:34;13129:18;;;13122:62;13220:19;13200:18;;;13193:47;13257:19;;4278:140:4;12869:413:17;4278:140:4;4429:39;4443:4;4449:2;4453:7;4462:5;4429:13;:39::i;:::-;4111:365;;;;:::o;2607:375:5:-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;2702:3:5::1;::::0;2669:29:::1;::::0;;;;2692:4:::1;2669:29;::::0;::::1;1779:74:17::0;2669:4:5::1;:14;;::::0;::::1;::::0;1752:18:17;;2669:29:5::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;2661:80;;;::::0;-1:-1:-1;;;2661:80:5;;19286:2:17;2661:80:5::1;::::0;::::1;19268:21:17::0;19325:2;19305:18;;;19298:30;19364:33;19344:18;;;19337:61;19415:18;;2661:80:5::1;19084:355:17::0;2661:80:5::1;2872:1;2852:17;:21:::0;2961:7:::1;::::0;2970:3:::1;::::0;2943:31:::1;::::0;2961:7;2943:17:::1;:31::i;:::-;;2607:375::o:0;8605:863::-;1101:6:12;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;8719:35:5;;::::1;8711:99;;;::::0;-1:-1:-1;;;8711:99:5;;22026:2:17;8711:99:5::1;::::0;::::1;22008:21:17::0;22065:2;22045:18;;;22038:30;22104:34;22084:18;;;22077:62;22175:21;22155:18;;;22148:49;22214:19;;8711:99:5::1;21824:415:17::0;8711:99:5::1;8821:21;8857:9:::0;8869:13:::1;1558:7:3::0;:14;;1470:110;8869:13:5::1;8857:25;;8898:9;8893:101;8913:19:::0;;::::1;8893:101;;;8971:8;;8980:1;8971:11;;;;;;;:::i;:::-;;;;;;;8954:28;;;;;:::i;:::-;::::0;-1:-1:-1;8934:3:5::1;::::0;::::1;:::i;:::-;;;8893:101;;;-1:-1:-1::0;9033:9:5::1;::::0;9012:17:::1;9016:13:::0;9012:1;:17:::1;:::i;:::-;:30;;9004:61;;;::::0;-1:-1:-1;;;9004:61:5;;15339:2:17;9004:61:5::1;::::0;::::1;15321:21:17::0;15378:2;15358:18;;;15351:30;15417:20;15397:18;;;15390:48;15455:18;;9004:61:5::1;15137:342:17::0;9004:61:5::1;9101:8;;9084:13;:25;;9076:58;;;::::0;-1:-1:-1;;;9076:58:5;;22446:2:17;9076:58:5::1;::::0;::::1;22428:21:17::0;22485:2;22465:18;;;22458:30;22524:22;22504:18;;;22497:50;22564:18;;9076:58:5::1;22244:344:17::0;9076:58:5::1;9203:13;9191:8;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;9229:20:5::1;::::0;-1:-1:-1;9229:20:5;;-1:-1:-1;9260:182:5::1;9280:20:::0;;::::1;9260:182;;;9327:9;9322:109;9346:8;;9355:1;9346:11;;;;;;;:::i;:::-;;;;;;;9342:1;:15;9322:109;;;9383:32;9393:9;;9403:1;9393:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9407:3:::0;::::1;::::0;::::1;:::i;:::-;;;9383:32;;;;;;;;;;;::::0;:9:::1;:32::i;:::-;9359:3;::::0;::::1;:::i;:::-;;;9322:109;;;-1:-1:-1::0;9302:3:5::1;::::0;::::1;:::i;:::-;;;9260:182;;;-1:-1:-1::0;;;;;;;8605:863:5:o;9476:339::-;9549:13;9583:16;9591:7;9583;:16::i;:::-;9575:62;;;;-1:-1:-1;;;9575:62:5;;22795:2:17;9575:62:5;;;22777:21:17;22834:2;22814:18;;;22807:30;22873:34;22853:18;;;22846:62;22944:3;22924:18;;;22917:31;22965:19;;9575:62:5;22593:397:17;9575:62:5;9648:28;9679:10;:8;:10::i;:::-;9648:41;;9738:1;9713:14;9707:28;:32;:100;;;;;;;;;;;;;;;;;9766:14;9782:18;:7;:16;:18::i;:::-;9749:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;9707:100;9700:107;9476:339;-1:-1:-1;;;9476:339:5:o;1911:198:12:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:12;1233:68;;;;-1:-1:-1;;;1233:68:12;;11229:2:17;1233:68:12;;;11211:21:17;;;11248:18;;;11241:30;11307:34;11287:18;;;11280:62;11359:18;;1233:68:12;11027:356:17;1233:68:12;1999:22:::1;::::0;::::1;1991:73;;;::::0;-1:-1:-1;;;1991:73:12;;23672:2:17;1991:73:12::1;::::0;::::1;23654:21:17::0;23711:2;23691:18;;;23684:30;23750:34;23730:18;;;23723:62;23821:8;23801:18;;;23794:36;23847:19;;1991:73:12::1;23470:402:17::0;1991:73:12::1;2074:28;2093:8;2074:18;:28::i;798:355:4:-:0;945:4;987:40;;;1002:25;987:40;;:105;;-1:-1:-1;1044:48:4;;;1059:33;1044:48;987:105;:158;;;-1:-1:-1;952:25:2;937:40;;;;1109:36:4;829:155:2;4844::4;4943:7;:14;4909:4;;4933:24;;:58;;;;;4989:1;4961:30;;:7;4969;4961:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;:30;;4926:65;4844:155;-1:-1:-1;;4844:155:4:o;7172:175::-;7247:24;;;;:15;:24;;;;;:29;;;;;;;;;;;;;:24;;7301;7247;7301:15;:24::i;:::-;7292:47;;;;;;;;;;;;7172:175;;:::o;6812:248:5:-;6913:7;6934:9;6945;6956:7;6967:26;6982:10;6967:14;:26::i;:::-;7011:41;;;;;;;;;;;;24104:25:17;;;24177:4;24165:17;;24145:18;;;24138:45;;;;24199:18;;;24192:34;;;24242:18;;;24235:34;;;6933:60:5;;-1:-1:-1;6933:60:5;;-1:-1:-1;6933:60:5;-1:-1:-1;7011:41:5;;24076:19:17;;7011:41:5;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7011:41:5;;;;;;6812:248;-1:-1:-1;;;;;;;6812:248:5:o;5007:453:4:-;5136:4;5180:16;5188:7;5180;:16::i;:::-;5158:110;;;;-1:-1:-1;;;5158:110:4;;24482:2:17;5158:110:4;;;24464:21:17;24521:2;24501:18;;;24494:30;24560:34;24540:18;;;24533:62;24631:14;24611:18;;;24604:42;24663:19;;5158:110:4;24280:408:17;5158:110:4;5279:13;5295:24;5311:7;5295:15;:24::i;:::-;5279:40;;5349:5;5338:16;;:7;:16;;;:64;;;;5395:7;5371:31;;:20;5383:7;5371:11;:20::i;:::-;:31;;;5338:64;:113;;;-1:-1:-1;3483:25:4;;;;3454:4;3483:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;5419:32;5330:122;5007:453;-1:-1:-1;;;;5007:453:4:o;6610:554::-;6784:4;6756:32;;:24;6772:7;6756:15;:24::i;:::-;:32;;;6734:123;;;;-1:-1:-1;;;6734:123:4;;24895:2:17;6734:123:4;;;24877:21:17;24934:2;24914:18;;;24907:30;24973:34;24953:18;;;24946:62;25044:11;25024:18;;;25017:39;25073:19;;6734:123:4;24693:405:17;6734:123:4;6876:16;;;6868:65;;;;-1:-1:-1;;;6868:65:4;;25305:2:17;6868:65:4;;;25287:21:17;25344:2;25324:18;;;25317:30;25383:34;25363:18;;;25356:62;25454:6;25434:18;;;25427:34;25478:19;;6868:65:4;25103:400:17;6868:65:4;7050:29;7067:1;7071:7;7050:8;:29::i;:::-;7109:2;7090:7;7098;7090:16;;;;;;;;:::i;:::-;;;;;;;;;:21;;;;;;;;;;;7129:27;;7148:7;;7129:27;;;;;;;;;;7090:16;7129:27;6610:554;;;:::o;5586:321::-;5716:18;5722:2;5726:7;5716:5;:18::i;:::-;5767:54;5798:1;5802:2;5806:7;5815:5;5767:22;:54::i;:::-;5745:154;;;;-1:-1:-1;;;5745:154:4;;25710:2:17;5745:154:4;;;25692:21:17;25749:2;25729:18;;;25722:30;25788:34;25768:18;;;25761:62;25859:20;25839:18;;;25832:48;25897:19;;5745:154:4;25508:414:17;2263:187:12;2355:6;;;;2371:17;;;;;;;;;;;2403:40;;2355:6;;;2371:17;2355:6;;2403:40;;2336:16;;2403:40;2326:124;2263:187;:::o;7741:1055:15:-;7845:17;7877:4;:20;;;7898:14;7914:4;7931:8;6598:1;7920:43;;;;;;;;26101:25:17;;;26157:2;26142:18;;26135:34;26089:2;26074:18;;25927:248;7920:43:15;;;;;;;;;;;;;7877:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;8195:15:15;8279:16;;;:6;:16;;;;;;;;;1005:51:16;;;;;29098:25:17;;;29139:18;;;29132:34;;;8272:4:15;29182:18:17;;;29175:83;29274:18;;;;29267:34;;;1005:51:16;;;;;;;;;;29070:19:17;;;;1005:51:16;;;995:62;;;;;;;;;8726:16:15;;;;;;;:20;;8745:1;8726:20;:::i;:::-;8707:16;;;;:6;:16;;;;;:39;8759:32;8714:8;8783:7;1600:41:16;;;;;;;29469:19:17;;;;29504:12;;;29497:28;;;;1600:41:16;;;;;;;;;29541:12:17;;;;1600:41:16;;1590:52;;;;;;1443:204;5129:457:5;5227:17;;5248:1;5227:22;5224:355;;;5266:17;:30;-1:-1:-1;9954:435:5:o;5224:355::-;5326:17;;5347:1;5326:22;5323:256;;;5365:17;:30;-1:-1:-1;9954:435:5:o;5323:256::-;5425:17;;5446:1;5425:22;5422:157;;;5464:17;:30;-1:-1:-1;9954:435:5:o;5422:157::-;5536:18;:31;-1:-1:-1;5129:457:5:o;4484:352:4:-;4641:28;4651:4;4657:2;4661:7;4641:9;:28::i;:::-;4702:48;4725:4;4731:2;4735:7;4744:5;4702:22;:48::i;:::-;4680:148;;;;-1:-1:-1;;;4680:148:4;;25710:2:17;4680:148:4;;;25692:21:17;25749:2;25729:18;;;25722:30;25788:34;25768:18;;;25761:62;25859:20;25839:18;;;25832:48;25897:19;;4680:148:4;25508:414:17;5611:99:5;5662:13;5695:7;5688:14;;;;;:::i;328:703:14:-;384:13;601:10;597:51;;-1:-1:-1;;627:10:14;;;;;;;;;;;;;;;;;;328:703::o;597:51::-;672:5;657:12;711:75;718:9;;711:75;;743:8;;;;:::i;:::-;;-1:-1:-1;765:10:14;;-1:-1:-1;773:2:14;765:10;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:17:14;;795:39;;844:150;851:10;;844:150;;877:11;887:1;877:11;;:::i;:::-;;-1:-1:-1;945:10:14;953:2;945:5;:10;:::i;:::-;932:24;;:2;:24;:::i;:::-;919:39;;902:6;909;902:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;972:11:14;981:2;972:11;;:::i;:::-;;;844:150;;7072:321:5;7136:9;7147;7158:7;7186:3;:10;7200:2;7186:16;7178:53;;;;-1:-1:-1;;;7178:53:5;;27227:2:17;7178:53:5;;;27209:21:17;27266:2;27246:18;;;27239:30;27305:26;27285:18;;;27278:54;27349:18;;7178:53:5;27025:348:17;7178:53:5;-1:-1:-1;;;7286:2:5;7277:12;;7271:19;7324:2;7315:12;;7309:19;7370:2;7361:12;;;7355:19;7271;;7352:1;7347:28;;;;;7072:321::o;5915:346:4:-;5995:16;;;5987:61;;;;-1:-1:-1;;;5987:61:4;;27580:2:17;5987:61:4;;;27562:21:17;;;27599:18;;;27592:30;27658:34;27638:18;;;27631:62;27710:18;;5987:61:4;27378:356:17;5987:61:4;6068:16;6076:7;6068;:16::i;:::-;6067:17;6059:58;;;;-1:-1:-1;;;6059:58:4;;27941:2:17;6059:58:4;;;27923:21:17;27980:2;27960:18;;;27953:30;28019;27999:18;;;27992:58;28067:18;;6059:58:4;27739:352:17;6059:58:4;6186:7;:16;;;;;;;-1:-1:-1;6186:16:4;;;;;;;;;;;;;;;;;;6220:33;;6245:7;;-1:-1:-1;6220:33:4;;-1:-1:-1;;6220:33:4;5915:346;;:::o;7355:980::-;7510:4;7531:13;;;1087:20:0;1133:8;7527:801:4;;7584:175;;;;;:36;;;;;;:175;;719:10:1;;7678:4:4;;7705:7;;7735:5;;7584:175;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7584:175:4;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;7563:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7942:13:4;;7938:320;;7985:108;;-1:-1:-1;;;7985:108:4;;25710:2:17;7985:108:4;;;25692:21:17;25749:2;25729:18;;;25722:30;25788:34;25768:18;;;25761:62;25859:20;25839:18;;;25832:48;25897:19;;7985:108:4;25508:414:17;7938:320:4;8208:6;8202:13;8193:6;8189:2;8185:15;8178:38;7563:710;7823:51;;7833:41;7823:51;;-1:-1:-1;7816:58:4;;7527:801;-1:-1:-1;8312:4:4;7355:980;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:177:17;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:258::-;710:1;720:113;734:6;731:1;728:13;720:113;;;810:11;;;804:18;791:11;;;784:39;756:2;749:10;720:113;;;851:6;848:1;845:13;842:48;;;-1:-1:-1;;886:1:17;868:16;;861:27;638:258::o;901:317::-;943:3;981:5;975:12;1008:6;1003:3;996:19;1024:63;1080:6;1073:4;1068:3;1064:14;1057:4;1050:5;1046:16;1024:63;:::i;:::-;1132:2;1120:15;1137:66;1116:88;1107:98;;;;1207:4;1103:109;;901:317;-1:-1:-1;;901:317:17:o;1223:220::-;1372:2;1361:9;1354:21;1335:4;1392:45;1433:2;1422:9;1418:18;1410:6;1392:45;:::i;1448:180::-;1507:6;1560:2;1548:9;1539:7;1535:23;1531:32;1528:52;;;1576:1;1573;1566:12;1528:52;-1:-1:-1;1599:23:17;;1448:180;-1:-1:-1;1448:180:17:o;1864:196::-;1932:20;;1992:42;1981:54;;1971:65;;1961:93;;2050:1;2047;2040:12;2065:254;2133:6;2141;2194:2;2182:9;2173:7;2169:23;2165:32;2162:52;;;2210:1;2207;2200:12;2162:52;2233:29;2252:9;2233:29;:::i;:::-;2223:39;2309:2;2294:18;;;;2281:32;;-1:-1:-1;;;2065:254:17:o;2506:184::-;2558:77;2555:1;2548:88;2655:4;2652:1;2645:15;2679:4;2676:1;2669:15;2695:690;2759:5;2789:18;2830:2;2822:6;2819:14;2816:40;;;2836:18;;:::i;:::-;2970:2;2964:9;3036:2;3024:15;;2875:66;3020:24;;;3046:2;3016:33;3012:42;3000:55;;;3070:18;;;3090:22;;;3067:46;3064:72;;;3116:18;;:::i;:::-;3156:10;3152:2;3145:22;3185:6;3176:15;;3215:6;3207;3200:22;3255:3;3246:6;3241:3;3237:16;3234:25;3231:45;;;3272:1;3269;3262:12;3231:45;3322:6;3317:3;3310:4;3302:6;3298:17;3285:44;3377:1;3370:4;3361:6;3353;3349:19;3345:30;3338:41;;;;2695:690;;;;;:::o;3390:220::-;3432:5;3485:3;3478:4;3470:6;3466:17;3462:27;3452:55;;3503:1;3500;3493:12;3452:55;3525:79;3600:3;3591:6;3578:20;3571:4;3563:6;3559:17;3525:79;:::i;3615:394::-;3692:6;3700;3753:2;3741:9;3732:7;3728:23;3724:32;3721:52;;;3769:1;3766;3759:12;3721:52;3792:29;3811:9;3792:29;:::i;:::-;3782:39;;3872:2;3861:9;3857:18;3844:32;3899:18;3891:6;3888:30;3885:50;;;3931:1;3928;3921:12;3885:50;3954:49;3995:7;3986:6;3975:9;3971:22;3954:49;:::i;:::-;3944:59;;;3615:394;;;;;:::o;4014:328::-;4091:6;4099;4107;4160:2;4148:9;4139:7;4135:23;4131:32;4128:52;;;4176:1;4173;4166:12;4128:52;4199:29;4218:9;4199:29;:::i;:::-;4189:39;;4247:38;4281:2;4270:9;4266:18;4247:38;:::i;:::-;4237:48;;4332:2;4321:9;4317:18;4304:32;4294:42;;4014:328;;;;;:::o;4347:118::-;4433:5;4426:13;4419:21;4412:5;4409:32;4399:60;;4455:1;4452;4445:12;4470:517;4553:6;4561;4569;4622:2;4610:9;4601:7;4597:23;4593:32;4590:52;;;4638:1;4635;4628:12;4590:52;4674:9;4661:23;4651:33;;4735:2;4724:9;4720:18;4707:32;4762:18;4754:6;4751:30;4748:50;;;4794:1;4791;4784:12;4748:50;4817:49;4858:7;4849:6;4838:9;4834:22;4817:49;:::i;:::-;4807:59;;;4916:2;4905:9;4901:18;4888:32;4929:28;4951:5;4929:28;:::i;:::-;4976:5;4966:15;;;4470:517;;;;;:::o;4992:248::-;5060:6;5068;5121:2;5109:9;5100:7;5096:23;5092:32;5089:52;;;5137:1;5134;5127:12;5089:52;-1:-1:-1;;5160:23:17;;;5230:2;5215:18;;;5202:32;;-1:-1:-1;4992:248:17:o;5245:450::-;5314:6;5367:2;5355:9;5346:7;5342:23;5338:32;5335:52;;;5383:1;5380;5373:12;5335:52;5423:9;5410:23;5456:18;5448:6;5445:30;5442:50;;;5488:1;5485;5478:12;5442:50;5511:22;;5564:4;5556:13;;5552:27;-1:-1:-1;5542:55:17;;5593:1;5590;5583:12;5542:55;5616:73;5681:7;5676:2;5663:16;5658:2;5654;5650:11;5616:73;:::i;5882:186::-;5941:6;5994:2;5982:9;5973:7;5969:23;5965:32;5962:52;;;6010:1;6007;6000:12;5962:52;6033:29;6052:9;6033:29;:::i;6073:632::-;6244:2;6296:21;;;6366:13;;6269:18;;;6388:22;;;6215:4;;6244:2;6467:15;;;;6441:2;6426:18;;;6215:4;6510:169;6524:6;6521:1;6518:13;6510:169;;;6585:13;;6573:26;;6654:15;;;;6619:12;;;;6546:1;6539:9;6510:169;;;-1:-1:-1;6696:3:17;;6073:632;-1:-1:-1;;;;;;6073:632:17:o;6710:241::-;6766:6;6819:2;6807:9;6798:7;6794:23;6790:32;6787:52;;;6835:1;6832;6825:12;6787:52;6874:9;6861:23;6893:28;6915:5;6893:28;:::i;7209:681::-;7380:2;7432:21;;;7502:13;;7405:18;;;7524:22;;;7351:4;;7380:2;7603:15;;;;7577:2;7562:18;;;7351:4;7646:218;7660:6;7657:1;7654:13;7646:218;;;7725:13;;7740:42;7721:62;7709:75;;7839:15;;;;7804:12;;;;7682:1;7675:9;7646:218;;7895:315;7960:6;7968;8021:2;8009:9;8000:7;7996:23;7992:32;7989:52;;;8037:1;8034;8027:12;7989:52;8060:29;8079:9;8060:29;:::i;:::-;8050:39;;8139:2;8128:9;8124:18;8111:32;8152:28;8174:5;8152:28;:::i;:::-;8199:5;8189:15;;;7895:315;;;;;:::o;8215:537::-;8310:6;8318;8326;8334;8387:3;8375:9;8366:7;8362:23;8358:33;8355:53;;;8404:1;8401;8394:12;8355:53;8427:29;8446:9;8427:29;:::i;:::-;8417:39;;8475:38;8509:2;8498:9;8494:18;8475:38;:::i;:::-;8465:48;;8560:2;8549:9;8545:18;8532:32;8522:42;;8615:2;8604:9;8600:18;8587:32;8642:18;8634:6;8631:30;8628:50;;;8674:1;8671;8664:12;8628:50;8697:49;8738:7;8729:6;8718:9;8714:22;8697:49;:::i;:::-;8687:59;;;8215:537;;;;;;;:::o;8757:367::-;8820:8;8830:6;8884:3;8877:4;8869:6;8865:17;8861:27;8851:55;;8902:1;8899;8892:12;8851:55;-1:-1:-1;8925:20:17;;8968:18;8957:30;;8954:50;;;9000:1;8997;8990:12;8954:50;9037:4;9029:6;9025:17;9013:29;;9097:3;9090:4;9080:6;9077:1;9073:14;9065:6;9061:27;9057:38;9054:47;9051:67;;;9114:1;9111;9104:12;9051:67;8757:367;;;;;:::o;9129:773::-;9251:6;9259;9267;9275;9328:2;9316:9;9307:7;9303:23;9299:32;9296:52;;;9344:1;9341;9334:12;9296:52;9384:9;9371:23;9413:18;9454:2;9446:6;9443:14;9440:34;;;9470:1;9467;9460:12;9440:34;9509:70;9571:7;9562:6;9551:9;9547:22;9509:70;:::i;:::-;9598:8;;-1:-1:-1;9483:96:17;-1:-1:-1;9686:2:17;9671:18;;9658:32;;-1:-1:-1;9702:16:17;;;9699:36;;;9731:1;9728;9721:12;9699:36;;9770:72;9834:7;9823:8;9812:9;9808:24;9770:72;:::i;:::-;9129:773;;;;-1:-1:-1;9861:8:17;-1:-1:-1;;;;9129:773:17:o;9907:260::-;9975:6;9983;10036:2;10024:9;10015:7;10011:23;10007:32;10004:52;;;10052:1;10049;10042:12;10004:52;10075:29;10094:9;10075:29;:::i;:::-;10065:39;;10123:38;10157:2;10146:9;10142:18;10123:38;:::i;:::-;10113:48;;9907:260;;;;;:::o;10172:437::-;10251:1;10247:12;;;;10294;;;10315:61;;10369:4;10361:6;10357:17;10347:27;;10315:61;10422:2;10414:6;10411:14;10391:18;10388:38;10385:218;;;10459:77;10456:1;10449:88;10560:4;10557:1;10550:15;10588:4;10585:1;10578:15;10385:218;;10172:437;;;:::o;14685:184::-;14737:77;14734:1;14727:88;14834:4;14831:1;14824:15;14858:4;14855:1;14848:15;14874:125;14914:4;14942:1;14939;14936:8;14933:34;;;14947:18;;:::i;:::-;-1:-1:-1;14984:9:17;;14874:125::o;15004:128::-;15044:3;15075:1;15071:6;15068:1;15065:13;15062:39;;;15081:18;;:::i;:::-;-1:-1:-1;15117:9:17;;15004:128::o;15484:228::-;15524:7;15650:1;15582:66;15578:74;15575:1;15572:81;15567:1;15560:9;15553:17;15549:105;15546:131;;;15657:18;;:::i;:::-;-1:-1:-1;15697:9:17;;15484:228::o;16412:195::-;16451:3;16482:66;16475:5;16472:77;16469:103;;;16552:18;;:::i;:::-;-1:-1:-1;16599:1:17;16588:13;;16412:195::o;16963:184::-;17015:77;17012:1;17005:88;17112:4;17109:1;17102:15;17136:4;17133:1;17126:15;18895:184;18965:6;19018:2;19006:9;18997:7;18993:23;18989:32;18986:52;;;19034:1;19031;19024:12;18986:52;-1:-1:-1;19057:16:17;;18895:184;-1:-1:-1;18895:184:17:o;21227:245::-;21294:6;21347:2;21335:9;21326:7;21322:23;21318:32;21315:52;;;21363:1;21360;21353:12;21315:52;21395:9;21389:16;21414:28;21436:5;21414:28;:::i;22995:470::-;23174:3;23212:6;23206:13;23228:53;23274:6;23269:3;23262:4;23254:6;23250:17;23228:53;:::i;:::-;23344:13;;23303:16;;;;23366:57;23344:13;23303:16;23400:4;23388:17;;23366:57;:::i;:::-;23439:20;;22995:470;-1:-1:-1;;;;22995:470:17:o;26180:409::-;26395:42;26387:6;26383:55;26372:9;26365:74;26475:6;26470:2;26459:9;26455:18;26448:34;26518:2;26513;26502:9;26498:18;26491:30;26346:4;26538:45;26579:2;26568:9;26564:18;26556:6;26538:45;:::i;:::-;26530:53;26180:409;-1:-1:-1;;;;;26180:409:17:o;26594:184::-;26646:77;26643:1;26636:88;26743:4;26740:1;26733:15;26767:4;26764:1;26757:15;26783:120;26823:1;26849;26839:35;;26854:18;;:::i;:::-;-1:-1:-1;26888:9:17;;26783:120::o;26908:112::-;26940:1;26966;26956:35;;26971:18;;:::i;:::-;-1:-1:-1;27005:9:17;;26908:112::o;28096:512::-;28290:4;28319:42;28400:2;28392:6;28388:15;28377:9;28370:34;28452:2;28444:6;28440:15;28435:2;28424:9;28420:18;28413:43;;28492:6;28487:2;28476:9;28472:18;28465:34;28535:3;28530:2;28519:9;28515:18;28508:31;28556:46;28597:3;28586:9;28582:19;28574:6;28556:46;:::i;:::-;28548:54;28096:512;-1:-1:-1;;;;;;28096:512:17:o;28613:249::-;28682:6;28735:2;28723:9;28714:7;28710:23;28706:32;28703:52;;;28751:1;28748;28741:12;28703:52;28783:9;28777:16;28802:30;28826:5;28802:30;:::i

Swarm Source

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