ETH Price: $2,601.50 (-2.33%)

Warriors of the Wand (WOTW)
 

Overview

TokenID

387

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

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:
Warrior

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 18 of 18: Warrior.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

// This is an NFT for Warrior NFT https://twitter.com/WaroftheWand

/*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^::::::::^:::::::::^::::::::^^^^^^::::::^^^^::::::^^:::::::^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^:^555!^^^:^^55555^^:^^^!555^:^^^^^^JPPJ^^^^^^JPPJ^^^:7PP5^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^:~@B!5BB5~P#J?!YP#P~5BB5!B@~:^^^:7&J!?5&7::7&J!?5&7^#P!?J#5:::::^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^:~@P :^7YG&@7~^7J@&GY7^: P@~:::::7B55GGG7::7GP5PGB7^PP5PPBY:!??!::^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^:^JY5~.  .?5BBPBB5?.  .~5YJ:!55Y^::G@P55!::!Y5P@G::^Y55#&^~5YY555!:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^:^PB@#G~:  .7???7.  :~G#@BGBP?JYBY:G@??JPP^?@J~&G^YGYJ7G#^?@57JP@?:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^:^BG?JYBP!!! ^Y^ !!!PBYJ?G##GJ5P#P!P#@G77?#G7??5G&Y77Y@5?!J###@G~^:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^:!PYYGBB&&77?77&&BBGYYP!::!P&@7JBJ7#G??J#P!?J5PBJ!JYGPPB57PBPJ::^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^:::7YJ5B&@5J7J5@&B5JY7::::::7YGPJYY7!~~!7!^!7!!~~!5Y!!7J5#5?^:^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^:::^!B@BGGGG@B!^:::^^^^^^::!Y&Y7:~JJ?^!YJ?:~J7!~~!!7YG@?::^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^::P@GY75G@P::^^^^^^^^^^::?@PJ~~~!!!!777!!!!~:~JJJJP@?:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^:G@!7GB#@G:^^^^^^^^^^^::?@57JJ7JJJJJJJ???JJ!!!!7YG@?::^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^:P@Y5#YJ@G:^^^^^^^^^^:^PP5B#YJ7?????77?????YYYYJ?5@BP^:^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^:~!&#P55@G:^^^^^^^^^^:~@B7B@BG57~~~7J5GBBJ7JJY7!???B#7~::::^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^:^&&B##@G:^^^^^^^^^^:^&#Y#@ <O> ^^ <O> ^^~?JY??YY???GP?J?:::::::^:::^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^:~&&#5Y@G::^^^^^^^^:?5GPYPG5Y7~~!!!?J:::^~Y5BBB5YYJ?7JPPP555555?:^^^:::^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^:~&&B5Y@G~^::^^^^^::G@BB##BGY^!7??**JJ?~7JYG@@&BG55Y??J??Y555YJYGGGGY~^::^^^^^^^^^
^^^^^^^^^^^^^^^^^^:^@&G#&@&GJ!^:^^^:~!PG~J@BP&BJ****?JY?JJ5PB#@J~~Y@#GP5?JY?77JJ??J?77JBJ!::^^^^^^^^
^^^^^^^^^^^^^^^^^:[email protected]@^:^^::?@?:^J@5?@&GJ7?YYY77JGGG5P#J7GGP!^5PB5YYJ???J5GGGJ??PGY7:::^^^^^
^^^^^^^^^^^^^^^^^:G@^:~~!&G~J5PJ::^5B@[email protected]@P?!7?7!75@J!@B~^~@B~~^:~JG#Y5#5J?J5&@#GYJJPPP!:^^^^^
^^^^^^^^^^^^^^^^^:G@J?JJYP5Y??&G~^^@B^!7G#@?::?@57~!?JJ75@#PJ!.:~&#J?7~!7G#55P#&5Y7G&JYBP5JYYGB^:^^^
^^^^^^^^^^^^^^^^^:G@~^^7JPGGBB7JPJ?BP777?5@Y!.!G5Y??J77Y5G7:::^?5@#YJ?~7JJY@#JG&@#GYJGP?5PGPJG#?!:^^
^^^^^^^^^^^^^^^^^:?5PPP55@@@GYJ7^G@55PBBB#@P?~^.P@J??77@P..:^!JPBBB#GPYYYYYY5B5Y@#YGBJYG5YYPB5Y@G::^
^^^^^^^^^^^^^^^^^^::75@#B@#YYY5Y77?#G?5G@@@G57!~G@Y?!?Y@G~7?JP&GPYP@@@5J?!~:?@G5PPGJ?#G7B@~~?G#PPB7:
^^^^^^^^^^^^^^^^^^^::?@&#@&G5JYYY?7@#YPG&B5#&?!^5BYJ?YP#G7??YG@G5YG@#B?YPGGPB@#GYP@?:BB555#5.5#PG&7:
^^^^^^^^^^^^^^^^^^^^:?@G5@G:JP5PBP5B##&@5YJ#@B5!~~&#J#@77JY5GGP#@5P#5J&&#PYYP@?^GGP!::?@PY@G:^^PJ:^^
^^^^^^^^^^^^^^^^^^^^:?@5J@G::^JYJG#BGJ#@55B5J@&GYY@&BBGGPPB#@P.P@5YY#@@&#G5JP@?:J7::^:?@G5@G::::::^^
^^^^^^^^^^^^^^^^^^^^:?@5?@G:^::::~77~:G@YP@J~@#YB&?JP##?J5PB@G^!7#BJ#@7Y@PJ?5@J^::^^^:~!PB7~:^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@#B@G:^^^^^:::::YBPB@BPGGG#&PPG#&GGGGGG#@7:GGPGG7J#Y7!7JB&!:^^^^::^~::^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@P5@G:^^^^^^^^^^:^&@@?..^J77Y55?7~!J~..~5YJ:?@?^@G^7?:..P@!:^^^^^^::^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@5J@G:^^^^^^^^^^:~&B7~:~7P7~....:~7P7~::.P@~~?5P?7~PB^:~G@!:^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@5?@G:^^^^^^^^^^:^@G 7JYP@G57!!!75G@G5!~:^!#5.5#~!YJJ77JG#!:^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@#B@G:^^^^^^^^^:!?PJ:7JGGBBBGGGGB@&P&@J77~^P5?~^PGBGGGGG7^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@PY@G:^^^^^^^^::G@77JY5@&PGGYYYY5@#5Y5BP!7!.7@?::!YYYY?:::^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@5J@G:^^^^^^^:7BJ!?J5B#PG#&&^::::!Y@Y7&#Y?!!!7PG^::::::^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@5?@G:^^^^^^::?@P?PPPB##&@J^^^^^::^~G&J5@Y77!~5B7~:^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@BG@G:^^^^^:^?Y5555G@BG#BP!:^^^^^^::JPPGBBGJ??JY@G::^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@Y7@G:^^^^^:~@G...^!JPB@G.:^^^^^^^^^:^&#J#@5P#5??JP!:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:?@?^@G:^^^^^:^!J#J!7?YGB&P~^:^^^^^^^^:^!JB&@PY7!~.7@?:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^:7B?!GY:^^^^^^^:7BGPPB@J~75@?:^^^^^^^^^^:^^G@&BPPPYP@?:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^::G@^:^^^^^^^^^::G@B#@J^75@?:^^^^^^^^^^^::?5#BP&@##@?:^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^:!7^:^^^^^^^^:::G@?Y@Y7BP?~:^^^^^^^^^^^^^::7YBJ7~J@?^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^:::^^^^^::::!!!G&!~~5B@G.:^^^^^^^^^^^^^^^^~J@Y!7JP##^:^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^::~JJJ5PPJ??7~~~BG?~:^^^^^^^^^^^^^:^@B??????5PJ7::^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^:^55J55~~~~~~~~!7YG@?:^^^^^^^^^^^^:J5J?~~~~~~^~GG5!:^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^:~@#?JJYYYYYYYYYY#G7~:^^^^^^^^^^^^:G@JJYYYYYYYYYG@?:^^^^^^^^^^^^^^^^^^^^
*/

import "./ERC721A.sol";
import "./Ownable.sol";
import "./IERC20.sol";
import "./ReentrancyGuard.sol";
import "./ERC2981.sol";
import "./PaymentSplitter.sol";
import {DefaultOperatorFilterer721, OperatorFilterer721} from "./DefaultOperatorFilterer721.sol";

interface Staker {
    function userStakeBalance(address user) external view returns (uint256);
    function userBurntBalance(address user) external view returns (uint256);
    function stakeList(address user) external view returns (uint16[] memory);
    function burntList(address user) external view returns (uint16[] memory ids);
}

contract Warrior is
    ERC721A,
    ReentrancyGuard,
    PaymentSplitter,
    Ownable,
    DefaultOperatorFilterer721,
    ERC2981
{

    string private constant _name = "Warriors of the Wand";
    string private constant _symbol = "WOTW";
    string public baseURI = "ipfs://QmNqEnxCjPidStahDS4VPdLifceHEX5YBCqN9kZHFSYPP5/";
    uint256 public cost = 0.025 ether;
    uint16 public maxSupply = 7777;
    uint16 public freeSupply = 1111;
    uint16 public paidSupply = 2222;
    uint16 public freeMinted;
    uint16 public paidMinted;
    uint16[7777] private claimed;
    bool public freezeURI = false;
    bool public freezeSupply = false;
	bool public paused = true;
    mapping(uint256 => bool) public tokenToIsStaked;
	mapping(address => uint16) public minted;

    address[] private firstPayees = [0x9FcFD77494a0696618Fab4568ff11aCB0F0e5d9C, 0xa4D89eb5388613A9BF7ED0eaFf5fD2c05a4B34e3];
    uint16[] private firstShares = [50, 50];

    Staker public staking = Staker(0x1dE0aef4d0135a561ffeaa84f74dd00eB747a489);

    constructor() ERC721A(_name, _symbol) PaymentSplitter(firstPayees, firstShares) payable {
        _setDefaultRoyalty(address(this), 750);
    }

    // to support royalties
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    // returns how many can be minted for free 
    function unclaimed(address user) public view returns (uint16) {
        uint16 available;
        uint256 stakeBalance = staking.userStakeBalance(user);
        uint256 burnBalance = staking.userBurntBalance(user);
        uint16[] memory ids;
        uint16 i;

        unchecked {
            if (stakeBalance > 0) {
                ids = staking.stakeList(user);

                for (i = 0; i < stakeBalance; i++) {
                    available += 1 - claimed[ids[i]];
                }
            }

            if (burnBalance > 0) {
                ids = staking.burntList(user);

                for (i = 0; i < burnBalance; i++) {
                    available += 2 - claimed[ids[i]];
                }
            }
        
            if (available > freeSupply - freeMinted) {
                available = freeSupply - freeMinted;
            }
        }

        return available;
    }

    // @dev public minting
	function mint(uint16 mintAmount) external payable nonReentrant {
        uint16 available = unclaimed(msg.sender);
        uint16[] memory ids;
        uint16 i;
        uint256 stakeBalance;
        uint256 burnBalance;

        require(Address.isContract(msg.sender) == false, "Warrior: no contracts");
        require(paused == false || msg.sender == owner(), "Warrior: Minting not started yet");
        require(totalSupply() + mintAmount <= maxSupply, "Warrior: Can't mint more than max supply");

        unchecked {
            if (msg.sender == owner() || msg.sender == 0xa4D89eb5388613A9BF7ED0eaFf5fD2c05a4B34e3) {
                //no cost to owner
                paidMinted += mintAmount;

            } else if (available > 0) {
                if (mintAmount > available) {
                    mintAmount = available;
                }
                uint16 claiming = mintAmount;

                //1 free mint for each id staked
                stakeBalance = staking.userStakeBalance(msg.sender);
                if (stakeBalance > 0) {
                    ids = staking.stakeList(msg.sender);

                    for (i = 0; i < stakeBalance; i++) {
                        if (claiming > 0 && claimed[ids[i]] == 0) {
                            claimed[ids[i]] = 1;
                            claiming -= 1;
                        }
                    }
                }

                //2 free mint for each id burnt
                burnBalance = staking.userBurntBalance(msg.sender);
                if (burnBalance > 0) {
                    ids = staking.burntList(msg.sender);

                    for (i = 0; i < burnBalance; i++) {
                        if (claiming > 1 && claimed[ids[i]] == 0) {
                            claimed[ids[i]] = 2;
                            claiming -= 2;
                        } else if (claiming > 0 && claimed[ids[i]] == 1) {
                            claimed[ids[i]] = 2;
                            claiming -= 1;
                        }
                    }
                }

                freeMinted += mintAmount;

            } else if (paidMinted < paidSupply) {
                require(paidMinted + mintAmount <= paidSupply, "Warrior: Cannot mint this many");
                require(msg.value >= cost * mintAmount, "Warrior: You must pay for the nft");

                paidMinted += mintAmount;

            } else {
                require(false, "Warrior: none available to mint");
            }

            minted[msg.sender] += mintAmount;
        }

        _safeMint(msg.sender, mintAmount);
	}

    //@dev prevent transfer or burn of staked id
    function _beforeTokenTransfers(address /*from*/, address /*to*/, uint256 startTokenId, uint256 /*quantity*/) internal virtual override {
        require(tokenToIsStaked[startTokenId] == false, "Warrior, cannot transfer - currently locked");
    }

    /**
     *  @dev returns whether a token is currently staked
     */
    function isStaked(uint256 tokenId) public view returns (bool) {
        return tokenToIsStaked[tokenId];
    }

    /**
     *  @dev marks a token as staked, calling this function
     *  you disable the ability to transfer the token.
     */
    function stake(uint256 tokenId) external nonReentrant {
        require(msg.sender == ownerOf(tokenId), "Warrior: caller is not the owner");
        tokenToIsStaked[tokenId] = true;
    }

    /**
     *  @dev marks a token as unstaked. By calling this function
     *  you re-enable the ability to transfer the token.
     */
    function unstake(uint256 tokenId) external nonReentrant {
        require(msg.sender == ownerOf(tokenId), "Warrior: caller is not the owner");
        tokenToIsStaked[tokenId] = false;
    }

    // @dev set cost of minting
	function setCost(uint256 _newCost) external onlyOwner {
    	cost = _newCost;
	}
		
    // @dev unpause main minting stage
	function setPaused(bool _status) external onlyOwner {
    	paused = _status;
	}
	
    // @dev set how many can be minted by paid minters
	function setPaidSupply(uint16 _new) external onlyOwner {
        require(_new >= paidMinted, "Warrior: too low");
    	paidSupply = _new;
	}

    // @dev set how many can be minted for free from stakers and burners
	function setFreeSupply(uint16 _new) external onlyOwner {
        require(_new >= freeMinted, "Warrior: too low");
    	freeSupply = _new;
	}

    // @dev Set the base url path to the metadata
    function setBaseURI(string memory _baseTokenURI) external onlyOwner {
        require(freezeURI == false, "Warrior: uri is frozen");
        baseURI = _baseTokenURI;
    }

    // @dev freeze the URI
    function setFreezeURI() external onlyOwner {
        freezeURI = true;
    }

    // @dev show the baseuri
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }

    // @dev Add payee for payment splitter
    function FreezeSupply() external onlyOwner {
        freezeSupply = true;
    }

    //reduce max supply if needed
    function setMaxSupply(uint16 newMax) external onlyOwner {
        require(freezeSupply == false, "Warrior: Max supply is frozen");
        require(newMax < maxSupply, "Warrior: New maximum must be less than existing maximum");
        maxSupply = newMax;
    }

    /**
     * @dev External onlyOwner version of {ERC2981-_setDefaultRoyalty}.
     */
    function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner {
        _setDefaultRoyalty(receiver, feeNumerator);
    }

    // @dev Add payee for payment splitter
    function addPayee(address account, uint16 shares_) external onlyOwner {
        _addPayee(account, shares_);
    }

    // @dev Set the number of shares for payment splitter
    function setShares(address account, uint16 shares_) external onlyOwner {
        _setShares(account, shares_);
    }

    // @dev add tokens that are used by payment splitter
    function addToken(address account) external onlyOwner {
        _addToken(account);
    }

    // @dev release payments to one payee
    function release(address payable account) external nonReentrant {
        require(Address.isContract(account) == false, "Warrior: no contracts");
        _release(account);
    }

    // @dev release ERC20 tokens due to a payee
    function releaseToken(IERC20 token, address payable account) external nonReentrant {
        require(Address.isContract(account) == false, "Warrior: no contracts");
        _releaseToken(token, account);
    }

    // @dev anyone can run withdraw which will send all payments
    function withdraw() external nonReentrant {
        _withdraw();
    }

    function setUseFilter(bool Use) external onlyOwner {
        setUse(Use);
    }

    function transferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public payable
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }
}

File 1 of 18: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 2 of 18: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/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 18: DefaultOperatorFilterer721.sol
// SPDX-License-Identifier: MIT
// https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/example/DefaultOperatorFilterer721.sol

pragma solidity ^0.8.13;

import {OperatorFilterer721} from "./OperatorFilterer721.sol";

abstract contract DefaultOperatorFilterer721 is OperatorFilterer721 {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer721(DEFAULT_SUBSCRIPTION, true) {}
}

File 4 of 18: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/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 5 of 18: ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/common/ERC2981.sol?s=09

pragma solidity ^0.8.0;

import "./IERC2981.sol";
import "./ERC165.sol";

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

File 6 of 18: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
// https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol

pragma solidity ^0.8.4;

import "./IERC721A.sol";

/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

    // Mapping from token ID to approved address.
    mapping(uint256 => TokenApprovalRef) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 1;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId),".json")) : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @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) public payable virtual override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @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) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token IDs
     * have been transferred. This includes minting.
     * And also called after one token has been burned.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

File 7 of 18: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/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 18: IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

File 9 of 18: IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/IERC20Permit.sol

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 10 of 18: IERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/IERC2981.sol

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 11 of 18: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
// https://github.com/chiru-labs/ERC721A/blob/main/contracts/IERC721A.sol

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // =============================================================
    //                            IERC721
    // =============================================================

    /**
     * @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,
        bytes calldata data
    ) external payable;

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` 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 payable;

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

    /**
     * @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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

File 12 of 18: IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
// https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/IOperatorFilterRegistry.sol

pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

File 13 of 18: OperatorFilterer721.sol
// SPDX-License-Identifier: MIT
// https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/example/OperatorFilterer721.sol

pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

abstract contract OperatorFilterer721 {
    error OperatorNotAllowed(address operator);

    bool public useFilter = true;

    // allow to bypass filter
    function setUse(bool use) internal virtual {
        useFilter = use;
    }

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (subscribe) {
                operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    operatorFilterRegistry.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (useFilter && address(operatorFilterRegistry).code.length > 0) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !(
                    operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)
                        && operatorFilterRegistry.isOperatorAllowed(address(this), from)
                )
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}

File 14 of 18: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

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

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

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

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

File 15 of 18: PaymentSplitter.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (finance/PaymentSplitter.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/finance/PaymentSplitter.sol
// Changes were made as client needs to change shares in the future. Also made it easier to manage withdrawls.

pragma solidity ^0.8.0;

import "./SafeERC20.sol";
import "./Address.sol";
import "./Context.sol";

/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 * 
 */

contract PaymentSplitter is Context {
    event PayeeAdded(address account, uint16 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;
    address[] private _payees;
    IERC20[] private _tokenList;
    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    mapping(IERC20 => uint256) private _erc20TotalReleased;
    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;


    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint16[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint16 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
        //Can add tokens eg wrapped ETH
        //_addToken(0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619);
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }

    /**
     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
     * contract.
     */
    function totalReleasedToken(IERC20 token) public view returns (uint256) {
        return _erc20TotalReleased[token];
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }

    /**
     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
     * IERC20 contract.
     */
    function releasedToken(IERC20 token, address account) public view returns (uint256) {
        return _erc20Released[token][account];
    }

    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function _release(address payable account) internal virtual {
        uint256 totalReceived = address(this).balance + totalReleased();
        uint256 payment = _pendingPayment(account, totalReceived, released(account));
 
        //in case calculation is wrong then give remaining balance
        if (payment > address(this).balance) {
            payment = address(this).balance;
        }

        if (payment > 0) {
            _released[account] += payment;
            _totalReleased += payment;

            Address.sendValue(account, payment);
            emit PaymentReleased(account, payment);
        }
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
     * contract.
     */
    function _releaseToken(IERC20 token, address payable account) internal virtual {
        uint256 totalReceived = token.balanceOf(address(this)) + totalReleasedToken(token);
        uint256 payment = _pendingPayment(account, totalReceived, releasedToken(token, account));

        //in case calculation is wrong then give remaining balance
        if (payment > token.balanceOf(address(this))) {
            payment = token.balanceOf(address(this));
        }

        if (payment > 0) {
            _erc20Released[token][account] += payment;
            _erc20TotalReleased[token] += payment;

            SafeERC20.safeTransfer(token, account, payment);
            emit ERC20PaymentReleased(token, account, payment);
        }
    }

    /**
     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(
        address account,
        uint256 totalReceived,
        uint256 alreadyReleased
    ) private view returns (uint256) {
        uint256 _pending;
        if (_totalShares == 0) {
            _pending = 0;
        } else {
            _pending = (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
        }
        return _pending;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint16 shares_) internal virtual {
        uint256 i;
        uint256 j;

        require(Address.isContract(account) == false, "PaymentSplitter: no contracts");
        require(shares_ > 0, "PaymentSplitter: shares are 0");

        //prevent duplicates as can be run after contract deployed
        uint payeeExists;
        for (i = 0; i < _payees.length; i++) {
            if (_payees[i] == account) {
                payeeExists = 1;
            }
        }

        //if new payee then add
        if (payeeExists == 0) {
            //make pay outs and reset values so next payout is correct
            if (shares_ > 0) {
                _withdraw();
                _totalReleased = 0;
                for (i = 0; i < _payees.length; i++) {
                    _released[_payees[i]] = 0;
                }

                //for each token
                for (j = 0; j < _tokenList.length; j++) {
                    IERC20 token = _tokenList[j];
                    _erc20TotalReleased[token] = 0;            
                    for (i = 0; i < _payees.length; i++) {
                        _erc20Released[token][_payees[i]] = 0;
                    }
                }
            }

            _payees.push(account);
            _shares[account] = shares_;
            _totalShares = _totalShares + shares_;
            emit PayeeAdded(account, shares_);
        }
    }

    // @dev set shares of payout account
    function _setShares(address account, uint256 shares_) internal virtual {
        uint256 i;
        uint256 j;
        uint256 pendingTotal;

        //make sure payee exists
        uint payeeExists = 0;
        for (i = 0; i < _payees.length; i++) {
            if (_payees[i] == account) {
                payeeExists = 1;
            }
        }
        require(payeeExists == 1, "PaymentSplitter: payee does not exist, add payee first");

        pendingTotal = _totalShares - _shares[account] + shares_;
        require(pendingTotal > 0, "PaymentSplitter: total shares must be greater than 0");

        //make pay outs and reset values so next payout is correct
        _withdraw();
        _totalReleased = 0;
        for (i = 0; i < _payees.length; i++) {
            _released[_payees[i]] = 0;
        }

        //for each token
        for (j = 0; j < _tokenList.length; j++) {
            IERC20 token = _tokenList[j];
            _erc20TotalReleased[token] = 0;            
            for (i = 0; i < _payees.length; i++) {
                _erc20Released[token][_payees[i]] = 0;
            }
        }

        _totalShares = pendingTotal;
        _shares[account] = shares_;
    }

    // @dev add erc20 token address to the list
    function _addToken(address token) internal virtual {
        require(Address.isContract(token) == true, "PaymentSplitter: must be a contract");

        //test if token exists
        IERC20(token).balanceOf(address(this));

        //prevent duplicates as can be run after contract deployed
        uint tokenExists = 0;
        for (uint256 i = 0; i < _tokenList.length; i++) {
            if (_tokenList[i] == IERC20(token)) {
                tokenExists = 1;
            }
        }
        require(tokenExists == 0, "PaymentSplitter: token already added");

        _tokenList.push(IERC20(token));
    }

    // @dev show list of erc20 tokens added in payment splitter
    function showTokens() public view returns (IERC20[] memory) {
        return _tokenList;
    }

    // @dev show list of payees added in payment splitter
    function showPayees() public view returns (address[] memory) {
        return _payees;
    }

    // @dev releases payments for all payees for ETH and all tokens
    function _withdraw() internal virtual {
        //for each payee
        for (uint256 i = 0; i < _payees.length; i++) {

            //for each token
            for (uint256 j = 0; j < _tokenList.length; j++) {
                IERC20 token = _tokenList[j];
                _releaseToken(token, payable(_payees[i]));
            }

            _release(payable(_payees[i]));
        }
    }
}

File 16 of 18: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/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() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // 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;
    }

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

File 17 of 18: SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./IERC20Permit.sol";
import "./Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","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":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint16","name":"shares","type":"uint16"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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":"FreezeSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint16","name":"shares_","type":"uint16"}],"name":"addPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMinted","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freezeSupply","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freezeURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"uint256","name":"tokenId","type":"uint256"}],"name":"isStaked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"mintAmount","type":"uint16"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minted","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"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":"paidMinted","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paidSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address payable","name":"account","type":"address"}],"name":"releaseToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releasedToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"payable","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":"payable","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":"_baseTokenURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_new","type":"uint16"}],"name":"setFreeSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setFreezeURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"newMax","type":"uint16"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_new","type":"uint16"}],"name":"setPaidSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint16","name":"shares_","type":"uint16"}],"name":"setShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"Use","type":"bool"}],"name":"setUseFilter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showPayees","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showTokens","outputs":[{"internalType":"contract IERC20[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract Staker","name":"","type":"address"}],"stateMutability":"view","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":"","type":"uint256"}],"name":"tokenToIsStaked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleasedToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"unclaimed","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"useFilter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6011805460ff60a01b1916600160a01b17905560e06040526036608081815290620062d660a03960149062000035908262001420565b506658d15e17628000601555601680546508ae04571e6165ffffffffffff199091161790556101fe805462ffffff19166201000017905560408051808201909152739fcfd77494a0696618fab4568ff11acb0f0e5d9c815273a4d89eb5388613a9bf7ed0eaff5fd2c05a4b34e36020820152620000b89061020190600262001256565b506040805180820190915260328082526020820152620000de90610202906002620012c0565b5061020380546001600160a01b031916731de0aef4d0135a561ffeaa84f74dd00eb747a489179055610201805460408051602080840282018101909252828152733cc6cdda760b79bafa08df41ecfa224f810dceb69360019391929091908301828280156200017757602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000158575b5050505050610202805480602002602001604051908101604052809291908181526020018280548015620001f357602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411620001b95790505b50505050506040518060400160405280601481526020017f57617272696f7273206f66207468652057616e6400000000000000000000000081525060405180604001604052806004815260200163574f545760e01b81525081600290816200025c919062001420565b5060036200026b828262001420565b506001600055505060016008558051825114620002ea5760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b60008251116200033d5760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f207061796565730000000000006044820152606401620002e1565b60005b82518161ffff161015620003b557620003a0838261ffff16815181106200036b576200036b620014ec565b6020026020010151838361ffff16815181106200038c576200038c620014ec565b60200260200101516200052e60201b60201c565b80620003ac8162001518565b91505062000340565b505050620003d2620003cc6200087a60201b60201c565b6200087e565b6daaeb6d7670e522a718067333cd4e3b15620005175780156200046557604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200044657600080fd5b505af11580156200045b573d6000803e3d6000fd5b5050505062000517565b6001600160a01b03821615620004b65760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af2903906044016200042b565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620004fd57600080fd5b505af115801562000512573d6000803e3d6000fd5b505050505b50620005289050306102ee620008d0565b6200167f565b6000806200054784620009d160201b6200292f1760201c565b15620005965760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a206e6f20636f6e7472616374730000006044820152606401620002e1565b60008361ffff1611620005ec5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401620002e1565b60008092505b600b548310156200065157846001600160a01b0316600b84815481106200061d576200061d620014ec565b6000918252602090912001546001600160a01b0316036200063c575060015b8262000648816200153c565b935050620005f2565b80600003620008735761ffff841615620007bb576200066f620009e0565b6000600a81905592505b600b54831015620006da576000600e6000600b8681548110620006a057620006a0620014ec565b60009182526020808320909101546001600160a01b0316835282019290925260400190205582620006d1816200153c565b93505062000679565b600091505b600c54821015620007bb576000600c8381548110620007025762000702620014ec565b60009182526020808320909101546001600160a01b0316808352600f9091526040822082905590945090505b600b54841015620007a5576001600160a01b0381166000908152601060205260408120600b8054839190889081106200076b576200076b620014ec565b60009182526020808320909101546001600160a01b03168352820192909252604001902055836200079c816200153c565b9450506200072e565b5081620007b2816200153c565b925050620006df565b600b8054600181019091557f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90180546001600160a01b0319166001600160a01b0387169081179091556000908152600d6020526040902061ffff8516908190556009546200082a919062001558565b600955604080516001600160a01b038716815261ffff861660208201527fefb20bd7b432b3f89ef344f5dd4dbc10c62729e41df4363592a810661c8c7ae4910160405180910390a15b5050505050565b3390565b601180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382161115620009405760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401620002e1565b6001600160a01b038216620009985760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620002e1565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601255565b6001600160a01b03163b151590565b60005b600b5481101562000acb5760005b600c5481101562000a80576000600c828154811062000a145762000a14620014ec565b9060005260206000200160009054906101000a90046001600160a01b0316905062000a6a81600b858154811062000a4f5762000a4f620014ec565b6000918252602090912001546001600160a01b031662000ace565b508062000a77816200153c565b915050620009f1565b5062000ab6600b828154811062000a9b5762000a9b620014ec565b6000918252602090912001546001600160a01b031662000d39565b8062000ac2816200153c565b915050620009e3565b50565b6001600160a01b0382166000908152600f60205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa15801562000b2c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b5291906200156e565b62000b5e919062001558565b9050600062000b7a838362000b74878362000e3b565b62000e68565b6040516370a0823160e01b81523060048201529091506001600160a01b038516906370a0823190602401602060405180830381865afa15801562000bc2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000be891906200156e565b81111562000c5e576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa15801562000c35573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c5b91906200156e565b90505b801562000d33576001600160a01b0380851660009081526010602090815260408083209387168352929052908120805483929062000c9e90849062001558565b90915550506001600160a01b0384166000908152600f60205260408120805483929062000ccd90849062001558565b9250508190555062000cec84848362000ecd60201b6200293e1760201c565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a25b50505050565b600062000d45600a5490565b62000d51904762001558565b9050600062000d7b838362000b74826001600160a01b03166000908152600e602052604090205490565b90504781111562000d895750475b801562000e36576001600160a01b0383166000908152600e60205260408120805483929062000dba90849062001558565b9250508190555080600a600082825462000dd5919062001558565b9250508190555062000df3838262000f2560201b620029c31760201c565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15b505050565b6001600160a01b038083166000908152601060209081526040808320938516835292905220545b92915050565b60008060095460000362000e7f5750600062000ec5565b6009546001600160a01b0386166000908152600d602052604090205484919062000eaa908762001588565b62000eb69190620015a2565b62000ec29190620015c5565b90505b949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000e369185916200104416565b8047101562000f775760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401620002e1565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811462000fc6576040519150601f19603f3d011682016040523d82523d6000602084013e62000fcb565b606091505b505090508062000e365760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401620002e1565b6000620010a0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200112260201b62002adc179092919060201c565b80519091501562000e365780806020019051810190620010c19190620015db565b62000e365760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620002e1565b606062000ec5848460008585600080866001600160a01b031685876040516200114c91906200162c565b60006040518083038185875af1925050503d80600081146200118b576040519150601f19603f3d011682016040523d82523d6000602084013e62001190565b606091505b509092509050620011a487838387620011af565b979650505050505050565b60608315620012235782516000036200121b576001600160a01b0385163b6200121b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620002e1565b508162000ec5565b62000ec583838151156200123a5781518083602001fd5b8060405162461bcd60e51b8152600401620002e191906200164a565b828054828255906000526020600020908101928215620012ae579160200282015b82811115620012ae57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062001277565b50620012bc92915062001365565b5090565b82805482825590600052602060002090600f01601090048101928215620012ae5791602002820160005b838211156200132b57835183826101000a81548161ffff021916908360ff1602179055509260200192600201602081600101049283019260010302620012ea565b80156200135b5782816101000a81549061ffff02191690556002016020816001010492830192600103026200132b565b5050620012bc9291505b5b80821115620012bc576000815560010162001366565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620013a757607f821691505b602082108103620013c857634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000e3657600081815260208120601f850160051c81016020861015620013f75750805b601f850160051c820191505b81811015620014185782815560010162001403565b505050505050565b81516001600160401b038111156200143c576200143c6200137c565b62001454816200144d845462001392565b84620013ce565b602080601f8311600181146200148c5760008415620014735750858301515b600019600386901b1c1916600185901b17855562001418565b600085815260208120601f198616915b82811015620014bd578886015182559484019460019091019084016200149c565b5085821015620014dc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600061ffff80831681810362001532576200153262001502565b6001019392505050565b60006001820162001551576200155162001502565b5060010190565b8082018082111562000e625762000e6262001502565b6000602082840312156200158157600080fd5b5051919050565b808202811582820484141762000e625762000e6262001502565b600082620015c057634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111562000e625762000e6262001502565b600060208284031215620015ee57600080fd5b81518015158114620015ff57600080fd5b9392505050565b60005b838110156200162357818101518382015260200162001609565b50506000910152565b600082516200164081846020870162001606565b9190910192915050565b60208152600082518060208401526200166b81604085016020870162001606565b601f01601f19169190910160400192915050565b614c47806200168f6000396000f3fe6080604052600436106103b15760003560e01c80635c975abb116101e7578063a3e82e1f1161010d578063c87b56dd116100a0578063d5abeb011161006f578063d5abeb0114610bb4578063e33b7de314610bcf578063e985e9c514610be4578063f2fde38b14610c2d57600080fd5b8063c87b56dd14610b19578063ce7c2ac214610b39578063d10a1a2b14610b6f578063d48bfca714610b9457600080fd5b8063b88d4fde116100dc578063b88d4fde14610a9a578063baa51f8614610aad578063c48fa41214610ade578063c793803c14610afe57600080fd5b8063a3e82e1f14610a14578063a694fc3a14610a34578063a96533e914610a54578063b440ff7a14610a8557600080fd5b80637ec2402f1161018557806395d89b411161015457806395d89b41146109895780639852595c1461099e5780639ce8a55b146109d4578063a22cb465146109f457600080fd5b80637ec2402f146109165780638b83209b146109365780638da5cb5b1461095657806394ea82cd1461097457600080fd5b80636c0360eb116101c15780636c0360eb146108ac57806370a08231146108c1578063715018a6146108e1578063796a6996146108f657600080fd5b80635c975abb14610848578063631525c3146108695780636352211e1461088c57600080fd5b806323b872dd116102d75780633ccfd60b1161026a5780634cf088d9116102395780634cf088d9146107a15780634f37cad8146107c2578063505bd3da1461080857806355f804b31461082857600080fd5b80633ccfd60b1461073957806342842e0e1461074e57806344a0d68a146107615780634ac7ef121461078157600080fd5b80632806b8fb116102a65780632806b8fb1461069e5780632a55205a146106c55780632e17de78146107045780633a98ef391461072457600080fd5b806323b872dd1461062157806323cf0a221461063457806324180d741461064757806324a6ab0c1461067d57600080fd5b806311164f541161034f578063171a80dc1161031e578063171a80dc1461057f57806318160ddd1461059f57806319165587146105bc5780631e7269c5146105dc57600080fd5b806311164f541461050457806311d4bc9a1461052657806313faede61461053b57806316c38b3c1461055f57600080fd5b806306421c2f1161038b57806306421c2f1461047757806306fdde0314610497578063081812fc146104b9578063095ea7b3146104f157600080fd5b806301ffc9a7146103ff57806302ff42211461043457806304634d8d1461045557600080fd5b366103fa577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561040b57600080fd5b5061041f61041a36600461443d565b610c4d565b60405190151581526020015b60405180910390f35b34801561044057600080fd5b5060115461041f90600160a01b900460ff1681565b34801561046157600080fd5b5061047561047036600461446f565b610c5e565b005b34801561048357600080fd5b506104756104923660046144c9565b610c74565b3480156104a357600080fd5b506104ac610d71565b60405161042b9190614536565b3480156104c557600080fd5b506104d96104d4366004614549565b610e03565b6040516001600160a01b03909116815260200161042b565b6104756104ff366004614562565b610e60565b34801561051057600080fd5b50610519610f26565b60405161042b919061458e565b34801561053257600080fd5b50610475610f87565b34801561054757600080fd5b5061055160155481565b60405190815260200161042b565b34801561056b57600080fd5b5061047561057a3660046145e9565b610f9f565b34801561058b57600080fd5b5061047561059a3660046144c9565b610fe0565b3480156105ab57600080fd5b506001546000540360001901610551565b3480156105c857600080fd5b506104756105d7366004614606565b61108b565b3480156105e857600080fd5b5061060e6105f7366004614606565b6102006020526000908152604090205461ffff1681565b60405161ffff909116815260200161042b565b61047561062f366004614623565b611101565b6104756106423660046144c9565b611275565b34801561065357600080fd5b50610551610662366004614606565b6001600160a01b03166000908152600f602052604090205490565b34801561068957600080fd5b5060165461060e9062010000900461ffff1681565b3480156106aa57600080fd5b5060165461060e9068010000000000000000900461ffff1681565b3480156106d157600080fd5b506106e56106e0366004614664565b611b4c565b604080516001600160a01b03909316835260208301919091520161042b565b34801561071057600080fd5b5061047561071f366004614549565b611c07565b34801561073057600080fd5b50600954610551565b34801561074557600080fd5b50610475611c99565b61047561075c366004614623565b611cb5565b34801561076d57600080fd5b5061047561077c366004614549565b611e1e565b34801561078d57600080fd5b5061047561079c366004614686565b611e2b565b3480156107ad57600080fd5b50610203546104d9906001600160a01b031681565b3480156107ce57600080fd5b506105516107dd3660046146b4565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205490565b34801561081457600080fd5b5061060e610823366004614606565b611e41565b34801561083457600080fd5b50610475610843366004614781565b6121c1565b34801561085457600080fd5b506101fe5461041f9062010000900460ff1681565b34801561087557600080fd5b5060165461060e90640100000000900461ffff1681565b34801561089857600080fd5b506104d96108a7366004614549565b612229565b3480156108b857600080fd5b506104ac612234565b3480156108cd57600080fd5b506105516108dc366004614606565b6122c2565b3480156108ed57600080fd5b5061047561232a565b34801561090257600080fd5b506104756109113660046146b4565b61233c565b34801561092257600080fd5b506101fe5461041f90610100900460ff1681565b34801561094257600080fd5b506104d9610951366004614549565b6123b0565b34801561096257600080fd5b506011546001600160a01b03166104d9565b34801561098057600080fd5b506105196123e0565b34801561099557600080fd5b506104ac612440565b3480156109aa57600080fd5b506105516109b9366004614606565b6001600160a01b03166000908152600e602052604090205490565b3480156109e057600080fd5b506104756109ef366004614686565b61244f565b348015610a0057600080fd5b50610475610a0f3660046147ca565b612461565b348015610a2057600080fd5b50610475610a2f3660046144c9565b6124cd565b348015610a4057600080fd5b50610475610a4f366004614549565b612574565b348015610a6057600080fd5b5061041f610a6f366004614549565b6101ff6020526000908152604090205460ff1681565b348015610a9157600080fd5b50610475612609565b610475610aa83660046147f8565b612640565b348015610ab957600080fd5b5061041f610ac8366004614549565b60009081526101ff602052604090205460ff1690565b348015610aea57600080fd5b50610475610af93660046145e9565b6127b7565b348015610b0a57600080fd5b506101fe5461041f9060ff1681565b348015610b2557600080fd5b506104ac610b34366004614549565b6127f4565b348015610b4557600080fd5b50610551610b54366004614606565b6001600160a01b03166000908152600d602052604090205490565b348015610b7b57600080fd5b5060165461060e906601000000000000900461ffff1681565b348015610ba057600080fd5b50610475610baf366004614606565b612891565b348015610bc057600080fd5b5060165461060e9061ffff1681565b348015610bdb57600080fd5b50600a54610551565b348015610bf057600080fd5b5061041f610bff3660046146b4565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610c3957600080fd5b50610475610c48366004614606565b6128a2565b6000610c5882612af3565b92915050565b610c66612b8a565b610c708282612be4565b5050565b610c7c612b8a565b6101fe54610100900460ff1615610cda5760405162461bcd60e51b815260206004820152601d60248201527f57617272696f723a204d617820737570706c792069732066726f7a656e00000060448201526064015b60405180910390fd5b60165461ffff90811690821610610d595760405162461bcd60e51b815260206004820152603760248201527f57617272696f723a204e6577206d6178696d756d206d757374206265206c657360448201527f73207468616e206578697374696e67206d6178696d756d0000000000000000006064820152608401610cd1565b6016805461ffff191661ffff92909216919091179055565b606060028054610d8090614878565b80601f0160208091040260200160405190810160405280929190818152602001828054610dac90614878565b8015610df95780601f10610dce57610100808354040283529160200191610df9565b820191906000526020600020905b815481529060010190602001808311610ddc57829003601f168201915b5050505050905090565b6000610e0e82612cfe565b610e44576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610e6b82612229565b9050336001600160a01b03821614610ebd57610e878133610bff565b610ebd576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6060600b805480602002602001604051908101604052809291908181526020018280548015610df957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610f60575050505050905090565b610f8f612b8a565b6101fe805460ff19166001179055565b610fa7612b8a565b6101fe805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b610fe8612b8a565b60165461ffff680100000000000000009091048116908216101561104e5760405162461bcd60e51b815260206004820152601060248201527f57617272696f723a20746f6f206c6f77000000000000000000000000000000006044820152606401610cd1565b6016805461ffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff909216919091179055565b611093612d4c565b6001600160a01b0381163b156110eb5760405162461bcd60e51b815260206004820152601560248201527f57617272696f723a206e6f20636f6e74726163747300000000000000000000006044820152606401610cd1565b6110f481612da5565b6110fe6001600855565b50565b6011548390600160a01b900460ff16801561112a57506daaeb6d7670e522a718067333cd4e3b15155b1561126457336001600160a01b0382160361114f5761114a848484612e92565b61126f565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561119e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c291906148b2565b80156112455750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611221573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124591906148b2565b61126457604051633b79c77360e21b8152336004820152602401610cd1565b61126f848484612e92565b50505050565b61127d612d4c565b600061128833611e41565b9050606060008080333b156112df5760405162461bcd60e51b815260206004820152601560248201527f57617272696f723a206e6f20636f6e74726163747300000000000000000000006044820152606401610cd1565b6101fe5462010000900460ff16158061130257506011546001600160a01b031633145b61134e5760405162461bcd60e51b815260206004820181905260248201527f57617272696f723a204d696e74696e67206e6f742073746172746564207965746044820152606401610cd1565b60165460015460005461ffff9283169289169190036000190161137191906148e5565b11156113e55760405162461bcd60e51b815260206004820152602860248201527f57617272696f723a2043616e2774206d696e74206d6f7265207468616e206d6160448201527f7820737570706c790000000000000000000000000000000000000000000000006064820152608401610cd1565b6011546001600160a01b0316331480611411575073a4d89eb5388613a9bf7ed0eaff5fd2c05a4b34e333145b15611449576016805461ffff6801000000000000000080830482168a019091160269ffff000000000000000019909116179055611b0b565b61ffff85161561197e578461ffff168661ffff161115611467578495505b610203546040517fe1fcd8a900000000000000000000000000000000000000000000000000000000815233600482015287916001600160a01b03169063e1fcd8a990602401602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed91906148f8565b9250821561166657610203546040517f21130faf0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03909116906321130faf90602401600060405180830381865afa158015611557573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261157f9190810190614911565b9450600093505b828461ffff1610156116665760008161ffff161180156115f357506017858561ffff16815181106115b9576115b96149c3565b602002602001015161ffff16611e6181106115d6576115d66149c3565b601081049190910154600f9091166002026101000a900461ffff16155b1561165b5760016017868661ffff1681518110611612576116126149c3565b602002602001015161ffff16611e61811061162f5761162f6149c3565b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506001810390505b600190930192611586565b610203546040517f018ea6d40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063018ea6d490602401602060405180830381865afa1580156116c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ec91906148f8565b9150811561193757610203546040517f2f1741440000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911690632f17414490602401600060405180830381865afa158015611756573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261177e9190810190614911565b9450600093505b818461ffff1610156119375760018161ffff161180156117f257506017858561ffff16815181106117b8576117b86149c3565b602002602001015161ffff16611e6181106117d5576117d56149c3565b601081049190910154600f9091166002026101000a900461ffff16155b1561185e5760026017868661ffff1681518110611811576118116149c3565b602002602001015161ffff16611e61811061182e5761182e6149c3565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060028103905061192c565b60008161ffff161180156118c457506017858561ffff1681518110611885576118856149c3565b602002602001015161ffff16611e6181106118a2576118a26149c3565b601091828204019190066002029054906101000a900461ffff1661ffff166001145b1561192c5760026017868661ffff16815181106118e3576118e36149c3565b602002602001015161ffff16611e618110611900576119006149c3565b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506001810390505b600190930192611785565b506016805461ffff660100000000000080830482168a01909116027fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff909116179055611b0b565b60165461ffff6401000000008204811668010000000000000000909204161015611ac35760165461ffff640100000000820481166801000000000000000090920481168801161115611a125760405162461bcd60e51b815260206004820152601e60248201527f57617272696f723a2043616e6e6f74206d696e742074686973206d616e7900006044820152606401610cd1565b8561ffff1660155402341015611a905760405162461bcd60e51b815260206004820152602160248201527f57617272696f723a20596f75206d7573742070617920666f7220746865206e6660448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610cd1565b6016805461ffff6801000000000000000080830482168a019091160269ffff000000000000000019909116179055611b0b565b60405162461bcd60e51b815260206004820152601f60248201527f57617272696f723a206e6f6e6520617661696c61626c6520746f206d696e74006044820152606401610cd1565b33600081815261020060205260409020805461ffff19811661ffff9182168a01821617909155611b3d919088166130b6565b50505050506110fe6001600855565b60008281526013602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046bffffffffffffffffffffffff16928201929092528291611bcb5750604080518082019091526012546001600160a01b0381168252600160a01b90046bffffffffffffffffffffffff1660208201525b602081015160009061271090611bef906bffffffffffffffffffffffff16876149d9565b611bf991906149f0565b915196919550909350505050565b611c0f612d4c565b611c1881612229565b6001600160a01b0316336001600160a01b031614611c785760405162461bcd60e51b815260206004820181905260248201527f57617272696f723a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b60008181526101ff60205260409020805460ff191690556110fe6001600855565b611ca1612d4c565b611ca96130d0565b611cb36001600855565b565b6011548390600160a01b900460ff168015611cde57506daaeb6d7670e522a718067333cd4e3b15155b15611e1357336001600160a01b03821603611cfe5761114a8484846131a6565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7191906148b2565b8015611df45750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df491906148b2565b611e1357604051633b79c77360e21b8152336004820152602401610cd1565b61126f8484846131a6565b611e26612b8a565b601555565b611e33612b8a565b610c70828261ffff166131c1565b610203546040517fe1fcd8a90000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092839283929091169063e1fcd8a990602401602060405180830381865afa158015611eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed091906148f8565b610203546040517f018ea6d40000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301529293506000929091169063018ea6d490602401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e91906148f8565b905060606000831561206957610203546040517f21130faf0000000000000000000000000000000000000000000000000000000081526001600160a01b038981166004830152909116906321130faf90602401600060405180830381865afa158015611fce573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ff69190810190614911565b9150600090505b838161ffff161015612069576017828261ffff1681518110612021576120216149c3565b602002602001015161ffff16611e61811061203e5761203e6149c3565b601081049190910154600f9091166002026101000a900461ffff166001908103959095019401611ffd565b821561216e57610203546040517f2f1741440000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015290911690632f17414490602401600060405180830381865afa1580156120d3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120fb9190810190614911565b9150600090505b828161ffff16101561216e576017828261ffff1681518110612126576121266149c3565b602002602001015161ffff16611e618110612143576121436149c3565b601081049091015461ffff6002600f90931683026101000a9091041690039490940193600101612102565b60165461ffff66010000000000008204811662010000909204811691909103811690861611156121b65760165461ffff66010000000000008204811662010000909204160394505b509295945050505050565b6121c9612b8a565b6101fe5460ff161561221d5760405162461bcd60e51b815260206004820152601660248201527f57617272696f723a207572692069732066726f7a656e000000000000000000006044820152606401610cd1565b6014610c708282614a58565b6000610c588261349e565b6014805461224190614878565b80601f016020809104026020016040519081016040528092919081815260200182805461226d90614878565b80156122ba5780601f1061228f576101008083540402835291602001916122ba565b820191906000526020600020905b81548152906001019060200180831161229d57829003601f168201915b505050505081565b60006001600160a01b038216612304576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b612332612b8a565b611cb3600061353f565b612344612d4c565b6001600160a01b0381163b1561239c5760405162461bcd60e51b815260206004820152601560248201527f57617272696f723a206e6f20636f6e74726163747300000000000000000000006044820152606401610cd1565b6123a6828261359e565b610c706001600855565b6000600b82815481106123c5576123c56149c3565b6000918252602090912001546001600160a01b031692915050565b6060600c805480602002602001604051908101604052809291908181526020018280548015610df9576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610f60575050505050905090565b606060038054610d8090614878565b612457612b8a565b610c708282613806565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6124d5612b8a565b60165461ffff6601000000000000909104811690821610156125395760405162461bcd60e51b815260206004820152601060248201527f57617272696f723a20746f6f206c6f77000000000000000000000000000000006044820152606401610cd1565b6016805461ffff90921662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff909216919091179055565b61257c612d4c565b61258581612229565b6001600160a01b0316336001600160a01b0316146125e55760405162461bcd60e51b815260206004820181905260248201527f57617272696f723a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b60008181526101ff60205260409020805460ff191660011790556110fe6001600855565b612611612b8a565b6101fe80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b6011548490600160a01b900460ff16801561266957506daaeb6d7670e522a718067333cd4e3b15155b156127a457336001600160a01b0382160361268f5761268a85858585613b2c565b6127b0565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156126de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270291906148b2565b80156127855750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278591906148b2565b6127a457604051633b79c77360e21b8152336004820152602401610cd1565b6127b085858585613b2c565b5050505050565b6127bf612b8a565b601180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b8315150217905550565b60606127ff82612cfe565b612835576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061283f613b70565b9050805160000361285f576040518060200160405280600081525061288a565b8061286984613b7f565b60405160200161287a929190614b18565b6040516020818303038152906040525b9392505050565b612899612b8a565b6110fe81613bc3565b6128aa612b8a565b6001600160a01b0381166129265760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610cd1565b6110fe8161353f565b6001600160a01b03163b151590565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526129be908490613dde565b505050565b80471015612a135760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610cd1565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612a60576040519150601f19603f3d011682016040523d82523d6000602084013e612a65565b606091505b50509050806129be5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610cd1565b6060612aeb8484600085613ec3565b949350505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a000000000000000000000000000000000000000000000000000000001480610c5857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610c58565b6011546001600160a01b03163314611cb35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b6127106bffffffffffffffffffffffff82161115612c6a5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610cd1565b6001600160a01b038216612cc05760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610cd1565b604080518082019091526001600160a01b039092168083526bffffffffffffffffffffffff9091166020909201829052600160a01b90910217601255565b600081600111158015612d12575060005482105b8015610c585750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b600260085403612d9e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cd1565b6002600855565b6000612db0600a5490565b612dba90476148e5565b90506000612de78383612de2866001600160a01b03166000908152600e602052604090205490565b613fb5565b905047811115612df45750475b80156129be576001600160a01b0383166000908152600e602052604081208054839290612e229084906148e5565b9250508190555080600a6000828254612e3b91906148e5565b90915550612e4b905083826129c3565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b6000612e9d8261349e565b9050836001600160a01b0316816001600160a01b031614612eea576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417612f5057612f1a8633610bff565b612f50576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516612f90576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612f9d8686866001614010565b8015612fa857600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b177c0200000000000000000000000000000000000000000000000000000000176000858152600460205260408120919091557c02000000000000000000000000000000000000000000000000000000008416900361306c5760018401600081815260046020526040812054900361306a57600054811461306a5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b610c70828260405180602001604052806000815250614096565b60005b600b548110156110fe5760005b600c54811015613163576000600c82815481106130ff576130ff6149c3565b9060005260206000200160009054906101000a90046001600160a01b0316905061315081600b8581548110613136576131366149c3565b6000918252602090912001546001600160a01b031661359e565b508061315b81614b6f565b9150506130e0565b50613194600b828154811061317a5761317a6149c3565b6000918252602090912001546001600160a01b0316612da5565b8061319e81614b6f565b9150506130d3565b6129be83838360405180602001604052806000815250612640565b60008080805b600b5484101561321e57856001600160a01b0316600b85815481106131ee576131ee6149c3565b6000918252602090912001546001600160a01b03160361320c575060015b8361321681614b6f565b9450506131c7565b806001146132945760405162461bcd60e51b815260206004820152603660248201527f5061796d656e7453706c69747465723a20706179656520646f6573206e6f742060448201527f65786973742c20616464207061796565206669727374000000000000000000006064820152608401610cd1565b6001600160a01b0386166000908152600d602052604090205460095486916132bb91614b89565b6132c591906148e5565b91506000821161333d5760405162461bcd60e51b815260206004820152603460248201527f5061796d656e7453706c69747465723a20746f74616c20736861726573206d7560448201527f73742062652067726561746572207468616e20300000000000000000000000006064820152608401610cd1565b6133456130d0565b6000600a81905593505b600b548410156133a9576000600e6000600b8781548110613372576133726149c3565b60009182526020808320909101546001600160a01b03168352820192909252604001902055836133a181614b6f565b94505061334f565b600092505b600c5483101561347c576000600c84815481106133cd576133cd6149c3565b60009182526020808320909101546001600160a01b0316808352600f9091526040822082905590955090505b600b54851015613469576001600160a01b0381166000908152601060205260408120600b805483919089908110613432576134326149c3565b60009182526020808320909101546001600160a01b031683528201929092526040019020558461346181614b6f565b9550506133f9565b508261347481614b6f565b9350506133ae565b5060095550506001600160a01b039091166000908152600d6020526040902055565b6000818060011161350d5760005481101561350d57600081815260046020526040812054907c01000000000000000000000000000000000000000000000000000000008216900361350b575b8060000361288a5750600019016000818152600460205260409020546134ea565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166000908152600f60205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa1580156135fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361f91906148f8565b61362991906148e5565b905060006136628383612de287876001600160a01b03918216600090815260106020908152604080832093909416825291909152205490565b6040516370a0823160e01b81523060048201529091506001600160a01b038516906370a0823190602401602060405180830381865afa1580156136a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136cd91906148f8565b81111561373f576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015613718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373c91906148f8565b90505b801561126f576001600160a01b0380851660009081526010602090815260408083209387168352929052908120805483929061377c9084906148e5565b90915550506001600160a01b0384166000908152600f6020526040812080548392906137a99084906148e5565b909155506137ba905084848361293e565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b6000806001600160a01b0384163b156138615760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a206e6f20636f6e7472616374730000006044820152606401610cd1565b60008361ffff16116138b55760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610cd1565b60008092505b600b5483101561391257846001600160a01b0316600b84815481106138e2576138e26149c3565b6000918252602090912001546001600160a01b031603613900575060015b8261390a81614b6f565b9350506138bb565b806000036127b05761ffff841615613a635761392c6130d0565b6000600a81905592505b600b54831015613990576000600e6000600b8681548110613959576139596149c3565b60009182526020808320909101546001600160a01b031683528201929092526040019020558261398881614b6f565b935050613936565b600091505b600c54821015613a63576000600c83815481106139b4576139b46149c3565b60009182526020808320909101546001600160a01b0316808352600f9091526040822082905590945090505b600b54841015613a50576001600160a01b0381166000908152601060205260408120600b805483919088908110613a1957613a196149c3565b60009182526020808320909101546001600160a01b0316835282019290925260400190205583613a4881614b6f565b9450506139e0565b5081613a5b81614b6f565b925050613995565b600b8054600181019091557f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db901805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387169081179091556000908152600d6020526040902061ffff851690819055600954613add91906148e5565b600955604080516001600160a01b038716815261ffff861660208201527fefb20bd7b432b3f89ef344f5dd4dbc10c62729e41df4363592a810661c8c7ae4910160405180910390a15050505050565b613b37848484611101565b6001600160a01b0383163b1561126f57613b53848484846140fc565b61126f576040516368d2bf6b60e11b815260040160405180910390fd5b606060148054610d8090614878565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a900480613b995750819003601f19909101908152919050565b60016001600160a01b0382163b151514613c455760405162461bcd60e51b815260206004820152602360248201527f5061796d656e7453706c69747465723a206d757374206265206120636f6e747260448201527f61637400000000000000000000000000000000000000000000000000000000006064820152608401610cd1565b6040516370a0823160e01b81523060048201526001600160a01b038216906370a0823190602401602060405180830381865afa158015613c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cad91906148f8565b506000805b600c54811015613d0a57826001600160a01b0316600c8281548110613cd957613cd96149c3565b6000918252602090912001546001600160a01b031603613cf857600191505b80613d0281614b6f565b915050613cb2565b508015613d7e5760405162461bcd60e51b8152602060048201526024808201527f5061796d656e7453706c69747465723a20746f6b656e20616c7265616479206160448201527f64646564000000000000000000000000000000000000000000000000000000006064820152608401610cd1565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000613e33826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612adc9092919063ffffffff16565b8051909150156129be5780806020019051810190613e5191906148b2565b6129be5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610cd1565b606082471015613f3b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610cd1565b600080866001600160a01b03168587604051613f579190614b9c565b60006040518083038185875af1925050503d8060008114613f94576040519150601f19603f3d011682016040523d82523d6000602084013e613f99565b606091505b5091509150613faa8783838761422e565b979650505050505050565b600080600954600003613fca57506000612aeb565b6009546001600160a01b0386166000908152600d6020526040902054849190613ff390876149d9565b613ffd91906149f0565b6140079190614b89565b95945050505050565b60008281526101ff602052604090205460ff161561126f5760405162461bcd60e51b815260206004820152602b60248201527f57617272696f722c2063616e6e6f74207472616e73666572202d20637572726560448201527f6e746c79206c6f636b65640000000000000000000000000000000000000000006064820152608401610cd1565b6140a083836142a7565b6001600160a01b0383163b156129be576000548281035b6140ca60008683806001019450866140fc565b6140e7576040516368d2bf6b60e11b815260040160405180910390fd5b8181106140b75781600054146127b057600080fd5b6040517f150b7a020000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063150b7a029061414a903390899088908890600401614bb8565b6020604051808303816000875af1925050508015614185575060408051601f3d908101601f1916820190925261418291810190614bf4565b60015b6141e3573d8080156141b3576040519150601f19603f3d011682016040523d82523d6000602084013e6141b8565b606091505b5080516000036141db576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050612aeb565b6060831561429d578251600003614296576001600160a01b0385163b6142965760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cd1565b5081612aeb565b612aeb83836143e5565b60008054908290036142e5576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142f26000848385614010565b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146143a157808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101614369565b50816000036143dc576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b8151156143f55781518083602001fd5b8060405162461bcd60e51b8152600401610cd19190614536565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146110fe57600080fd5b60006020828403121561444f57600080fd5b813561288a8161440f565b6001600160a01b03811681146110fe57600080fd5b6000806040838503121561448257600080fd5b823561448d8161445a565b915060208301356bffffffffffffffffffffffff811681146144ae57600080fd5b809150509250929050565b61ffff811681146110fe57600080fd5b6000602082840312156144db57600080fd5b813561288a816144b9565b60005b838110156145015781810151838201526020016144e9565b50506000910152565b600081518084526145228160208601602086016144e6565b601f01601f19169290920160200192915050565b60208152600061288a602083018461450a565b60006020828403121561455b57600080fd5b5035919050565b6000806040838503121561457557600080fd5b82356145808161445a565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b818110156145cf5783516001600160a01b0316835292840192918401916001016145aa565b50909695505050505050565b80151581146110fe57600080fd5b6000602082840312156145fb57600080fd5b813561288a816145db565b60006020828403121561461857600080fd5b813561288a8161445a565b60008060006060848603121561463857600080fd5b83356146438161445a565b925060208401356146538161445a565b929592945050506040919091013590565b6000806040838503121561467757600080fd5b50508035926020909101359150565b6000806040838503121561469957600080fd5b82356146a48161445a565b915060208301356144ae816144b9565b600080604083850312156146c757600080fd5b82356146d28161445a565b915060208301356144ae8161445a565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614721576147216146e2565b604052919050565b600067ffffffffffffffff831115614743576147436146e2565b6147566020601f19601f860116016146f8565b905082815283838301111561476a57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561479357600080fd5b813567ffffffffffffffff8111156147aa57600080fd5b8201601f810184136147bb57600080fd5b612aeb84823560208401614729565b600080604083850312156147dd57600080fd5b82356147e88161445a565b915060208301356144ae816145db565b6000806000806080858703121561480e57600080fd5b84356148198161445a565b935060208501356148298161445a565b925060408501359150606085013567ffffffffffffffff81111561484c57600080fd5b8501601f8101871361485d57600080fd5b61486c87823560208401614729565b91505092959194509250565b600181811c9082168061488c57607f821691505b6020821081036148ac57634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156148c457600080fd5b815161288a816145db565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c5857610c586148cf565b60006020828403121561490a57600080fd5b5051919050565b6000602080838503121561492457600080fd5b825167ffffffffffffffff8082111561493c57600080fd5b818501915085601f83011261495057600080fd5b815181811115614962576149626146e2565b8060051b91506149738483016146f8565b818152918301840191848101908884111561498d57600080fd5b938501935b838510156149b757845192506149a7836144b9565b8282529385019390850190614992565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417610c5857610c586148cf565b600082614a0d57634e487b7160e01b600052601260045260246000fd5b500490565b601f8211156129be57600081815260208120601f850160051c81016020861015614a395750805b601f850160051c820191505b818110156130ae57828155600101614a45565b815167ffffffffffffffff811115614a7257614a726146e2565b614a8681614a808454614878565b84614a12565b602080601f831160018114614abb5760008415614aa35750858301515b600019600386901b1c1916600185901b1785556130ae565b600085815260208120601f198616915b82811015614aea57888601518255948401946001909101908401614acb565b5085821015614b085787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008351614b2a8184602088016144e6565b835190830190614b3e8183602088016144e6565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000009101908152600501949350505050565b60006000198203614b8257614b826148cf565b5060010190565b81810381811115610c5857610c586148cf565b60008251614bae8184602087016144e6565b9190910192915050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152614bea608083018461450a565b9695505050505050565b600060208284031215614c0657600080fd5b815161288a8161440f56fea26469706673582212203cfa432c67c2e27fbd47eca6ba4517bdd1d950b7d77030549207242e2642b47264736f6c63430008110033697066733a2f2f516d4e71456e78436a506964537461684453345650644c6966636548455835594243714e396b5a484653595050352f

Deployed Bytecode

0x6080604052600436106103b15760003560e01c80635c975abb116101e7578063a3e82e1f1161010d578063c87b56dd116100a0578063d5abeb011161006f578063d5abeb0114610bb4578063e33b7de314610bcf578063e985e9c514610be4578063f2fde38b14610c2d57600080fd5b8063c87b56dd14610b19578063ce7c2ac214610b39578063d10a1a2b14610b6f578063d48bfca714610b9457600080fd5b8063b88d4fde116100dc578063b88d4fde14610a9a578063baa51f8614610aad578063c48fa41214610ade578063c793803c14610afe57600080fd5b8063a3e82e1f14610a14578063a694fc3a14610a34578063a96533e914610a54578063b440ff7a14610a8557600080fd5b80637ec2402f1161018557806395d89b411161015457806395d89b41146109895780639852595c1461099e5780639ce8a55b146109d4578063a22cb465146109f457600080fd5b80637ec2402f146109165780638b83209b146109365780638da5cb5b1461095657806394ea82cd1461097457600080fd5b80636c0360eb116101c15780636c0360eb146108ac57806370a08231146108c1578063715018a6146108e1578063796a6996146108f657600080fd5b80635c975abb14610848578063631525c3146108695780636352211e1461088c57600080fd5b806323b872dd116102d75780633ccfd60b1161026a5780634cf088d9116102395780634cf088d9146107a15780634f37cad8146107c2578063505bd3da1461080857806355f804b31461082857600080fd5b80633ccfd60b1461073957806342842e0e1461074e57806344a0d68a146107615780634ac7ef121461078157600080fd5b80632806b8fb116102a65780632806b8fb1461069e5780632a55205a146106c55780632e17de78146107045780633a98ef391461072457600080fd5b806323b872dd1461062157806323cf0a221461063457806324180d741461064757806324a6ab0c1461067d57600080fd5b806311164f541161034f578063171a80dc1161031e578063171a80dc1461057f57806318160ddd1461059f57806319165587146105bc5780631e7269c5146105dc57600080fd5b806311164f541461050457806311d4bc9a1461052657806313faede61461053b57806316c38b3c1461055f57600080fd5b806306421c2f1161038b57806306421c2f1461047757806306fdde0314610497578063081812fc146104b9578063095ea7b3146104f157600080fd5b806301ffc9a7146103ff57806302ff42211461043457806304634d8d1461045557600080fd5b366103fa577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561040b57600080fd5b5061041f61041a36600461443d565b610c4d565b60405190151581526020015b60405180910390f35b34801561044057600080fd5b5060115461041f90600160a01b900460ff1681565b34801561046157600080fd5b5061047561047036600461446f565b610c5e565b005b34801561048357600080fd5b506104756104923660046144c9565b610c74565b3480156104a357600080fd5b506104ac610d71565b60405161042b9190614536565b3480156104c557600080fd5b506104d96104d4366004614549565b610e03565b6040516001600160a01b03909116815260200161042b565b6104756104ff366004614562565b610e60565b34801561051057600080fd5b50610519610f26565b60405161042b919061458e565b34801561053257600080fd5b50610475610f87565b34801561054757600080fd5b5061055160155481565b60405190815260200161042b565b34801561056b57600080fd5b5061047561057a3660046145e9565b610f9f565b34801561058b57600080fd5b5061047561059a3660046144c9565b610fe0565b3480156105ab57600080fd5b506001546000540360001901610551565b3480156105c857600080fd5b506104756105d7366004614606565b61108b565b3480156105e857600080fd5b5061060e6105f7366004614606565b6102006020526000908152604090205461ffff1681565b60405161ffff909116815260200161042b565b61047561062f366004614623565b611101565b6104756106423660046144c9565b611275565b34801561065357600080fd5b50610551610662366004614606565b6001600160a01b03166000908152600f602052604090205490565b34801561068957600080fd5b5060165461060e9062010000900461ffff1681565b3480156106aa57600080fd5b5060165461060e9068010000000000000000900461ffff1681565b3480156106d157600080fd5b506106e56106e0366004614664565b611b4c565b604080516001600160a01b03909316835260208301919091520161042b565b34801561071057600080fd5b5061047561071f366004614549565b611c07565b34801561073057600080fd5b50600954610551565b34801561074557600080fd5b50610475611c99565b61047561075c366004614623565b611cb5565b34801561076d57600080fd5b5061047561077c366004614549565b611e1e565b34801561078d57600080fd5b5061047561079c366004614686565b611e2b565b3480156107ad57600080fd5b50610203546104d9906001600160a01b031681565b3480156107ce57600080fd5b506105516107dd3660046146b4565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205490565b34801561081457600080fd5b5061060e610823366004614606565b611e41565b34801561083457600080fd5b50610475610843366004614781565b6121c1565b34801561085457600080fd5b506101fe5461041f9062010000900460ff1681565b34801561087557600080fd5b5060165461060e90640100000000900461ffff1681565b34801561089857600080fd5b506104d96108a7366004614549565b612229565b3480156108b857600080fd5b506104ac612234565b3480156108cd57600080fd5b506105516108dc366004614606565b6122c2565b3480156108ed57600080fd5b5061047561232a565b34801561090257600080fd5b506104756109113660046146b4565b61233c565b34801561092257600080fd5b506101fe5461041f90610100900460ff1681565b34801561094257600080fd5b506104d9610951366004614549565b6123b0565b34801561096257600080fd5b506011546001600160a01b03166104d9565b34801561098057600080fd5b506105196123e0565b34801561099557600080fd5b506104ac612440565b3480156109aa57600080fd5b506105516109b9366004614606565b6001600160a01b03166000908152600e602052604090205490565b3480156109e057600080fd5b506104756109ef366004614686565b61244f565b348015610a0057600080fd5b50610475610a0f3660046147ca565b612461565b348015610a2057600080fd5b50610475610a2f3660046144c9565b6124cd565b348015610a4057600080fd5b50610475610a4f366004614549565b612574565b348015610a6057600080fd5b5061041f610a6f366004614549565b6101ff6020526000908152604090205460ff1681565b348015610a9157600080fd5b50610475612609565b610475610aa83660046147f8565b612640565b348015610ab957600080fd5b5061041f610ac8366004614549565b60009081526101ff602052604090205460ff1690565b348015610aea57600080fd5b50610475610af93660046145e9565b6127b7565b348015610b0a57600080fd5b506101fe5461041f9060ff1681565b348015610b2557600080fd5b506104ac610b34366004614549565b6127f4565b348015610b4557600080fd5b50610551610b54366004614606565b6001600160a01b03166000908152600d602052604090205490565b348015610b7b57600080fd5b5060165461060e906601000000000000900461ffff1681565b348015610ba057600080fd5b50610475610baf366004614606565b612891565b348015610bc057600080fd5b5060165461060e9061ffff1681565b348015610bdb57600080fd5b50600a54610551565b348015610bf057600080fd5b5061041f610bff3660046146b4565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610c3957600080fd5b50610475610c48366004614606565b6128a2565b6000610c5882612af3565b92915050565b610c66612b8a565b610c708282612be4565b5050565b610c7c612b8a565b6101fe54610100900460ff1615610cda5760405162461bcd60e51b815260206004820152601d60248201527f57617272696f723a204d617820737570706c792069732066726f7a656e00000060448201526064015b60405180910390fd5b60165461ffff90811690821610610d595760405162461bcd60e51b815260206004820152603760248201527f57617272696f723a204e6577206d6178696d756d206d757374206265206c657360448201527f73207468616e206578697374696e67206d6178696d756d0000000000000000006064820152608401610cd1565b6016805461ffff191661ffff92909216919091179055565b606060028054610d8090614878565b80601f0160208091040260200160405190810160405280929190818152602001828054610dac90614878565b8015610df95780601f10610dce57610100808354040283529160200191610df9565b820191906000526020600020905b815481529060010190602001808311610ddc57829003601f168201915b5050505050905090565b6000610e0e82612cfe565b610e44576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610e6b82612229565b9050336001600160a01b03821614610ebd57610e878133610bff565b610ebd576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6060600b805480602002602001604051908101604052809291908181526020018280548015610df957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610f60575050505050905090565b610f8f612b8a565b6101fe805460ff19166001179055565b610fa7612b8a565b6101fe805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b610fe8612b8a565b60165461ffff680100000000000000009091048116908216101561104e5760405162461bcd60e51b815260206004820152601060248201527f57617272696f723a20746f6f206c6f77000000000000000000000000000000006044820152606401610cd1565b6016805461ffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff909216919091179055565b611093612d4c565b6001600160a01b0381163b156110eb5760405162461bcd60e51b815260206004820152601560248201527f57617272696f723a206e6f20636f6e74726163747300000000000000000000006044820152606401610cd1565b6110f481612da5565b6110fe6001600855565b50565b6011548390600160a01b900460ff16801561112a57506daaeb6d7670e522a718067333cd4e3b15155b1561126457336001600160a01b0382160361114f5761114a848484612e92565b61126f565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561119e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c291906148b2565b80156112455750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611221573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124591906148b2565b61126457604051633b79c77360e21b8152336004820152602401610cd1565b61126f848484612e92565b50505050565b61127d612d4c565b600061128833611e41565b9050606060008080333b156112df5760405162461bcd60e51b815260206004820152601560248201527f57617272696f723a206e6f20636f6e74726163747300000000000000000000006044820152606401610cd1565b6101fe5462010000900460ff16158061130257506011546001600160a01b031633145b61134e5760405162461bcd60e51b815260206004820181905260248201527f57617272696f723a204d696e74696e67206e6f742073746172746564207965746044820152606401610cd1565b60165460015460005461ffff9283169289169190036000190161137191906148e5565b11156113e55760405162461bcd60e51b815260206004820152602860248201527f57617272696f723a2043616e2774206d696e74206d6f7265207468616e206d6160448201527f7820737570706c790000000000000000000000000000000000000000000000006064820152608401610cd1565b6011546001600160a01b0316331480611411575073a4d89eb5388613a9bf7ed0eaff5fd2c05a4b34e333145b15611449576016805461ffff6801000000000000000080830482168a019091160269ffff000000000000000019909116179055611b0b565b61ffff85161561197e578461ffff168661ffff161115611467578495505b610203546040517fe1fcd8a900000000000000000000000000000000000000000000000000000000815233600482015287916001600160a01b03169063e1fcd8a990602401602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed91906148f8565b9250821561166657610203546040517f21130faf0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03909116906321130faf90602401600060405180830381865afa158015611557573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261157f9190810190614911565b9450600093505b828461ffff1610156116665760008161ffff161180156115f357506017858561ffff16815181106115b9576115b96149c3565b602002602001015161ffff16611e6181106115d6576115d66149c3565b601081049190910154600f9091166002026101000a900461ffff16155b1561165b5760016017868661ffff1681518110611612576116126149c3565b602002602001015161ffff16611e61811061162f5761162f6149c3565b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506001810390505b600190930192611586565b610203546040517f018ea6d40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063018ea6d490602401602060405180830381865afa1580156116c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ec91906148f8565b9150811561193757610203546040517f2f1741440000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911690632f17414490602401600060405180830381865afa158015611756573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261177e9190810190614911565b9450600093505b818461ffff1610156119375760018161ffff161180156117f257506017858561ffff16815181106117b8576117b86149c3565b602002602001015161ffff16611e6181106117d5576117d56149c3565b601081049190910154600f9091166002026101000a900461ffff16155b1561185e5760026017868661ffff1681518110611811576118116149c3565b602002602001015161ffff16611e61811061182e5761182e6149c3565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060028103905061192c565b60008161ffff161180156118c457506017858561ffff1681518110611885576118856149c3565b602002602001015161ffff16611e6181106118a2576118a26149c3565b601091828204019190066002029054906101000a900461ffff1661ffff166001145b1561192c5760026017868661ffff16815181106118e3576118e36149c3565b602002602001015161ffff16611e618110611900576119006149c3565b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506001810390505b600190930192611785565b506016805461ffff660100000000000080830482168a01909116027fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff909116179055611b0b565b60165461ffff6401000000008204811668010000000000000000909204161015611ac35760165461ffff640100000000820481166801000000000000000090920481168801161115611a125760405162461bcd60e51b815260206004820152601e60248201527f57617272696f723a2043616e6e6f74206d696e742074686973206d616e7900006044820152606401610cd1565b8561ffff1660155402341015611a905760405162461bcd60e51b815260206004820152602160248201527f57617272696f723a20596f75206d7573742070617920666f7220746865206e6660448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610cd1565b6016805461ffff6801000000000000000080830482168a019091160269ffff000000000000000019909116179055611b0b565b60405162461bcd60e51b815260206004820152601f60248201527f57617272696f723a206e6f6e6520617661696c61626c6520746f206d696e74006044820152606401610cd1565b33600081815261020060205260409020805461ffff19811661ffff9182168a01821617909155611b3d919088166130b6565b50505050506110fe6001600855565b60008281526013602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046bffffffffffffffffffffffff16928201929092528291611bcb5750604080518082019091526012546001600160a01b0381168252600160a01b90046bffffffffffffffffffffffff1660208201525b602081015160009061271090611bef906bffffffffffffffffffffffff16876149d9565b611bf991906149f0565b915196919550909350505050565b611c0f612d4c565b611c1881612229565b6001600160a01b0316336001600160a01b031614611c785760405162461bcd60e51b815260206004820181905260248201527f57617272696f723a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b60008181526101ff60205260409020805460ff191690556110fe6001600855565b611ca1612d4c565b611ca96130d0565b611cb36001600855565b565b6011548390600160a01b900460ff168015611cde57506daaeb6d7670e522a718067333cd4e3b15155b15611e1357336001600160a01b03821603611cfe5761114a8484846131a6565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7191906148b2565b8015611df45750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df491906148b2565b611e1357604051633b79c77360e21b8152336004820152602401610cd1565b61126f8484846131a6565b611e26612b8a565b601555565b611e33612b8a565b610c70828261ffff166131c1565b610203546040517fe1fcd8a90000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092839283929091169063e1fcd8a990602401602060405180830381865afa158015611eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed091906148f8565b610203546040517f018ea6d40000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301529293506000929091169063018ea6d490602401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e91906148f8565b905060606000831561206957610203546040517f21130faf0000000000000000000000000000000000000000000000000000000081526001600160a01b038981166004830152909116906321130faf90602401600060405180830381865afa158015611fce573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ff69190810190614911565b9150600090505b838161ffff161015612069576017828261ffff1681518110612021576120216149c3565b602002602001015161ffff16611e61811061203e5761203e6149c3565b601081049190910154600f9091166002026101000a900461ffff166001908103959095019401611ffd565b821561216e57610203546040517f2f1741440000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015290911690632f17414490602401600060405180830381865afa1580156120d3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120fb9190810190614911565b9150600090505b828161ffff16101561216e576017828261ffff1681518110612126576121266149c3565b602002602001015161ffff16611e618110612143576121436149c3565b601081049091015461ffff6002600f90931683026101000a9091041690039490940193600101612102565b60165461ffff66010000000000008204811662010000909204811691909103811690861611156121b65760165461ffff66010000000000008204811662010000909204160394505b509295945050505050565b6121c9612b8a565b6101fe5460ff161561221d5760405162461bcd60e51b815260206004820152601660248201527f57617272696f723a207572692069732066726f7a656e000000000000000000006044820152606401610cd1565b6014610c708282614a58565b6000610c588261349e565b6014805461224190614878565b80601f016020809104026020016040519081016040528092919081815260200182805461226d90614878565b80156122ba5780601f1061228f576101008083540402835291602001916122ba565b820191906000526020600020905b81548152906001019060200180831161229d57829003601f168201915b505050505081565b60006001600160a01b038216612304576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b612332612b8a565b611cb3600061353f565b612344612d4c565b6001600160a01b0381163b1561239c5760405162461bcd60e51b815260206004820152601560248201527f57617272696f723a206e6f20636f6e74726163747300000000000000000000006044820152606401610cd1565b6123a6828261359e565b610c706001600855565b6000600b82815481106123c5576123c56149c3565b6000918252602090912001546001600160a01b031692915050565b6060600c805480602002602001604051908101604052809291908181526020018280548015610df9576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610f60575050505050905090565b606060038054610d8090614878565b612457612b8a565b610c708282613806565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6124d5612b8a565b60165461ffff6601000000000000909104811690821610156125395760405162461bcd60e51b815260206004820152601060248201527f57617272696f723a20746f6f206c6f77000000000000000000000000000000006044820152606401610cd1565b6016805461ffff90921662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff909216919091179055565b61257c612d4c565b61258581612229565b6001600160a01b0316336001600160a01b0316146125e55760405162461bcd60e51b815260206004820181905260248201527f57617272696f723a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b60008181526101ff60205260409020805460ff191660011790556110fe6001600855565b612611612b8a565b6101fe80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b6011548490600160a01b900460ff16801561266957506daaeb6d7670e522a718067333cd4e3b15155b156127a457336001600160a01b0382160361268f5761268a85858585613b2c565b6127b0565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156126de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270291906148b2565b80156127855750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278591906148b2565b6127a457604051633b79c77360e21b8152336004820152602401610cd1565b6127b085858585613b2c565b5050505050565b6127bf612b8a565b601180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b8315150217905550565b60606127ff82612cfe565b612835576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061283f613b70565b9050805160000361285f576040518060200160405280600081525061288a565b8061286984613b7f565b60405160200161287a929190614b18565b6040516020818303038152906040525b9392505050565b612899612b8a565b6110fe81613bc3565b6128aa612b8a565b6001600160a01b0381166129265760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610cd1565b6110fe8161353f565b6001600160a01b03163b151590565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526129be908490613dde565b505050565b80471015612a135760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610cd1565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612a60576040519150601f19603f3d011682016040523d82523d6000602084013e612a65565b606091505b50509050806129be5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610cd1565b6060612aeb8484600085613ec3565b949350505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a000000000000000000000000000000000000000000000000000000001480610c5857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610c58565b6011546001600160a01b03163314611cb35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b6127106bffffffffffffffffffffffff82161115612c6a5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610cd1565b6001600160a01b038216612cc05760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610cd1565b604080518082019091526001600160a01b039092168083526bffffffffffffffffffffffff9091166020909201829052600160a01b90910217601255565b600081600111158015612d12575060005482105b8015610c585750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b600260085403612d9e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cd1565b6002600855565b6000612db0600a5490565b612dba90476148e5565b90506000612de78383612de2866001600160a01b03166000908152600e602052604090205490565b613fb5565b905047811115612df45750475b80156129be576001600160a01b0383166000908152600e602052604081208054839290612e229084906148e5565b9250508190555080600a6000828254612e3b91906148e5565b90915550612e4b905083826129c3565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b6000612e9d8261349e565b9050836001600160a01b0316816001600160a01b031614612eea576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417612f5057612f1a8633610bff565b612f50576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516612f90576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612f9d8686866001614010565b8015612fa857600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b177c0200000000000000000000000000000000000000000000000000000000176000858152600460205260408120919091557c02000000000000000000000000000000000000000000000000000000008416900361306c5760018401600081815260046020526040812054900361306a57600054811461306a5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b610c70828260405180602001604052806000815250614096565b60005b600b548110156110fe5760005b600c54811015613163576000600c82815481106130ff576130ff6149c3565b9060005260206000200160009054906101000a90046001600160a01b0316905061315081600b8581548110613136576131366149c3565b6000918252602090912001546001600160a01b031661359e565b508061315b81614b6f565b9150506130e0565b50613194600b828154811061317a5761317a6149c3565b6000918252602090912001546001600160a01b0316612da5565b8061319e81614b6f565b9150506130d3565b6129be83838360405180602001604052806000815250612640565b60008080805b600b5484101561321e57856001600160a01b0316600b85815481106131ee576131ee6149c3565b6000918252602090912001546001600160a01b03160361320c575060015b8361321681614b6f565b9450506131c7565b806001146132945760405162461bcd60e51b815260206004820152603660248201527f5061796d656e7453706c69747465723a20706179656520646f6573206e6f742060448201527f65786973742c20616464207061796565206669727374000000000000000000006064820152608401610cd1565b6001600160a01b0386166000908152600d602052604090205460095486916132bb91614b89565b6132c591906148e5565b91506000821161333d5760405162461bcd60e51b815260206004820152603460248201527f5061796d656e7453706c69747465723a20746f74616c20736861726573206d7560448201527f73742062652067726561746572207468616e20300000000000000000000000006064820152608401610cd1565b6133456130d0565b6000600a81905593505b600b548410156133a9576000600e6000600b8781548110613372576133726149c3565b60009182526020808320909101546001600160a01b03168352820192909252604001902055836133a181614b6f565b94505061334f565b600092505b600c5483101561347c576000600c84815481106133cd576133cd6149c3565b60009182526020808320909101546001600160a01b0316808352600f9091526040822082905590955090505b600b54851015613469576001600160a01b0381166000908152601060205260408120600b805483919089908110613432576134326149c3565b60009182526020808320909101546001600160a01b031683528201929092526040019020558461346181614b6f565b9550506133f9565b508261347481614b6f565b9350506133ae565b5060095550506001600160a01b039091166000908152600d6020526040902055565b6000818060011161350d5760005481101561350d57600081815260046020526040812054907c01000000000000000000000000000000000000000000000000000000008216900361350b575b8060000361288a5750600019016000818152600460205260409020546134ea565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166000908152600f60205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa1580156135fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361f91906148f8565b61362991906148e5565b905060006136628383612de287876001600160a01b03918216600090815260106020908152604080832093909416825291909152205490565b6040516370a0823160e01b81523060048201529091506001600160a01b038516906370a0823190602401602060405180830381865afa1580156136a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136cd91906148f8565b81111561373f576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015613718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373c91906148f8565b90505b801561126f576001600160a01b0380851660009081526010602090815260408083209387168352929052908120805483929061377c9084906148e5565b90915550506001600160a01b0384166000908152600f6020526040812080548392906137a99084906148e5565b909155506137ba905084848361293e565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b6000806001600160a01b0384163b156138615760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a206e6f20636f6e7472616374730000006044820152606401610cd1565b60008361ffff16116138b55760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610cd1565b60008092505b600b5483101561391257846001600160a01b0316600b84815481106138e2576138e26149c3565b6000918252602090912001546001600160a01b031603613900575060015b8261390a81614b6f565b9350506138bb565b806000036127b05761ffff841615613a635761392c6130d0565b6000600a81905592505b600b54831015613990576000600e6000600b8681548110613959576139596149c3565b60009182526020808320909101546001600160a01b031683528201929092526040019020558261398881614b6f565b935050613936565b600091505b600c54821015613a63576000600c83815481106139b4576139b46149c3565b60009182526020808320909101546001600160a01b0316808352600f9091526040822082905590945090505b600b54841015613a50576001600160a01b0381166000908152601060205260408120600b805483919088908110613a1957613a196149c3565b60009182526020808320909101546001600160a01b0316835282019290925260400190205583613a4881614b6f565b9450506139e0565b5081613a5b81614b6f565b925050613995565b600b8054600181019091557f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db901805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387169081179091556000908152600d6020526040902061ffff851690819055600954613add91906148e5565b600955604080516001600160a01b038716815261ffff861660208201527fefb20bd7b432b3f89ef344f5dd4dbc10c62729e41df4363592a810661c8c7ae4910160405180910390a15050505050565b613b37848484611101565b6001600160a01b0383163b1561126f57613b53848484846140fc565b61126f576040516368d2bf6b60e11b815260040160405180910390fd5b606060148054610d8090614878565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a900480613b995750819003601f19909101908152919050565b60016001600160a01b0382163b151514613c455760405162461bcd60e51b815260206004820152602360248201527f5061796d656e7453706c69747465723a206d757374206265206120636f6e747260448201527f61637400000000000000000000000000000000000000000000000000000000006064820152608401610cd1565b6040516370a0823160e01b81523060048201526001600160a01b038216906370a0823190602401602060405180830381865afa158015613c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cad91906148f8565b506000805b600c54811015613d0a57826001600160a01b0316600c8281548110613cd957613cd96149c3565b6000918252602090912001546001600160a01b031603613cf857600191505b80613d0281614b6f565b915050613cb2565b508015613d7e5760405162461bcd60e51b8152602060048201526024808201527f5061796d656e7453706c69747465723a20746f6b656e20616c7265616479206160448201527f64646564000000000000000000000000000000000000000000000000000000006064820152608401610cd1565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000613e33826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612adc9092919063ffffffff16565b8051909150156129be5780806020019051810190613e5191906148b2565b6129be5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610cd1565b606082471015613f3b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610cd1565b600080866001600160a01b03168587604051613f579190614b9c565b60006040518083038185875af1925050503d8060008114613f94576040519150601f19603f3d011682016040523d82523d6000602084013e613f99565b606091505b5091509150613faa8783838761422e565b979650505050505050565b600080600954600003613fca57506000612aeb565b6009546001600160a01b0386166000908152600d6020526040902054849190613ff390876149d9565b613ffd91906149f0565b6140079190614b89565b95945050505050565b60008281526101ff602052604090205460ff161561126f5760405162461bcd60e51b815260206004820152602b60248201527f57617272696f722c2063616e6e6f74207472616e73666572202d20637572726560448201527f6e746c79206c6f636b65640000000000000000000000000000000000000000006064820152608401610cd1565b6140a083836142a7565b6001600160a01b0383163b156129be576000548281035b6140ca60008683806001019450866140fc565b6140e7576040516368d2bf6b60e11b815260040160405180910390fd5b8181106140b75781600054146127b057600080fd5b6040517f150b7a020000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063150b7a029061414a903390899088908890600401614bb8565b6020604051808303816000875af1925050508015614185575060408051601f3d908101601f1916820190925261418291810190614bf4565b60015b6141e3573d8080156141b3576040519150601f19603f3d011682016040523d82523d6000602084013e6141b8565b606091505b5080516000036141db576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050612aeb565b6060831561429d578251600003614296576001600160a01b0385163b6142965760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cd1565b5081612aeb565b612aeb83836143e5565b60008054908290036142e5576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142f26000848385614010565b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146143a157808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101614369565b50816000036143dc576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b8151156143f55781518083602001fd5b8060405162461bcd60e51b8152600401610cd19190614536565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146110fe57600080fd5b60006020828403121561444f57600080fd5b813561288a8161440f565b6001600160a01b03811681146110fe57600080fd5b6000806040838503121561448257600080fd5b823561448d8161445a565b915060208301356bffffffffffffffffffffffff811681146144ae57600080fd5b809150509250929050565b61ffff811681146110fe57600080fd5b6000602082840312156144db57600080fd5b813561288a816144b9565b60005b838110156145015781810151838201526020016144e9565b50506000910152565b600081518084526145228160208601602086016144e6565b601f01601f19169290920160200192915050565b60208152600061288a602083018461450a565b60006020828403121561455b57600080fd5b5035919050565b6000806040838503121561457557600080fd5b82356145808161445a565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b818110156145cf5783516001600160a01b0316835292840192918401916001016145aa565b50909695505050505050565b80151581146110fe57600080fd5b6000602082840312156145fb57600080fd5b813561288a816145db565b60006020828403121561461857600080fd5b813561288a8161445a565b60008060006060848603121561463857600080fd5b83356146438161445a565b925060208401356146538161445a565b929592945050506040919091013590565b6000806040838503121561467757600080fd5b50508035926020909101359150565b6000806040838503121561469957600080fd5b82356146a48161445a565b915060208301356144ae816144b9565b600080604083850312156146c757600080fd5b82356146d28161445a565b915060208301356144ae8161445a565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614721576147216146e2565b604052919050565b600067ffffffffffffffff831115614743576147436146e2565b6147566020601f19601f860116016146f8565b905082815283838301111561476a57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561479357600080fd5b813567ffffffffffffffff8111156147aa57600080fd5b8201601f810184136147bb57600080fd5b612aeb84823560208401614729565b600080604083850312156147dd57600080fd5b82356147e88161445a565b915060208301356144ae816145db565b6000806000806080858703121561480e57600080fd5b84356148198161445a565b935060208501356148298161445a565b925060408501359150606085013567ffffffffffffffff81111561484c57600080fd5b8501601f8101871361485d57600080fd5b61486c87823560208401614729565b91505092959194509250565b600181811c9082168061488c57607f821691505b6020821081036148ac57634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156148c457600080fd5b815161288a816145db565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c5857610c586148cf565b60006020828403121561490a57600080fd5b5051919050565b6000602080838503121561492457600080fd5b825167ffffffffffffffff8082111561493c57600080fd5b818501915085601f83011261495057600080fd5b815181811115614962576149626146e2565b8060051b91506149738483016146f8565b818152918301840191848101908884111561498d57600080fd5b938501935b838510156149b757845192506149a7836144b9565b8282529385019390850190614992565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417610c5857610c586148cf565b600082614a0d57634e487b7160e01b600052601260045260246000fd5b500490565b601f8211156129be57600081815260208120601f850160051c81016020861015614a395750805b601f850160051c820191505b818110156130ae57828155600101614a45565b815167ffffffffffffffff811115614a7257614a726146e2565b614a8681614a808454614878565b84614a12565b602080601f831160018114614abb5760008415614aa35750858301515b600019600386901b1c1916600185901b1785556130ae565b600085815260208120601f198616915b82811015614aea57888601518255948401946001909101908401614acb565b5085821015614b085787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008351614b2a8184602088016144e6565b835190830190614b3e8183602088016144e6565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000009101908152600501949350505050565b60006000198203614b8257614b826148cf565b5060010190565b81810381811115610c5857610c586148cf565b60008251614bae8184602087016144e6565b9190910192915050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152614bea608083018461450a565b9695505050505050565b600060208284031215614c0657600080fd5b815161288a8161440f56fea26469706673582212203cfa432c67c2e27fbd47eca6ba4517bdd1d950b7d77030549207242e2642b47264736f6c63430008110033

Deployed Bytecode Sourcemap

5543:9980:17:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3648:40:14;835:10:1;3648:40:14;;;-1:-1:-1;;;;;206:55:18;;;188:74;;3678:9:14;293:2:18;278:18;;271:34;161:18;3648:40:14;;;;;;;5543:9980:17;;;;;6780:171;;;;;;;;;;-1:-1:-1;6780:171:17;;;;;:::i;:::-;;:::i;:::-;;;913:14:18;;906:22;888:41;;876:2;861:18;6780:171:17;;;;;;;;342:28:12;;;;;;;;;;-1:-1:-1;342:28:12;;;;-1:-1:-1;;;342:28:12;;;;;;13518:146:17;;;;;;;;;;-1:-1:-1;13518:146:17;;;;;:::i;:::-;;:::i;:::-;;13155:264;;;;;;;;;;-1:-1:-1;13155:264:17;;;;;:::i;:::-;;:::i;10386:100:5:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16885:218::-;;;;;;;;;;-1:-1:-1;16885:218:5;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3075:55:18;;;3057:74;;3045:2;3030:18;16885:218:5;2911:226:18;16318:408:5;;;;;;:::i;:::-;;:::i;11528:94:14:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;12755:78:17:-;;;;;;;;;;;;;:::i;5886:33::-;;;;;;;;;;;;;;;;;;;4294:25:18;;;4282:2;4267:18;5886:33:17;4148:177:18;11978:81:17;;;;;;;;;;-1:-1:-1;11978:81:17;;;;;:::i;:::-;;:::i;12121:143::-;;;;;;;;;;-1:-1:-1;12121:143:17;;;;;:::i;:::-;;:::i;6137:323:5:-;;;;;;;;;;-1:-1:-1;5736:1:5;6411:12;6198:7;6395:13;:28;-1:-1:-1;;6395:46:5;6137:323;;14225:181:17;;;;;;;;;;-1:-1:-1;14225:181:17;;;;;:::i;:::-;;:::i;6291:40::-;;;;;;;;;;-1:-1:-1;6291:40:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5385:6:18;5373:19;;;5355:38;;5343:2;5328:18;6291:40:17;5211:188:18;14918:171:17;;;;;;:::i;:::-;;:::i;7972:2661::-;;;;;;:::i;:::-;;:::i;4216:124:14:-;;;;;;;;;;-1:-1:-1;4216:124:14;;;;;:::i;:::-;-1:-1:-1;;;;;4306:26:14;4279:7;4306:26;;;:19;:26;;;;;;;4216:124;5963:31:17;;;;;;;;;;-1:-1:-1;5963:31:17;;;;;;;;;;;6070:24;;;;;;;;;;-1:-1:-1;6070:24:17;;;;;;;;;;;1785:442:4;;;;;;;;;;-1:-1:-1;1785:442:4;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;206:55:18;;;188:74;;293:2;278:18;;271:34;;;;161:18;1785:442:4;14:297:18;11618:193:17;;;;;;;;;;-1:-1:-1;11618:193:17;;;;;:::i;:::-;;:::i;3779:91:14:-;;;;;;;;;;-1:-1:-1;3850:12:14;;3779:91;;14749:72:17;;;;;;;;;;;;;:::i;15097:179::-;;;;;;:::i;:::-;;:::i;11849:82::-;;;;;;;;;;-1:-1:-1;11849:82:17;;;;;:::i;:::-;;:::i;13899:118::-;;;;;;;;;;-1:-1:-1;13899:118:17;;;;;:::i;:::-;;:::i;6515:74::-;;;;;;;;;;-1:-1:-1;6515:74:17;;;;-1:-1:-1;;;;;6515:74:17;;;4913:140:14;;;;;;;;;;-1:-1:-1;4913:140:14;;;;;:::i;:::-;-1:-1:-1;;;;;5015:21:14;;;4988:7;5015:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;4913:140;7008:931:17;;;;;;;;;;-1:-1:-1;7008:931:17;;;;;:::i;:::-;;:::i;12545:174::-;;;;;;;;;;-1:-1:-1;12545:174:17;;;;;:::i;:::-;;:::i;6208:25::-;;;;;;;;;;-1:-1:-1;6208:25:17;;;;;;;;;;;6001:31;;;;;;;;;;-1:-1:-1;6001:31:17;;;;;;;;;;;11787:152:5;;;;;;;;;;-1:-1:-1;11787:152:5;;;;;:::i;:::-;;:::i;5799:80:17:-;;;;;;;;;;;;;:::i;7321:233:5:-;;;;;;;;;;-1:-1:-1;7321:233:5;;;;;:::i;:::-;;:::i;1984:103:13:-;;;;;;;;;;;;;:::i;14463:212:17:-;;;;;;;;;;-1:-1:-1;14463:212:17;;;;;:::i;:::-;;:::i;6172:32::-;;;;;;;;;;-1:-1:-1;6172:32:17;;;;;;;;;;;5144:100:14;;;;;;;;;;-1:-1:-1;5144:100:14;;;;;:::i;:::-;;:::i;1336:87:13:-;;;;;;;;;;-1:-1:-1;1409:6:13;;-1:-1:-1;;;;;1409:6:13;1336:87;;11365:96:14;;;;;;;;;;;;;:::i;10562:104:5:-;;;;;;;;;;;;;:::i;4635:109:14:-;;;;;;;;;;-1:-1:-1;4635:109:14;;;;;:::i;:::-;-1:-1:-1;;;;;4718:18:14;4691:7;4718:18;;;:9;:18;;;;;;;4635:109;13716:116:17;;;;;;;;;;-1:-1:-1;13716:116:17;;;;;:::i;:::-;;:::i;17443:234:5:-;;;;;;;;;;-1:-1:-1;17443:234:5;;;;;:::i;:::-;;:::i;12343:143:17:-;;;;;;;;;;-1:-1:-1;12343:143:17;;;;;:::i;:::-;;:::i;11278:190::-;;;;;;;;;;-1:-1:-1;11278:190:17;;;;;:::i;:::-;;:::i;6240:47::-;;;;;;;;;;-1:-1:-1;6240:47:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;13031:81;;;;;;;;;;;;;:::i;15284:236::-;;;;;;:::i;:::-;;:::i;11023:112::-;;;;;;;;;;-1:-1:-1;11023:112:17;;;;;:::i;:::-;11079:4;11103:24;;;:15;:24;;;;;;;;;11023:112;14829:81;;;;;;;;;;-1:-1:-1;14829:81:17;;;;;:::i;:::-;;:::i;6136:29::-;;;;;;;;;;-1:-1:-1;6136:29:17;;;;;;;;10772:326:5;;;;;;;;;;-1:-1:-1;10772:326:5;;;;;:::i;:::-;;:::i;4431:105:14:-;;;;;;;;;;-1:-1:-1;4431:105:14;;;;;:::i;:::-;-1:-1:-1;;;;;4512:16:14;4485:7;4512:16;;;:7;:16;;;;;;;4431:105;6039:24:17;;;;;;;;;;-1:-1:-1;6039:24:17;;;;;;;;;;;14083:91;;;;;;;;;;-1:-1:-1;14083:91:17;;;;;:::i;:::-;;:::i;5926:30::-;;;;;;;;;;-1:-1:-1;5926:30:17;;;;;;;;3964:95:14;;;;;;;;;;-1:-1:-1;4037:14:14;;3964:95;;17834:164:5;;;;;;;;;;-1:-1:-1;17834:164:5;;;;;:::i;:::-;-1:-1:-1;;;;;17955:25:5;;;17931:4;17955:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;17834:164;2242:201:13;;;;;;;;;;-1:-1:-1;2242:201:13;;;;;:::i;:::-;;:::i;6780:171:17:-;6883:4;6907:36;6931:11;6907:23;:36::i;:::-;6900:43;6780:171;-1:-1:-1;;6780:171:17:o;13518:146::-;1222:13:13;:11;:13::i;:::-;13614:42:17::1;13633:8;13643:12;13614:18;:42::i;:::-;13518:146:::0;;:::o;13155:264::-;1222:13:13;:11;:13::i;:::-;13230:12:17::1;::::0;::::1;::::0;::::1;;;:21;13222:63;;;::::0;-1:-1:-1;;;13222:63:17;;11784:2:18;13222:63:17::1;::::0;::::1;11766:21:18::0;11823:2;11803:18;;;11796:30;11862:31;11842:18;;;11835:59;11911:18;;13222:63:17::1;;;;;;;;;13313:9;::::0;::::1;::::0;;::::1;13304:18:::0;;::::1;;13296:86;;;::::0;-1:-1:-1;;;13296:86:17;;12142:2:18;13296:86:17::1;::::0;::::1;12124:21:18::0;12181:2;12161:18;;;12154:30;12220:34;12200:18;;;12193:62;12291:25;12271:18;;;12264:53;12334:19;;13296:86:17::1;11940:419:18::0;13296:86:17::1;13393:9;:18:::0;;-1:-1:-1;;13393:18:17::1;;::::0;;;::::1;::::0;;;::::1;::::0;;13155:264::o;10386:100:5:-;10440:13;10473:5;10466:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10386:100;:::o;16885:218::-;16961:7;16986:16;16994:7;16986;:16::i;:::-;16981:64;;17011:34;;;;;;;;;;;;;;16981:64;-1:-1:-1;17065:24:5;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;17065:30:5;;16885:218::o;16318:408::-;16407:13;16423:16;16431:7;16423;:16::i;:::-;16407:32;-1:-1:-1;835:10:1;-1:-1:-1;;;;;16456:28:5;;;16452:175;;16504:44;16521:5;835:10:1;17834:164:5;:::i;16504:44::-;16499:128;;16576:35;;;;;;;;;;;;;;16499:128;16639:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;16639:35:5;-1:-1:-1;;;;;16639:35:5;;;;;;;;;16690:28;;16639:24;;16690:28;;;;;;;16396:330;16318:408;;:::o;11528:94:14:-;11571:16;11607:7;11600:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11600:14:14;;;;;;;;;;;;;;;;;;;;;;11528:94;:::o;12755:78:17:-;1222:13:13;:11;:13::i;:::-;12809:9:17::1;:16:::0;;-1:-1:-1;;12809:16:17::1;12821:4;12809:16;::::0;;12755:78::o;11978:81::-;1222:13:13;:11;:13::i;:::-;12038:6:17::1;:16:::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;11978:81::o;12121:143::-;1222:13:13;:11;:13::i;:::-;12203:10:17::1;::::0;::::1;::::0;;;::::1;::::0;::::1;12195:18:::0;;::::1;;;12187:47;;;::::0;-1:-1:-1;;;12187:47:17;;13008:2:18;12187:47:17::1;::::0;::::1;12990:21:18::0;13047:2;13027:18;;;13020:30;13086:18;13066;;;13059:46;13122:18;;12187:47:17::1;12806:340:18::0;12187:47:17::1;12242:10;:17:::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;12121:143::o;14225:181::-;2406:21:15;:19;:21::i;:::-;-1:-1:-1;;;;;1604:19:0;;;:23;14300:70:17::1;;;::::0;-1:-1:-1;;;14300:70:17;;13353:2:18;14300:70:17::1;::::0;::::1;13335:21:18::0;13392:2;13372:18;;;13365:30;13431:23;13411:18;;;13404:51;13472:18;;14300:70:17::1;13151:345:18::0;14300:70:17::1;14381:17;14390:7;14381:8;:17::i;:::-;2450:20:15::0;1844:1;2966:7;:22;2783:213;2450:20;14225:181:17;:::o;14918:171::-;1726:9:12;;15027:4:17;;-1:-1:-1;;;1726:9:12;;;;:60;;;;-1:-1:-1;586:42:12;1739:43;:47;;1726:60;1722:712;;;2026:10;-1:-1:-1;;;;;2018:18:12;;;2014:85;;15044:37:17::1;15063:4;15069:2;15073:7;15044:18;:37::i;:::-;2077:7:12::0;;2014:85;2159:67;;-1:-1:-1;;;2159:67:12;;2208:4;2159:67;;;13736:34:18;2215:10:12;13786:18:18;;;13779:43;586:42:12;;2159:40;;13648:18:18;;2159:67:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;2255:61:12;;-1:-1:-1;;;2255:61:12;;2304:4;2255:61;;;13736:34:18;-1:-1:-1;;;;;13806:15:18;;13786:18;;;13779:43;586:42:12;;2255:40;;13648:18:18;;2255:61:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2113:310;;2377:30;;-1:-1:-1;;;2377:30:12;;2396:10;2377:30;;;3057:74:18;3030:18;;2377:30:12;2911:226:18;2113:310:12;15044:37:17::1;15063:4;15069:2;15073:7;15044:18;:37::i;:::-;14918:171:::0;;;;:::o;7972:2661::-;2406:21:15;:19;:21::i;:::-;8046:16:17::1;8065:21;8075:10;8065:9;:21::i;:::-;8046:40:::0;-1:-1:-1;8097:19:17::1;8127:8;::::0;;8236:10:::1;1604:19:0::0;:23;8209:73:17::1;;;::::0;-1:-1:-1;;;8209:73:17;;13353:2:18;8209:73:17::1;::::0;::::1;13335:21:18::0;13392:2;13372:18;;;13365:30;13431:23;13411:18;;;13404:51;13472:18;;8209:73:17::1;13151:345:18::0;8209:73:17::1;8301:6;::::0;;;::::1;;;:15;::::0;:40:::1;;-1:-1:-1::0;1409:6:13;;-1:-1:-1;;;;;1409:6:13;8320:10:17::1;:21;8301:40;8293:85;;;::::0;-1:-1:-1;;;8293:85:17;;14285:2:18;8293:85:17::1;::::0;::::1;14267:21:18::0;;;14304:18;;;14297:30;14363:34;14343:18;;;14336:62;14415:18;;8293:85:17::1;14083:356:18::0;8293:85:17::1;8427:9;::::0;5736:1:5;6411:12;6198:7;6395:13;8427:9:17::1;::::0;;::::1;::::0;8397:26;::::1;::::0;6395:28:5;;-1:-1:-1;;6395:46:5;8397:26:17::1;;;;:::i;:::-;:39;;8389:92;;;::::0;-1:-1:-1;;;8389:92:17;;14965:2:18;8389:92:17::1;::::0;::::1;14947:21:18::0;15004:2;14984:18;;;14977:30;15043:34;15023:18;;;15016:62;15114:10;15094:18;;;15087:38;15142:19;;8389:92:17::1;14763:404:18::0;8389:92:17::1;1409:6:13::0;;-1:-1:-1;;;;;1409:6:13;8523:10:17::1;:21;::::0;:81:::1;;-1:-1:-1::0;8562:42:17::1;8548:10;:56;8523:81;8519:2004;;;8661:10;:24:::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;-1:-1:-1::0;;8661:24:17;;::::1;;::::0;;8519:2004:::1;;;8713:13;::::0;::::1;::::0;8709:1814:::1;;8764:9;8751:22;;:10;:22;;;8747:93;;;8811:9;8798:22;;8747:93;8972:7;::::0;:36:::1;::::0;;;;8997:10:::1;8972:36;::::0;::::1;3057:74:18::0;8876:10:17;;-1:-1:-1;;;;;8972:7:17::1;::::0;:24:::1;::::0;3030:18:18;;8972:36:17::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8957:51:::0;-1:-1:-1;9031:16:17;;9027:373:::1;;9078:7;::::0;:29:::1;::::0;;;;9096:10:::1;9078:29;::::0;::::1;3057:74:18::0;-1:-1:-1;;;;;9078:7:17;;::::1;::::0;:17:::1;::::0;3030:18:18;;9078:29:17::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;9078:29:17::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;9072:35;;9141:1;9137:5;;9132:249;9148:12;9144:1;:16;;;9132:249;;;9209:1;9198:8;:12;;;:36;;;;;9214:7;9222:3;9226:1;9222:6;;;;;;;;;;:::i;:::-;;;;;;;9214:15;;;;;;;;;:::i;:::-;;::::0;::::1;::::0;;;::::1;::::0;;;;;::::1;;;;::::0;::::1;;;:20:::0;9198:36:::1;9194:164;;;9285:1;9267:7;9275:3;9279:1;9275:6;;;;;;;;;;:::i;:::-;;;;;;;9267:15;;;;;;;;;:::i;:::-;;;;;;;;;;;;:19;;;;;;;;;;;;;;;;;;9329:1;9317:13;;;;9194:164;9162:3;::::0;;::::1;::::0;9132:249:::1;;;9483:7;::::0;:36:::1;::::0;;;;9508:10:::1;9483:36;::::0;::::1;3057:74:18::0;-1:-1:-1;;;;;9483:7:17;;::::1;::::0;:24:::1;::::0;3030:18:18;;9483:36:17::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9469:50:::0;-1:-1:-1;9542:15:17;;9538:541:::1;;9588:7;::::0;:29:::1;::::0;;;;9606:10:::1;9588:29;::::0;::::1;3057:74:18::0;-1:-1:-1;;;;;9588:7:17;;::::1;::::0;:17:::1;::::0;3030:18:18;;9588:29:17::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;9588:29:17::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;9582:35;;9651:1;9647:5;;9642:418;9658:11;9654:1;:15;;;9642:418;;;9718:1;9707:8;:12;;;:36;;;;;9723:7;9731:3;9735:1;9731:6;;;;;;;;;;:::i;:::-;;;;;;;9723:15;;;;;;;;;:::i;:::-;;::::0;::::1;::::0;;;::::1;::::0;;;;;::::1;;;;::::0;::::1;;;:20:::0;9707:36:::1;9703:334;;;9794:1;9776:7;9784:3;9788:1;9784:6;;;;;;;;;;:::i;:::-;;;;;;;9776:15;;;;;;;;;:::i;:::-;;;;;;;;;;;;:19;;;;;;;;;;;;;;;;;;9838:1;9826:13;;;;9703:334;;;9888:1;9877:8;:12;;;:36;;;;;9893:7;9901:3;9905:1;9901:6;;;;;;;;;;:::i;:::-;;;;;;;9893:15;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:20;;9912:1;9893:20;9877:36;9873:164;;;9964:1;9946:7;9954:3;9958:1;9954:6;;;;;;;;;;:::i;:::-;;;;;;;9946:15;;;;;;;;;:::i;:::-;;;;;;;;;;;;:19;;;;;;;;;;;;;;;;;;10008:1;9996:13;;;;9873:164;9671:3;::::0;;::::1;::::0;9642:418:::1;;;-1:-1:-1::0;10099:10:17::1;:24:::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;::::0;;;::::1;;::::0;;8709:1814:::1;;;10164:10;::::0;::::1;::::0;;::::1;::::0;::::1;10151::::0;;;::::1;;:23;10147:376;;;10230:10;::::0;::::1;::::0;;::::1;::::0;::::1;10203::::0;;;::::1;::::0;::::1;:23:::0;::::1;:37;;;10195:80;;;::::0;-1:-1:-1;;;10195:80:17;;16766:2:18;10195:80:17::1;::::0;::::1;16748:21:18::0;16805:2;16785:18;;;16778:30;16844:32;16824:18;;;16817:60;16894:18;;10195:80:17::1;16564:354:18::0;10195:80:17::1;10322:10;10315:17;;:4;;:17;10302:9;:30;;10294:76;;;::::0;-1:-1:-1;;;10294:76:17;;17125:2:18;10294:76:17::1;::::0;::::1;17107:21:18::0;17164:2;17144:18;;;17137:30;17203:34;17183:18;;;17176:62;17274:3;17254:18;;;17247:31;17295:19;;10294:76:17::1;16923:397:18::0;10294:76:17::1;10391:10;:24:::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;-1:-1:-1::0;;10391:24:17;;::::1;;::::0;;10147:376:::1;;;10458:49;::::0;-1:-1:-1;;;10458:49:17;;17527:2:18;10458:49:17::1;::::0;::::1;17509:21:18::0;17566:2;17546:18;;;17539:30;17605:33;17585:18;;;17578:61;17656:18;;10458:49:17::1;17325:355:18::0;10458:49:17::1;10546:10;10539:18;::::0;;;:6:::1;:18;::::0;;;;:32;;-1:-1:-1;;10539:32:17;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;;;10595:33:::1;::::0;10546:10;10595:33;::::1;:9;:33::i;:::-;8035:2598;;;;;2450:20:15::0;1844:1;2966:7;:22;2783:213;1785:442:4;1882:7;1940:27;;;:17;:27;;;;;;;;1911:56;;;;;;;;;-1:-1:-1;;;;;1911:56:4;;;;;-1:-1:-1;;;1911:56:4;;;;;;;;;;;;1882:7;;1980:92;;-1:-1:-1;2031:29:4;;;;;;;;;2041:19;2031:29;-1:-1:-1;;;;;2031:29:4;;;;-1:-1:-1;;;2031:29:4;;;;;;;;1980:92;2122:23;;;;2084:21;;2593:5;;2109:36;;2108:58;2109:36;:10;:36;:::i;:::-;2108:58;;;;:::i;:::-;2187:16;;;;;-1:-1:-1;1785:442:4;;-1:-1:-1;;;;1785:442:4:o;11618:193:17:-;2406:21:15;:19;:21::i;:::-;11707:16:17::1;11715:7;11707;:16::i;:::-;-1:-1:-1::0;;;;;11693:30:17::1;:10;-1:-1:-1::0;;;;;11693:30:17::1;;11685:75;;;::::0;-1:-1:-1;;;11685:75:17;;18339:2:18;11685:75:17::1;::::0;::::1;18321:21:18::0;;;18358:18;;;18351:30;18417:34;18397:18;;;18390:62;18469:18;;11685:75:17::1;18137:356:18::0;11685:75:17::1;11798:5;11771:24:::0;;;:15:::1;:24;::::0;;;;:32;;-1:-1:-1;;11771:32:17::1;::::0;;2450:20:15;1844:1;2966:7;:22;2783:213;14749:72:17;2406:21:15;:19;:21::i;:::-;14802:11:17::1;:9;:11::i;:::-;2450:20:15::0;1844:1;2966:7;:22;2783:213;2450:20;14749:72:17:o;15097:179::-;1726:9:12;;15210:4:17;;-1:-1:-1;;;1726:9:12;;;;:60;;;;-1:-1:-1;586:42:12;1739:43;:47;;1726:60;1722:712;;;2026:10;-1:-1:-1;;;;;2018:18:12;;;2014:85;;15227:41:17::1;15250:4;15256:2;15260:7;15227:22;:41::i;2014:85:12:-:0;2159:67;;-1:-1:-1;;;2159:67:12;;2208:4;2159:67;;;13736:34:18;2215:10:12;13786:18:18;;;13779:43;586:42:12;;2159:40;;13648:18:18;;2159:67:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;2255:61:12;;-1:-1:-1;;;2255:61:12;;2304:4;2255:61;;;13736:34:18;-1:-1:-1;;;;;13806:15:18;;13786:18;;;13779:43;586:42:12;;2255:40;;13648:18:18;;2255:61:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2113:310;;2377:30;;-1:-1:-1;;;2377:30:12;;2396:10;2377:30;;;3057:74:18;3030:18;;2377:30:12;2911:226:18;2113:310:12;15227:41:17::1;15250:4;15256:2;15260:7;15227:22;:41::i;11849:82::-:0;1222:13:13;:11;:13::i;:::-;11911:4:17::1;:15:::0;11849:82::o;13899:118::-;1222:13:13;:11;:13::i;:::-;13981:28:17::1;13992:7;14001;13981:28;;:10;:28::i;7008:931::-:0;7131:7;;:30;;;;;-1:-1:-1;;;;;3075:55:18;;;7131:30:17;;;3057:74:18;7062:6:17;;;;;;7131:7;;;;:24;;3030:18:18;;7131:30:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7194:7;;:30;;;;;-1:-1:-1;;;;;3075:55:18;;;7194:30:17;;;3057:74:18;7108:53:17;;-1:-1:-1;7172:19:17;;7194:7;;;;:24;;3030:18:18;;7194:30:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7172:52;-1:-1:-1;7235:19:17;7265:8;7315:16;;7311:216;;7358:7;;:23;;;;;-1:-1:-1;;;;;3075:55:18;;;7358:23:17;;;3057:74:18;7358:7:17;;;;:17;;3030:18:18;;7358:23:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7358:23:17;;;;;;;;;;;;:::i;:::-;7352:29;;7411:1;7407:5;;7402:110;7418:12;7414:1;:16;;;7402:110;;;7477:7;7485:3;7489:1;7485:6;;;;;;;;;;:::i;:::-;;;;;;;7477:15;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;7473:1;:19;;;7460:32;;;;;7432:3;7402:110;;;7547:15;;7543:214;;7589:7;;:23;;;;;-1:-1:-1;;;;;3075:55:18;;;7589:23:17;;;3057:74:18;7589:7:17;;;;:17;;3030:18:18;;7589:23:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7589:23:17;;;;;;;;;;;;:::i;:::-;7583:29;;7642:1;7638:5;;7633:109;7649:11;7645:1;:15;;;7633:109;;;7707:7;7715:3;7719:1;7715:6;;;;;;;;;;:::i;:::-;;;;;;;7707:15;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;7703:19;;7690:32;;;;;7662:3;;7633:109;;;7810:10;;;;;;;;7797;;;;;;:23;;;;7785:35;;;;;;7781:111;;;7866:10;;;;;;;;7853;;;;;:23;;-1:-1:-1;7781:111:17;-1:-1:-1;7922:9:17;;7008:931;-1:-1:-1;;;;;7008:931:17:o;12545:174::-;1222:13:13;:11;:13::i;:::-;12632:9:17::1;::::0;::::1;;:18;12624:53;;;::::0;-1:-1:-1;;;12624:53:17;;18700:2:18;12624:53:17::1;::::0;::::1;18682:21:18::0;18739:2;18719:18;;;18712:30;18778:24;18758:18;;;18751:52;18820:18;;12624:53:17::1;18498:346:18::0;12624:53:17::1;12688:7;:23;12698:13:::0;12688:7;:23:::1;:::i;11787:152:5:-:0;11859:7;11902:27;11921:7;11902:18;:27::i;5799:80:17:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7321:233:5:-;7393:7;-1:-1:-1;;;;;7417:19:5;;7413:60;;7445:28;;;;;;;;;;;;;;7413:60;-1:-1:-1;;;;;;7491:25:5;;;;;:18;:25;;;;;;1480:13;7491:55;;7321:233::o;1984:103:13:-;1222:13;:11;:13::i;:::-;2049:30:::1;2076:1;2049:18;:30::i;14463:212:17:-:0;2406:21:15;:19;:21::i;:::-;-1:-1:-1;;;;;1604:19:0;;;:23;14557:70:17::1;;;::::0;-1:-1:-1;;;14557:70:17;;13353:2:18;14557:70:17::1;::::0;::::1;13335:21:18::0;13392:2;13372:18;;;13365:30;13431:23;13411:18;;;13404:51;13472:18;;14557:70:17::1;13151:345:18::0;14557:70:17::1;14638:29;14652:5;14659:7;14638:13;:29::i;:::-;2450:20:15::0;1844:1;2966:7;:22;2783:213;5144:100:14;5195:7;5222;5230:5;5222:14;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;5222:14:14;;5144:100;-1:-1:-1;;5144:100:14:o;11365:96::-;11408:15;11443:10;11436:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11436:17:14;;;;;;;;;;;;;;;;;;;;;;11365:96;:::o;10562:104:5:-;10618:13;10651:7;10644:14;;;;;:::i;13716:116:17:-;1222:13:13;:11;:13::i;:::-;13797:27:17::1;13807:7;13816;13797:9;:27::i;17443:234:5:-:0;835:10:1;17538:39:5;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;17538:49:5;;;;;;;;;;;;:60;;-1:-1:-1;;17538:60:5;;;;;;;;;;17614:55;;888:41:18;;;17538:49:5;;835:10:1;17614:55:5;;861:18:18;17614:55:5;;;;;;;17443:234;;:::o;12343:143:17:-;1222:13:13;:11;:13::i;:::-;12425:10:17::1;::::0;::::1;::::0;;;::::1;::::0;::::1;12417:18:::0;;::::1;;;12409:47;;;::::0;-1:-1:-1;;;12409:47:17;;13008:2:18;12409:47:17::1;::::0;::::1;12990:21:18::0;13047:2;13027:18;;;13020:30;13086:18;13066;;;13059:46;13122:18;;12409:47:17::1;12806:340:18::0;12409:47:17::1;12464:10;:17:::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;12343:143::o;11278:190::-;2406:21:15;:19;:21::i;:::-;11365:16:17::1;11373:7;11365;:16::i;:::-;-1:-1:-1::0;;;;;11351:30:17::1;:10;-1:-1:-1::0;;;;;11351:30:17::1;;11343:75;;;::::0;-1:-1:-1;;;11343:75:17;;18339:2:18;11343:75:17::1;::::0;::::1;18321:21:18::0;;;18358:18;;;18351:30;18417:34;18397:18;;;18390:62;18469:18;;11343:75:17::1;18137:356:18::0;11343:75:17::1;11429:24;::::0;;;:15:::1;:24;::::0;;;;:31;;-1:-1:-1;;11429:31:17::1;11456:4;11429:31;::::0;;2450:20:15;1844:1;2966:7;:22;2783:213;13031:81:17;1222:13:13;:11;:13::i;:::-;13085:12:17::1;:19:::0;;;::::1;;;::::0;;13031:81::o;15284:236::-;1726:9:12;;15443:4:17;;-1:-1:-1;;;1726:9:12;;;;:60;;;;-1:-1:-1;586:42:12;1739:43;:47;;1726:60;1722:712;;;2026:10;-1:-1:-1;;;;;2018:18:12;;;2014:85;;15465:47:17::1;15488:4;15494:2;15498:7;15507:4;15465:22;:47::i;:::-;2077:7:12::0;;2014:85;2159:67;;-1:-1:-1;;;2159:67:12;;2208:4;2159:67;;;13736:34:18;2215:10:12;13786:18:18;;;13779:43;586:42:12;;2159:40;;13648:18:18;;2159:67:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;2255:61:12;;-1:-1:-1;;;2255:61:12;;2304:4;2255:61;;;13736:34:18;-1:-1:-1;;;;;13806:15:18;;13786:18;;;13779:43;586:42:12;;2255:40;;13648:18:18;;2255:61:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2113:310;;2377:30;;-1:-1:-1;;;2377:30:12;;2396:10;2377:30;;;3057:74:18;3030:18;;2377:30:12;2911:226:18;2113:310:12;15465:47:17::1;15488:4;15494:2;15498:7;15507:4;15465:22;:47::i;:::-;15284:236:::0;;;;;:::o;14829:81::-;1222:13:13;:11;:13::i;:::-;464:9:12;:15;;;;-1:-1:-1;;;464:15:12;;;;;;;14225:181:17;:::o;10772:326:5:-;10845:13;10876:16;10884:7;10876;:16::i;:::-;10871:59;;10901:29;;;;;;;;;;;;;;10871:59;10943:21;10967:10;:8;:10::i;:::-;10943:34;;11001:7;10995:21;11020:1;10995:26;:95;;;;;;;;;;;;;;;;;11048:7;11057:18;11067:7;11057:9;:18::i;:::-;11031:53;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10995:95;10988:102;10772:326;-1:-1:-1;;;10772:326:5:o;14083:91:17:-;1222:13:13;:11;:13::i;:::-;14148:18:17::1;14158:7;14148:9;:18::i;2242:201:13:-:0;1222:13;:11;:13::i;:::-;-1:-1:-1;;;;;2331:22:13;::::1;2323:73;;;::::0;-1:-1:-1;;;2323:73:13;;22102:2:18;2323:73:13::1;::::0;::::1;22084:21:18::0;22141:2;22121:18;;;22114:30;22180:34;22160:18;;;22153:62;22251:8;22231:18;;;22224:36;22277:19;;2323:73:13::1;21900:402:18::0;2323:73:13::1;2407:28;2426:8;2407:18;:28::i;1309:326:0:-:0;-1:-1:-1;;;;;1604:19:0;;:23;;;1309:326::o;865:211:16:-;1009:58;;;-1:-1:-1;;;;;206:55:18;;1009:58:16;;;188:74:18;278:18;;;;271:34;;;1009:58:16;;;;;;;;;;161:18:18;;;;1009:58:16;;;;;;;;;;1032:23;1009:58;;;982:86;;1002:5;;982:19;:86::i;:::-;865:211;;;:::o;2570:317:0:-;2685:6;2660:21;:31;;2652:73;;;;-1:-1:-1;;;2652:73:0;;22509:2:18;2652:73:0;;;22491:21:18;22548:2;22528:18;;;22521:30;22587:31;22567:18;;;22560:59;22636:18;;2652:73:0;22307:353:18;2652:73:0;2739:12;2757:9;-1:-1:-1;;;;;2757:14:0;2779:6;2757:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2738:52;;;2809:7;2801:78;;;;-1:-1:-1;;;2801:78:0;;23077:2:18;2801:78:0;;;23059:21:18;23116:2;23096:18;;;23089:30;23155:34;23135:18;;;23128:62;23226:28;23206:18;;;23199:56;23272:19;;2801:78:0;22875:422:18;4066:229:0;4203:12;4235:52;4257:6;4265:4;4271:1;4274:12;4235:21;:52::i;:::-;4228:59;4066:229;-1:-1:-1;;;;4066:229:0:o;1515:215:4:-;1617:4;1641:41;;;1656:26;1641:41;;:81;;-1:-1:-1;1090:25:3;1075:40;;;;1686:36:4;966:157:3;1501:132:13;1409:6;;-1:-1:-1;;;;;1409:6:13;835:10:1;1565:23:13;1557:68;;;;-1:-1:-1;;;1557:68:13;;23504:2:18;1557:68:13;;;23486:21:18;;;23523:18;;;23516:30;23582:34;23562:18;;;23555:62;23634:18;;1557:68:13;23302:356:18;2877:332:4;2593:5;2980:33;;;;;2972:88;;;;-1:-1:-1;;;2972:88:4;;23865:2:18;2972:88:4;;;23847:21:18;23904:2;23884:18;;;23877:30;23943:34;23923:18;;;23916:62;24014:12;23994:18;;;23987:40;24044:19;;2972:88:4;23663:406:18;2972:88:4;-1:-1:-1;;;;;3079:22:4;;3071:60;;;;-1:-1:-1;;;3071:60:4;;24276:2:18;3071:60:4;;;24258:21:18;24315:2;24295:18;;;24288:30;24354:27;24334:18;;;24327:55;24399:18;;3071:60:4;24074:349:18;3071:60:4;3166:35;;;;;;;;;-1:-1:-1;;;;;3166:35:4;;;;;;;;;;;;;;;;;-1:-1:-1;;;3144:57:4;;;;:19;:57;2877:332::o;18256:282:5:-;18321:4;18377:7;5736:1;18358:26;;:66;;;;;18411:13;;18401:7;:23;18358:66;:153;;;;-1:-1:-1;;18462:26:5;;;;:17;:26;;;;;;2256:8;18462:44;:49;;18256:282::o;2486:289:15:-;1888:1;2616:7;;:19;2608:63;;;;-1:-1:-1;;;2608:63:15;;24630:2:18;2608:63:15;;;24612:21:18;24669:2;24649:18;;;24642:30;24708:33;24688:18;;;24681:61;24759:18;;2608:63:15;24428:355:18;2608:63:15;1888:1;2749:7;:18;2486:289::o;5444:635:14:-;5515:21;5563:15;4037:14;;;3964:95;5563:15;5539:39;;:21;:39;:::i;:::-;5515:63;;5589:15;5607:58;5623:7;5632:13;5647:17;5656:7;-1:-1:-1;;;;;4718:18:14;4691:7;4718:18;;;:9;:18;;;;;;;4635:109;5647:17;5607:15;:58::i;:::-;5589:76;;5761:21;5751:7;:31;5747:95;;;-1:-1:-1;5809:21:14;5747:95;5858:11;;5854:218;;-1:-1:-1;;;;;5886:18:14;;;;;;:9;:18;;;;;:29;;5908:7;;5886:18;:29;;5908:7;;5886:29;:::i;:::-;;;;;;;;5948:7;5930:14;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;5972:35:14;;-1:-1:-1;5990:7:14;5999;5972:17;:35::i;:::-;6027:33;;;-1:-1:-1;;;;;206:55:18;;188:74;;293:2;278:18;;271:34;;;6027:33:14;;161:18:18;6027:33:14;;;;;;;5504:575;;5444:635;:::o;20524:2825:5:-;20666:27;20696;20715:7;20696:18;:27::i;:::-;20666:57;;20781:4;-1:-1:-1;;;;;20740:45:5;20756:19;-1:-1:-1;;;;;20740:45:5;;20736:86;;20794:28;;;;;;;;;;;;;;20736:86;20836:27;19632:24;;;:15;:24;;;;;19860:26;;835:10:1;19257:30:5;;;-1:-1:-1;;;;;18950:28:5;;19235:20;;;19232:56;21022:180;;21115:43;21132:4;835:10:1;17834:164:5;:::i;21115:43::-;21110:92;;21167:35;;;;;;;;;;;;;;21110:92;-1:-1:-1;;;;;21219:16:5;;21215:52;;21244:23;;;;;;;;;;;;;;21215:52;21280:43;21302:4;21308:2;21312:7;21321:1;21280:21;:43::i;:::-;21416:15;21413:160;;;21556:1;21535:19;21528:30;21413:160;-1:-1:-1;;;;;21953:24:5;;;;;;;:18;:24;;;;;;21951:26;;-1:-1:-1;;21951:26:5;;;22022:22;;;;;;;;;22020:24;;-1:-1:-1;22020:24:5;;;15176:11;15151:23;15147:41;15134:63;2536:8;15134:63;22315:26;;;;:17;:26;;;;;:175;;;;2536:8;22610:47;;:52;;22606:627;;22715:1;22705:11;;22683:19;22838:30;;;:17;:30;;;;;;:35;;22834:384;;22976:13;;22961:11;:28;22957:242;;23123:30;;;;:17;:30;;;;;:52;;;22957:242;22664:569;22606:627;23280:7;23276:2;-1:-1:-1;;;;;23261:27:5;23270:4;-1:-1:-1;;;;;23261:27:5;;;;;;;;;;;23299:42;20655:2694;;;20524:2825;;;:::o;34396:112::-;34473:27;34483:2;34487:8;34473:27;;;;;;;;;;;;:9;:27::i;11699:402:14:-;11779:9;11774:320;11798:7;:14;11794:18;;11774:320;;;11871:9;11866:171;11890:10;:17;11886:21;;11866:171;;;11933:12;11948:10;11959:1;11948:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11948:13:14;11933:28;;11980:41;11994:5;12009:7;12017:1;12009:10;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;12009:10:14;11980:13;:41::i;:::-;-1:-1:-1;11909:3:14;;;;:::i;:::-;;;;11866:171;;;;12053:29;12070:7;12078:1;12070:10;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;12070:10:14;12053:8;:29::i;:::-;11814:3;;;;:::i;:::-;;;;11774:320;;23445:193:5;23591:39;23608:4;23614:2;23618:7;23591:39;;;;;;;;;;;;:16;:39::i;9379:1232:14:-;9461:9;;;;9599:140;9615:7;:14;9611:18;;9599:140;;;9669:7;-1:-1:-1;;;;;9655:21:14;:7;9663:1;9655:10;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;9655:10:14;:21;9651:77;;-1:-1:-1;9711:1:14;9651:77;9631:3;;;;:::i;:::-;;;;9599:140;;;9757:11;9772:1;9757:16;9749:83;;;;-1:-1:-1;;;9749:83:14;;25500:2:18;9749:83:14;;;25482:21:18;25539:2;25519:18;;;25512:30;25578:34;25558:18;;;25551:62;25649:24;25629:18;;;25622:52;25691:19;;9749:83:14;25298:418:18;9749:83:14;-1:-1:-1;;;;;9875:16:14;;;;;;:7;:16;;;;;;9860:12;;9894:7;;9860:31;;;:::i;:::-;:41;;;;:::i;:::-;9845:56;;9935:1;9920:12;:16;9912:81;;;;-1:-1:-1;;;9912:81:14;;26056:2:18;9912:81:14;;;26038:21:18;26095:2;26075:18;;;26068:30;26134:34;26114:18;;;26107:62;26205:22;26185:18;;;26178:50;26245:19;;9912:81:14;25854:416:18;9912:81:14;10074:11;:9;:11::i;:::-;10113:1;10096:14;:18;;;10113:1;-1:-1:-1;10125:89:14;10141:7;:14;10137:18;;10125:89;;;10201:1;10177:9;:21;10187:7;10195:1;10187:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;10187:10:14;10177:21;;;;;;;;;;;;:25;10157:3;;;;:::i;:::-;;;;10125:89;;;10261:1;10257:5;;10252:275;10268:10;:17;10264:21;;10252:275;;;10307:12;10322:10;10333:1;10322:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;10322:13:14;10350:26;;;:19;:26;;;;;;:30;;;10322:13;;-1:-1:-1;10322:13:14;-1:-1:-1;10407:109:14;10423:7;:14;10419:18;;10407:109;;;-1:-1:-1;;;;;10463:21:14;;10499:1;10463:21;;;:14;:21;;;;;10485:7;:10;;10499:1;;10485:7;10493:1;;10485:10;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;10485:10:14;10463:33;;;;;;;;;;;;:37;10439:3;;;;:::i;:::-;;;;10407:109;;;-1:-1:-1;10287:3:14;;;;:::i;:::-;;;;10252:275;;;-1:-1:-1;10539:12:14;:27;-1:-1:-1;;;;;;;10577:16:14;;;;;;;:7;:16;;;;;:26;9379:1232::o;12942:1275:5:-;13009:7;13044;;5736:1;13093:23;13089:1061;;13146:13;;13139:4;:20;13135:1015;;;13184:14;13201:23;;;:17;:23;;;;;;;2256:8;13290:24;;:29;;13286:845;;13955:113;13962:6;13972:1;13962:11;13955:113;;-1:-1:-1;;;14033:6:5;14015:25;;;;:17;:25;;;;;;13955:113;;13286:845;13161:989;13135:1015;14178:31;;;;;;;;;;;;;;2603:191:13;2696:6;;;-1:-1:-1;;;;;2713:17:13;;;-1:-1:-1;;2713:17:13;;;;;;;2746:40;;2696:6;;;2713:17;2696:6;;2746:40;;2677:16;;2746:40;2666:128;2603:191;:::o;6347:750:14:-;-1:-1:-1;;;;;4306:26:14;;6437:21;4306:26;;;:19;:26;;;;;;6461:30;;-1:-1:-1;;;6461:30:14;;6485:4;6461:30;;;3057:74:18;-1:-1:-1;;;;;6461:15:14;;;;;3030:18:18;;6461:30:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;;;;:::i;:::-;6437:82;;6530:15;6548:70;6564:7;6573:13;6588:29;6602:5;6609:7;-1:-1:-1;;;;;5015:21:14;;;4988:7;5015:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;4913:140;6548:70;6713:30;;-1:-1:-1;;;6713:30:14;;6737:4;6713:30;;;3057:74:18;6530:88:14;;-1:-1:-1;;;;;;6713:15:14;;;;;3030:18:18;;6713:30:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6703:7;:40;6699:113;;;6770:30;;-1:-1:-1;;;6770:30:14;;6794:4;6770:30;;;3057:74:18;-1:-1:-1;;;;;6770:15:14;;;;;3030:18:18;;6770:30:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6760:40;;6699:113;6828:11;;6824:266;;-1:-1:-1;;;;;6856:21:14;;;;;;;:14;:21;;;;;;;;:30;;;;;;;;;;;:41;;6890:7;;6856:21;:41;;6890:7;;6856:41;:::i;:::-;;;;-1:-1:-1;;;;;;;6912:26:14;;;;;;:19;:26;;;;;:37;;6942:7;;6912:26;:37;;6942:7;;6912:37;:::i;:::-;;;;-1:-1:-1;6966:47:14;;-1:-1:-1;6989:5:14;6996:7;7005;6966:22;:47::i;:::-;7033:45;;;-1:-1:-1;;;;;206:55:18;;;188:74;;293:2;278:18;;271:34;;;7033:45:14;;;;;161:18:18;7033:45:14;;;;;;;6426:671;;6347:750;;:::o;7866:1463::-;7946:9;;-1:-1:-1;;;;;1604:19:0;;;:23;7988:78:14;;;;-1:-1:-1;;;7988:78:14;;26477:2:18;7988:78:14;;;26459:21:18;26516:2;26496:18;;;26489:30;26555:31;26535:18;;;26528:59;26604:18;;7988:78:14;26275:353:18;7988:78:14;8095:1;8085:7;:11;;;8077:53;;;;-1:-1:-1;;;8077:53:14;;26835:2:18;8077:53:14;;;26817:21:18;26874:2;26854:18;;;26847:30;26913:31;26893:18;;;26886:59;26962:18;;8077:53:14;26633:353:18;8077:53:14;8211:16;8247:1;8243:5;;8238:140;8254:7;:14;8250:18;;8238:140;;;8308:7;-1:-1:-1;;;;;8294:21:14;:7;8302:1;8294:10;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;8294:10:14;:21;8290:77;;-1:-1:-1;8350:1:14;8290:77;8270:3;;;;:::i;:::-;;;;8238:140;;;8427:11;8442:1;8427:16;8423:899;;8536:11;;;;8532:600;;8568:11;:9;:11::i;:::-;8615:1;8598:14;:18;;;8615:1;-1:-1:-1;8635:105:14;8651:7;:14;8647:18;;8635:105;;;8719:1;8695:9;:21;8705:7;8713:1;8705:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;8705:10:14;8695:21;;;;;;;;;;;;:25;8667:3;;;;:::i;:::-;;;;8635:105;;;8803:1;8799:5;;8794:323;8810:10;:17;8806:21;;8794:323;;;8857:12;8872:10;8883:1;8872:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;8872:13:14;8908:26;;;:19;:26;;;;;;:30;;;8872:13;;-1:-1:-1;8872:13:14;-1:-1:-1;8973:125:14;8989:7;:14;8985:18;;8973:125;;;-1:-1:-1;;;;;9037:21:14;;9073:1;9037:21;;;:14;:21;;;;;9059:7;:10;;9073:1;;9059:7;9067:1;;9059:10;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;9059:10:14;9037:33;;;;;;;;;;;;:37;9005:3;;;;:::i;:::-;;;;8973:125;;;-1:-1:-1;8829:3:14;;;;:::i;:::-;;;;8794:323;;;9148:7;:21;;;;;;;;;;;;-1:-1:-1;;9148:21:14;-1:-1:-1;;;;;9148:21:14;;;;;;;;-1:-1:-1;9184:16:14;;;:7;9148:21;9184:16;;;;:26;;;;;;;9240:12;;:22;;9184:26;9240:22;:::i;:::-;9225:12;:37;9282:28;;;-1:-1:-1;;;;;27181:55:18;;27163:74;;27285:6;27273:19;;27268:2;27253:18;;27246:47;9282:28:14;;27136:18:18;9282:28:14;;;;;;;7935:1394;;;7866:1463;;:::o;24236:407:5:-;24411:31;24424:4;24430:2;24434:7;24411:12;:31::i;:::-;-1:-1:-1;;;;;24457:14:5;;;:19;24453:183;;24496:56;24527:4;24533:2;24537:7;24546:5;24496:30;:56::i;:::-;24491:145;;24580:40;;-1:-1:-1;;;24580:40:5;;;;;;;;;;;12871:108:17;12931:13;12964:7;12957:14;;;;;:::i;40771:1745:5:-;40836:17;41270:4;41263;41257:11;41253:22;41362:1;41356:4;41349:15;41437:4;41434:1;41430:12;41423:19;;;41519:1;41514:3;41507:14;41623:3;41862:5;41844:428;41910:1;41905:3;41901:11;41894:18;;42081:2;42075:4;42071:13;42067:2;42063:22;42058:3;42050:36;42175:2;42165:13;;42232:25;41844:428;42232:25;-1:-1:-1;42302:13:5;;;-1:-1:-1;;42417:14:5;;;42479:19;;;42417:14;40771:1745;-1:-1:-1;40771:1745:5:o;10668:624:14:-;10767:4;-1:-1:-1;;;;;1604:19:0;;;:23;;10738:33:14;10730:81;;;;-1:-1:-1;;;10730:81:14;;27506:2:18;10730:81:14;;;27488:21:18;27545:2;27525:18;;;27518:30;27584:34;27564:18;;;27557:62;27655:5;27635:18;;;27628:33;27678:19;;10730:81:14;27304:399:18;10730:81:14;10856:38;;-1:-1:-1;;;10856:38:14;;10888:4;10856:38;;;3057:74:18;-1:-1:-1;;;;;10856:23:14;;;;;3030:18:18;;10856:38:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;10975:16;11011:9;11006:160;11030:10;:17;11026:21;;11006:160;;;11097:5;-1:-1:-1;;;;;11073:30:14;:10;11084:1;11073:13;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;11073:13:14;:30;11069:86;;11138:1;11124:15;;11069:86;11049:3;;;;:::i;:::-;;;;11006:160;;;-1:-1:-1;11184:16:14;;11176:65;;;;-1:-1:-1;;;11176:65:14;;27910:2:18;11176:65:14;;;27892:21:18;27949:2;27929:18;;;27922:30;27988:34;27968:18;;;27961:62;28059:6;28039:18;;;28032:34;28083:19;;11176:65:14;27708:400:18;11176:65:14;-1:-1:-1;11254:10:14;:30;;;;;;;-1:-1:-1;11254:30:14;;;;;;;;-1:-1:-1;;11254:30:14;-1:-1:-1;;;;;11254:30:14;;;;;;;;;;10668:624::o;3932:716:16:-;4356:23;4382:69;4410:4;4382:69;;;;;;;;;;;;;;;;;4390:5;-1:-1:-1;;;;;4382:27:16;;;:69;;;;;:::i;:::-;4466:17;;4356:95;;-1:-1:-1;4466:21:16;4462:179;;4563:10;4552:30;;;;;;;;;;;;:::i;:::-;4544:85;;;;-1:-1:-1;;;4544:85:16;;28315:2:18;4544:85:16;;;28297:21:18;28354:2;28334:18;;;28327:30;28393:34;28373:18;;;28366:62;28464:12;28444:18;;;28437:40;28494:19;;4544:85:16;28113:406:18;5186:455:0;5356:12;5414:5;5389:21;:30;;5381:81;;;;-1:-1:-1;;;5381:81:0;;28726:2:18;5381:81:0;;;28708:21:18;28765:2;28745:18;;;28738:30;28804:34;28784:18;;;28777:62;28875:8;28855:18;;;28848:36;28901:19;;5381:81:0;28524:402:18;5381:81:0;5474:12;5488:23;5515:6;-1:-1:-1;;;;;5515:11:0;5534:5;5541:4;5515:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5473:73;;;;5564:69;5591:6;5599:7;5608:10;5620:12;5564:26;:69::i;:::-;5557:76;5186:455;-1:-1:-1;;;;;;;5186:455:0:o;7275:399:14:-;7421:7;7441:16;7472:12;;7488:1;7472:17;7468:173;;-1:-1:-1;7517:1:14;7468:173;;;7599:12;;-1:-1:-1;;;;;7579:16:14;;;;;;:7;:16;;;;;;7614:15;;7599:12;7563:32;;:13;:32;:::i;:::-;7562:49;;;;:::i;:::-;:67;;;;:::i;:::-;7551:78;7658:8;-1:-1:-1;;;;;7275:399:14:o;10691:248:17:-;10845:29;;;;:15;:29;;;;;;;;:38;10837:94;;;;-1:-1:-1;;;10837:94:17;;29425:2:18;10837:94:17;;;29407:21:18;29464:2;29444:18;;;29437:30;29503:34;29483:18;;;29476:62;29574:13;29554:18;;;29547:41;29605:19;;10837:94:17;29223:407:18;33623:689:5;33754:19;33760:2;33764:8;33754:5;:19::i;:::-;-1:-1:-1;;;;;33815:14:5;;;:19;33811:483;;33855:11;33869:13;33917:14;;;33950:233;33981:62;34020:1;34024:2;34028:7;;;;;;34037:5;33981:30;:62::i;:::-;33976:167;;34079:40;;-1:-1:-1;;;34079:40:5;;;;;;;;;;;33976:167;34178:3;34170:5;:11;33950:233;;34265:3;34248:13;;:20;34244:34;;34270:8;;;26727:716;26911:88;;;;;26890:4;;-1:-1:-1;;;;;26911:45:5;;;;;:88;;835:10:1;;26978:4:5;;26984:7;;26993:5;;26911:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26911:88:5;;;;;;;;-1:-1:-1;;26911:88:5;;;;;;;;;;;;:::i;:::-;;;26907:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27194:6;:13;27211:1;27194:18;27190:235;;27240:40;;-1:-1:-1;;;27240:40:5;;;;;;;;;;;27190:235;27383:6;27377:13;27368:6;27364:2;27360:15;27353:38;26907:529;27070:64;;27080:54;27070:64;;-1:-1:-1;27063:71:5;;7759:644:0;7944:12;7973:7;7969:427;;;8001:10;:17;8022:1;8001:22;7997:290;;-1:-1:-1;;;;;1604:19:0;;;8211:60;;;;-1:-1:-1;;;8211:60:0;;30608:2:18;8211:60:0;;;30590:21:18;30647:2;30627:18;;;30620:30;30686:31;30666:18;;;30659:59;30735:18;;8211:60:0;30406:353:18;8211:60:0;-1:-1:-1;8308:10:0;8301:17;;7969:427;8351:33;8359:10;8371:12;8351:7;:33::i;27905:2966:5:-;27978:20;28001:13;;;28029;;;28025:44;;28051:18;;;;;;;;;;;;;;28025:44;28082:61;28112:1;28116:2;28120:12;28134:8;28082:21;:61::i;:::-;-1:-1:-1;;;;;28557:22:5;;;;;;:18;:22;;;;1618:2;28557:22;;;:71;;28595:32;28583:45;;28557:71;;;28871:31;;;:17;:31;;;;;-1:-1:-1;15607:15:5;;15581:24;15577:46;15176:11;15151:23;15147:41;15144:52;15134:63;;28871:173;;29106:23;;;;28871:31;;28557:22;;29871:25;28557:22;;29724:335;30385:1;30371:12;30367:20;30325:346;30426:3;30417:7;30414:16;30325:346;;30644:7;30634:8;30631:1;30604:25;30601:1;30598;30593:59;30479:1;30466:15;30325:346;;;30329:77;30704:8;30716:1;30704:13;30700:45;;30726:19;;;;;;;;;;;;;;30700:45;30762:13;:19;-1:-1:-1;865:211:16;;;:::o;8945:552:0:-;9106:17;;:21;9102:388;;9338:10;9332:17;9395:15;9382:10;9378:2;9374:19;9367:44;9102:388;9465:12;9458:20;;-1:-1:-1;;;9458:20:0;;;;;;;;:::i;316:177:18:-;401:66;394:5;390:78;383:5;380:89;370:117;;483:1;480;473:12;498:245;556:6;609:2;597:9;588:7;584:23;580:32;577:52;;;625:1;622;615:12;577:52;664:9;651:23;683:30;707:5;683:30;:::i;940:154::-;-1:-1:-1;;;;;1019:5:18;1015:54;1008:5;1005:65;995:93;;1084:1;1081;1074:12;1099:435;1166:6;1174;1227:2;1215:9;1206:7;1202:23;1198:32;1195:52;;;1243:1;1240;1233:12;1195:52;1282:9;1269:23;1301:31;1326:5;1301:31;:::i;:::-;1351:5;-1:-1:-1;1408:2:18;1393:18;;1380:32;1456:26;1443:40;;1431:53;;1421:81;;1498:1;1495;1488:12;1421:81;1521:7;1511:17;;;1099:435;;;;;:::o;1539:117::-;1624:6;1617:5;1613:18;1606:5;1603:29;1593:57;;1646:1;1643;1636:12;1661:245;1719:6;1772:2;1760:9;1751:7;1747:23;1743:32;1740:52;;;1788:1;1785;1778:12;1740:52;1827:9;1814:23;1846:30;1870:5;1846:30;:::i;1911:250::-;1996:1;2006:113;2020:6;2017:1;2014:13;2006:113;;;2096:11;;;2090:18;2077:11;;;2070:39;2042:2;2035:10;2006:113;;;-1:-1:-1;;2153:1:18;2135:16;;2128:27;1911:250::o;2166:330::-;2208:3;2246:5;2240:12;2273:6;2268:3;2261:19;2289:76;2358:6;2351:4;2346:3;2342:14;2335:4;2328:5;2324:16;2289:76;:::i;:::-;2410:2;2398:15;-1:-1:-1;;2394:88:18;2385:98;;;;2485:4;2381:109;;2166:330;-1:-1:-1;;2166:330:18:o;2501:220::-;2650:2;2639:9;2632:21;2613:4;2670:45;2711:2;2700:9;2696:18;2688:6;2670:45;:::i;2726:180::-;2785:6;2838:2;2826:9;2817:7;2813:23;2809:32;2806:52;;;2854:1;2851;2844:12;2806:52;-1:-1:-1;2877:23:18;;2726:180;-1:-1:-1;2726:180:18:o;3142:315::-;3210:6;3218;3271:2;3259:9;3250:7;3246:23;3242:32;3239:52;;;3287:1;3284;3277:12;3239:52;3326:9;3313:23;3345:31;3370:5;3345:31;:::i;:::-;3395:5;3447:2;3432:18;;;;3419:32;;-1:-1:-1;;;3142:315:18:o;3462:681::-;3633:2;3685:21;;;3755:13;;3658:18;;;3777:22;;;3604:4;;3633:2;3856:15;;;;3830:2;3815:18;;;3604:4;3899:218;3913:6;3910:1;3907:13;3899:218;;;3978:13;;-1:-1:-1;;;;;3974:62:18;3962:75;;4092:15;;;;4057:12;;;;3935:1;3928:9;3899:218;;;-1:-1:-1;4134:3:18;;3462:681;-1:-1:-1;;;;;;3462:681:18:o;4330:118::-;4416:5;4409:13;4402:21;4395:5;4392:32;4382:60;;4438:1;4435;4428:12;4453:241;4509:6;4562:2;4550:9;4541:7;4537:23;4533:32;4530:52;;;4578:1;4575;4568:12;4530:52;4617:9;4604:23;4636:28;4658:5;4636:28;:::i;4699:255::-;4766:6;4819:2;4807:9;4798:7;4794:23;4790:32;4787:52;;;4835:1;4832;4825:12;4787:52;4874:9;4861:23;4893:31;4918:5;4893:31;:::i;5404:456::-;5481:6;5489;5497;5550:2;5538:9;5529:7;5525:23;5521:32;5518:52;;;5566:1;5563;5556:12;5518:52;5605:9;5592:23;5624:31;5649:5;5624:31;:::i;:::-;5674:5;-1:-1:-1;5731:2:18;5716:18;;5703:32;5744:33;5703:32;5744:33;:::i;:::-;5404:456;;5796:7;;-1:-1:-1;;;5850:2:18;5835:18;;;;5822:32;;5404:456::o;6132:248::-;6200:6;6208;6261:2;6249:9;6240:7;6236:23;6232:32;6229:52;;;6277:1;6274;6267:12;6229:52;-1:-1:-1;;6300:23:18;;;6370:2;6355:18;;;6342:32;;-1:-1:-1;6132:248:18:o;6385:386::-;6452:6;6460;6513:2;6501:9;6492:7;6488:23;6484:32;6481:52;;;6529:1;6526;6519:12;6481:52;6568:9;6555:23;6587:31;6612:5;6587:31;:::i;:::-;6637:5;-1:-1:-1;6694:2:18;6679:18;;6666:32;6707;6666;6707;:::i;7022:403::-;7105:6;7113;7166:2;7154:9;7145:7;7141:23;7137:32;7134:52;;;7182:1;7179;7172:12;7134:52;7221:9;7208:23;7240:31;7265:5;7240:31;:::i;:::-;7290:5;-1:-1:-1;7347:2:18;7332:18;;7319:32;7360:33;7319:32;7360:33;:::i;7430:184::-;-1:-1:-1;;;7479:1:18;7472:88;7579:4;7576:1;7569:15;7603:4;7600:1;7593:15;7619:334;7690:2;7684:9;7746:2;7736:13;;-1:-1:-1;;7732:86:18;7720:99;;7849:18;7834:34;;7870:22;;;7831:62;7828:88;;;7896:18;;:::i;:::-;7932:2;7925:22;7619:334;;-1:-1:-1;7619:334:18:o;7958:466::-;8023:5;8057:18;8049:6;8046:30;8043:56;;;8079:18;;:::i;:::-;8117:116;8227:4;-1:-1:-1;;8153:2:18;8145:6;8141:15;8137:88;8133:99;8117:116;:::i;:::-;8108:125;;8256:6;8249:5;8242:21;8296:3;8287:6;8282:3;8278:16;8275:25;8272:45;;;8313:1;8310;8303:12;8272:45;8362:6;8357:3;8350:4;8343:5;8339:16;8326:43;8416:1;8409:4;8400:6;8393:5;8389:18;8385:29;8378:40;7958:466;;;;;:::o;8429:451::-;8498:6;8551:2;8539:9;8530:7;8526:23;8522:32;8519:52;;;8567:1;8564;8557:12;8519:52;8607:9;8594:23;8640:18;8632:6;8629:30;8626:50;;;8672:1;8669;8662:12;8626:50;8695:22;;8748:4;8740:13;;8736:27;-1:-1:-1;8726:55:18;;8777:1;8774;8767:12;8726:55;8800:74;8866:7;8861:2;8848:16;8843:2;8839;8835:11;8800:74;:::i;10002:382::-;10067:6;10075;10128:2;10116:9;10107:7;10103:23;10099:32;10096:52;;;10144:1;10141;10134:12;10096:52;10183:9;10170:23;10202:31;10227:5;10202:31;:::i;:::-;10252:5;-1:-1:-1;10309:2:18;10294:18;;10281:32;10322:30;10281:32;10322:30;:::i;10389:795::-;10484:6;10492;10500;10508;10561:3;10549:9;10540:7;10536:23;10532:33;10529:53;;;10578:1;10575;10568:12;10529:53;10617:9;10604:23;10636:31;10661:5;10636:31;:::i;:::-;10686:5;-1:-1:-1;10743:2:18;10728:18;;10715:32;10756:33;10715:32;10756:33;:::i;:::-;10808:7;-1:-1:-1;10862:2:18;10847:18;;10834:32;;-1:-1:-1;10917:2:18;10902:18;;10889:32;10944:18;10933:30;;10930:50;;;10976:1;10973;10966:12;10930:50;10999:22;;11052:4;11044:13;;11040:27;-1:-1:-1;11030:55:18;;11081:1;11078;11071:12;11030:55;11104:74;11170:7;11165:2;11152:16;11147:2;11143;11139:11;11104:74;:::i;:::-;11094:84;;;10389:795;;;;;;;:::o;12364:437::-;12443:1;12439:12;;;;12486;;;12507:61;;12561:4;12553:6;12549:17;12539:27;;12507:61;12614:2;12606:6;12603:14;12583:18;12580:38;12577:218;;-1:-1:-1;;;12648:1:18;12641:88;12752:4;12749:1;12742:15;12780:4;12777:1;12770:15;12577:218;;12364:437;;;:::o;13833:245::-;13900:6;13953:2;13941:9;13932:7;13928:23;13924:32;13921:52;;;13969:1;13966;13959:12;13921:52;14001:9;13995:16;14020:28;14042:5;14020:28;:::i;14444:184::-;-1:-1:-1;;;14493:1:18;14486:88;14593:4;14590:1;14583:15;14617:4;14614:1;14607:15;14633:125;14698:9;;;14719:10;;;14716:36;;;14732:18;;:::i;15172:184::-;15242:6;15295:2;15283:9;15274:7;15270:23;15266:32;15263:52;;;15311:1;15308;15301:12;15263:52;-1:-1:-1;15334:16:18;;15172:184;-1:-1:-1;15172:184:18:o;15361:1009::-;15455:6;15486:2;15529;15517:9;15508:7;15504:23;15500:32;15497:52;;;15545:1;15542;15535:12;15497:52;15578:9;15572:16;15607:18;15648:2;15640:6;15637:14;15634:34;;;15664:1;15661;15654:12;15634:34;15702:6;15691:9;15687:22;15677:32;;15747:7;15740:4;15736:2;15732:13;15728:27;15718:55;;15769:1;15766;15759:12;15718:55;15798:2;15792:9;15820:2;15816;15813:10;15810:36;;;15826:18;;:::i;:::-;15872:2;15869:1;15865:10;15855:20;;15895:28;15919:2;15915;15911:11;15895:28;:::i;:::-;15957:15;;;16027:11;;;16023:20;;;15988:12;;;;16055:19;;;16052:39;;;16087:1;16084;16077:12;16052:39;16111:11;;;;16131:209;16147:6;16142:3;16139:15;16131:209;;;16220:3;16214:10;16201:23;;16237:30;16261:5;16237:30;:::i;:::-;16280:18;;;16164:12;;;;16318;;;;16131:209;;;16359:5;15361:1009;-1:-1:-1;;;;;;;;15361:1009:18:o;16375:184::-;-1:-1:-1;;;16424:1:18;16417:88;16524:4;16521:1;16514:15;16548:4;16545:1;16538:15;17685:168;17758:9;;;17789;;17806:15;;;17800:22;;17786:37;17776:71;;17827:18;;:::i;17858:274::-;17898:1;17924;17914:189;;-1:-1:-1;;;17956:1:18;17949:88;18060:4;18057:1;18050:15;18088:4;18085:1;18078:15;17914:189;-1:-1:-1;18117:9:18;;17858:274::o;18975:545::-;19077:2;19072:3;19069:11;19066:448;;;19113:1;19138:5;19134:2;19127:17;19183:4;19179:2;19169:19;19253:2;19241:10;19237:19;19234:1;19230:27;19224:4;19220:38;19289:4;19277:10;19274:20;19271:47;;;-1:-1:-1;19312:4:18;19271:47;19367:2;19362:3;19358:12;19355:1;19351:20;19345:4;19341:31;19331:41;;19422:82;19440:2;19433:5;19430:13;19422:82;;;19485:17;;;19466:1;19455:13;19422:82;;19756:1471;19882:3;19876:10;19909:18;19901:6;19898:30;19895:56;;;19931:18;;:::i;:::-;19960:97;20050:6;20010:38;20042:4;20036:11;20010:38;:::i;:::-;20004:4;19960:97;:::i;:::-;20112:4;;20176:2;20165:14;;20193:1;20188:782;;;;21014:1;21031:6;21028:89;;;-1:-1:-1;21083:19:18;;;21077:26;21028:89;-1:-1:-1;;19653:1:18;19649:11;;;19645:84;19641:89;19631:100;19737:1;19733:11;;;19628:117;21130:81;;20158:1063;;20188:782;18922:1;18915:14;;;18959:4;18946:18;;-1:-1:-1;;20224:79:18;;;20401:236;20415:7;20412:1;20409:14;20401:236;;;20504:19;;;20498:26;20483:42;;20596:27;;;;20564:1;20552:14;;;;20431:19;;20401:236;;;20405:3;20665:6;20656:7;20653:19;20650:261;;;20726:19;;;20720:26;-1:-1:-1;;20809:1:18;20805:14;;;20821:3;20801:24;20797:97;20793:102;20778:118;20763:134;;20650:261;-1:-1:-1;;;;;20957:1:18;20941:14;;;20937:22;20924:36;;-1:-1:-1;19756:1471:18:o;21232:663::-;21512:3;21550:6;21544:13;21566:66;21625:6;21620:3;21613:4;21605:6;21601:17;21566:66;:::i;:::-;21695:13;;21654:16;;;;21717:70;21695:13;21654:16;21764:4;21752:17;;21717:70;:::i;:::-;21852:7;21809:20;;21838:22;;;21887:1;21876:13;;21232:663;-1:-1:-1;;;;21232:663:18:o;25098:195::-;25137:3;-1:-1:-1;;25161:5:18;25158:77;25155:103;;25238:18;;:::i;:::-;-1:-1:-1;25285:1:18;25274:13;;25098:195::o;25721:128::-;25788:9;;;25809:11;;;25806:37;;;25823:18;;:::i;28931:287::-;29060:3;29098:6;29092:13;29114:66;29173:6;29168:3;29161:4;29153:6;29149:17;29114:66;:::i;:::-;29196:16;;;;;28931:287;-1:-1:-1;;28931:287:18:o;29635:512::-;29829:4;-1:-1:-1;;;;;29939:2:18;29931:6;29927:15;29916:9;29909:34;29991:2;29983:6;29979:15;29974:2;29963:9;29959:18;29952:43;;30031:6;30026:2;30015:9;30011:18;30004:34;30074:3;30069:2;30058:9;30054:18;30047:31;30095:46;30136:3;30125:9;30121:19;30113:6;30095:46;:::i;:::-;30087:54;29635:512;-1:-1:-1;;;;;;29635:512:18:o;30152:249::-;30221:6;30274:2;30262:9;30253:7;30249:23;30245:32;30242:52;;;30290:1;30287;30280:12;30242:52;30322:9;30316:16;30341:30;30365:5;30341:30;:::i

Swarm Source

ipfs://3cfa432c67c2e27fbd47eca6ba4517bdd1d950b7d77030549207242e2642b472
Loading...
Loading
Loading...
Loading
[ 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.