ETH Price: $3,680.78 (+1.71%)

Token

Friends Of Nick Davis ()
 

Overview

Max Total Supply

390

Holders

98

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
hirtme.eth
0xBfcC73DC4b03f0fEBb5Ce1d53e5E410a3ee8CFC1
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:
NickDavisTribute

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity Multiple files format)

File 19 of 23: NickDavisTribute.sol
// SPDX-License-Identifier: GPL-3.0
// ----------    Friends of Nick Davis   ----------
// ----------   Tribute NFT Collection   ----------

pragma solidity 0.8.10;

import "./ERC1155Burnable.sol";
import "./IERC721.sol";
import "./IERC1155.sol";
import "./Ownable.sol";
import "./ReentrancyGuard.sol";
import "./ERC721Enumerable.sol";
import "./ERC721.sol";

import {DefaultOperatorFilterer} from "./DefaultOperatorFilterer.sol";
contract OwnableDelegateProxy {}

/**
 * Used to delegate ownership of a contract to another address, to save on unneeded transactions to approve contract use for users
 */
contract ProxyRegistry {
    mapping(address => OwnableDelegateProxy) public proxies;
}

contract NickDavisTribute is ERC1155Burnable, Ownable, ReentrancyGuard, DefaultOperatorFilterer {
	using Strings for uint256;

    uint256 public currentTokenID = 1;
	uint256 public totalMinted = 0;
    uint256 public totalWithdrawn = 0;
    
	address public minter;
	bool public isMintingEnabled = true;

    uint256 public price = 0.01 ether;
    uint256 public maxPerTx = 10;

	string private _baseTokenURI = "https://houseoffirst.com:1335/tribute/opensea/";
	string private _contractURI = "https://houseoffirst.com:1335/tribute/opensea/";

    address public proxyRegistryAddress = 0xa5409ec958C83C3f309868babACA7c86DCB077c1; // OpenSea Mainnet Proxy Registry address

	event CustomAction(uint256 nftID, uint256 value, uint256 actionID, string payload);
	string public name;

	constructor() ERC1155(_baseTokenURI) {
		name = "Friends Of Nick Davis";
		minter = msg.sender;
        setStartEndTimesForToken(1, 1675429200, 0);
        setStartEndTimesForToken(2, 1675429200, 0);
        setStartEndTimesForToken(3, 1675429200, 0);
        setStartEndTimesForToken(4, 1675429200, 0);
	}

    address[] internal _burners;
    uint256[] internal _burntTokenIds;
    uint256[] internal _burntTokenAmounts;
    address[] internal _owners;
    mapping(address => bool) public addressIsAnOwner;
	mapping(uint256 => bool) public tokenIdBurnEnabled;
	mapping(uint256 => uint256) public tokenIdTotalSupply;
	mapping(uint256 => uint256) public tokenIdStartTimes;
	mapping(uint256 => uint256) public tokenIdEndTimes;


	function totalSupply() public view virtual returns (uint256) {
		uint256 total = 0;
        for(uint256 tokenId = 0; tokenId <= currentTokenID; tokenId++) {
            total += tokenIdTotalSupply[tokenId];
        }
		return total;
    }

	function totalSupplyForTokenId(uint256 tokenId) public view virtual returns (uint256) {
		return tokenIdTotalSupply[tokenId];
    }

    // returns current owners
    function getOwners() external view returns (address[] memory) {
        return _owners;
    }

    function getBurners() external view returns (address[] memory) {
        return _burners;
    }

    function getBurntTokenIds() external view returns (uint256[] memory) {
        return _burntTokenIds;
    }

    function getBurntTokenAmounts() external view returns (uint256[] memory) {
        return _burntTokenAmounts;
    }

    function setCurrentTokenId(uint256 newCurrentTokenID) public onlyOwner {
		currentTokenID = newCurrentTokenID;
	}

	function setTokenIdBurnEnabled(uint256 tokenId, bool burnEnabled) public onlyOwner {
		tokenIdBurnEnabled[tokenId] = burnEnabled;
	}

	function canBurnToken(uint256 tokenId) public view returns (bool) {
		return tokenIdBurnEnabled[tokenId];
	}

    function addressIsOwner(address addr) public view returns (bool) {
        return addressIsAnOwner[addr];
    }

    function getNFTPrice() public view returns (uint256) {
        return price;
    }

    function getTokenIdStartTime(uint256 tokenId) public view returns (uint256) {
        return tokenIdStartTimes[tokenId];
    }

    function getTokenIdEndTime(uint256 tokenId) public view returns (uint256) {
        return tokenIdEndTimes[tokenId];
    }

    function getCurrentStartTime() public view returns (uint256) {
        return getTokenIdStartTime(currentTokenID);
    }

    function getCurrentEndTime() public view returns (uint256) {
        return getTokenIdEndTime(currentTokenID);
    }

	function tokenBalancesByAddress(address addr) public view returns(uint256[] memory) {
		uint256[] memory tokenBals = new uint256[](currentTokenID + 1);
		for(uint256 tokenId = 0; tokenId <= currentTokenID; tokenId++) {
			tokenBals[tokenId] = balanceOf(addr, tokenId);
		}
		return tokenBals;
	}

	function tokenOwnershipsByAddress(address addr) public view returns(bool[] memory) {
		bool[] memory tokenOwnerships = new bool[](currentTokenID + 1);
		for(uint256 tokenId = 0; tokenId <= currentTokenID; tokenId++) {
			tokenOwnerships[tokenId] = balanceOf(addr, tokenId) > 0;
		}
		return tokenOwnerships;
	}

	// mint 1 type of NFT with quantity x to the receiver
	function mint(
		address receiver,
		uint256 quantity,
		bytes memory data // "0x"
	) payable external {
		require(isMintingEnabled, "minting disabled");
        require(block.timestamp >= getCurrentStartTime(), "minting not open yet");
        require(block.timestamp < getCurrentEndTime(), "minting closed");
        require(quantity > 0 && quantity <= maxPerTx, "Invalid quantity");
        require(msg.value >= price * quantity, "Not Enough ETH");
		_mint(receiver, currentTokenID, quantity, data);
	}

    function isMintingOpen() public view returns(bool) {
        if(!isMintingEnabled) {
            return false;
        }
        if(block.timestamp < getCurrentStartTime()) {
            return false;
        }
        if(block.timestamp > getCurrentEndTime()) {
            return false;
        }
        return true;
    }

	// airdrops an NFT
	function airdrop(
		address[] memory receivers,
		uint256[] memory quantities,
		uint256[] memory tokenIds,
		bytes[] memory datas // "0x"
	) external {
		require(receivers.length == quantities.length, "arrays should be equal");
		require(receivers.length == tokenIds.length, "arrays should be equal 2");
		require(msg.sender == minter, "only minter account can call this");
		require(isMintingEnabled == true, "minting disabled");
		for (uint256 i = 0; i < receivers.length; i++) {
			_mint(receivers[i], tokenIds[i], quantities[i], datas[i]);
		}
	}

	function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual override {
		require(id <= currentTokenID, "token id does not exist");
		super._mint(to, id, amount, data);
		tokenIdTotalSupply[id] += amount;
        if(!addressIsAnOwner[to]) {
            _owners.push(to);
            addressIsAnOwner[to] = true;
        }
	}

    // transfers NFTs
	function transferMany(
		address[] memory receivers,
		uint256[] memory quantities,
		uint256[] memory tokenIds,
		bytes[] memory datas // "0x0"
	) external {
		require(receivers.length == quantities.length, "arrays should be equal");
		require(receivers.length == tokenIds.length, "arrays should be equal 2");
		require(msg.sender == minter, "only minter account can call this");
		for (uint256 i = 0; i < receivers.length; i++) {
            address receiver = receivers[i];
            uint256 tokenId = tokenIds[i];
            uint256 quantity = quantities[i];
            _safeTransferFrom(msg.sender, receiver, tokenId, quantity, datas[i]);
		}
	}

	function customAction(
		uint256 tokenId,
		uint256 id,
		string memory what
	) external payable {
		require(balanceOf(msg.sender, tokenId) > 0, "NFT ownership required");
        require(tokenId <= currentTokenID, "token id does not exist");
		emit CustomAction(tokenId, msg.value, id, what);
	}

    function getTotalBalance(address addr) public view returns(uint256) {
        uint256 totalBal = 0;
        for(uint256 tokenId = 0; tokenId <= currentTokenID; tokenId++) {
            totalBal += balanceOf(addr, tokenId);
        }
        return totalBal;
    }

	function uri(uint256 tokenId) public view override returns (string memory) {
		return string(abi.encodePacked(_baseTokenURI, uint2str(tokenId)));
	}

	function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
    	return string(abi.encodePacked(_baseTokenURI, uint2str(tokenId)));
    }

	//sets the minter address
	function setMinter(address _newMinter) public onlyOwner {
		minter = _newMinter;
	}

	function toggleMinting(bool _enabled) public onlyOwner {
		isMintingEnabled = _enabled;
	}

	function contractURI() public view returns (string memory) {
		return _contractURI;
	}

	function withdrawETH() public onlyOwner {
		payable(msg.sender).transfer(address(this).balance);
	}

	function setBaseURI(string memory newBaseURI) public onlyOwner {
		_baseTokenURI = newBaseURI;
	}

	function setContractURI(string memory newuri) public onlyOwner {
		_contractURI = newuri;
	}

    function setMaxPerTx(uint256 newMax) public onlyOwner {
		maxPerTx = newMax;
	}

    function setStartEndTimesForToken(uint256 tokenId, uint256 startTime, uint256 endTime) public onlyOwner {
        tokenIdStartTimes[tokenId] = startTime;
        if(endTime == 0) {
            endTime = startTime + 24 * 60 * 60;
        }
        tokenIdEndTimes[tokenId] = endTime;
    }

	function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) {
		if (_i == 0) {
			return "0";
		}
		uint256 j = _i;
		uint256 len;
		while (j != 0) {
			len++;
			j /= 10;
		}
		bytes memory bstr = new bytes(len);
		uint256 k = len;
		while (_i != 0) {
			k = k - 1;
			uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
			bytes1 b1 = bytes1(temp);
			bstr[k] = b1;
			_i /= 10;
		}
		return string(bstr);
	}

    function removeAddressFromOwners(address addr) internal {
        for (uint256 i; i < _owners.length; i++) {
            if (_owners[i] == addr) {
                _owners[i] = _owners[_owners.length - 1];
                _owners.pop();
                addressIsAnOwner[addr] = false;
                break;
            }
        }
    }

    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        // add recipient to list of owners
        if(to != address(0) && !addressIsAnOwner[to]) {
            _owners.push(to);
            addressIsAnOwner[to] = true;
        }
        // sent to the 0 address (burnt)
        if(to == address(0)) {
            for(uint256 i = 0; i < amounts.length; i++) {
                uint256 id = ids[i];
                uint256 amt = amounts[i];
                _burners.push(from);
                _burntTokenIds.push(id);
                _burntTokenAmounts.push(amt);
            }
        }
        // remove sender if they are no longer a holder
        if(from != address(0) && getTotalBalance(from) == 0) {
            removeAddressFromOwners(from);
        }
        super._afterTokenTransfer(operator, from, to, ids, amounts, data);
    }

	function burn(
        address account,
        uint256 id,
        uint256 value
    ) public virtual override {
		if(msg.sender != minter) {
			require(canBurnToken(id), "token burning for this id is not enabled");
		}
		super.burn(account, id, value);
		tokenIdTotalSupply[id] -= value;
	}

	function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory values
    ) public virtual override {
		for(uint256 i = 0; i < ids.length; i++) {
			if(msg.sender != minter) {
				require(canBurnToken(ids[i]), "token burning for this id is not enabled");
			}
			tokenIdTotalSupply[ids[i]] -= values[i];
		}
		super.burnBatch(account, ids, values);
	}

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

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

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

    /**
     * withdraw ETH from the contract (callable by Owner only)
     */
    function withdraw() public payable onlyOwner {
        uint256 val = address(this).balance;
        (bool success, ) = payable(msg.sender).call{
            value: val
        }("");
        require(success);
        totalWithdrawn += val;
        delete val;
    }
    /**
     * whitelist user's OpenSea proxy accounts to enable gas-less listings.
     */
    function isApprovedForAll(address owner, address operator) override public view returns (bool) {
        // Whitelist OpenSea proxy contract for easy trading.
        ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
        if (address(proxyRegistry.proxies(owner)) == operator) {
            return true;
        }
        return super.isApprovedForAll(owner, operator);
    }
}

File 1 of 23: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (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 functionCall(target, data, "Address: low-level call failed");
    }

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

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

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

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

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

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

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

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

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

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

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

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

File 2 of 23: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 3 of 23: DefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

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

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

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

File 4 of 23: ERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./IERC1155MetadataURI.sol";
import "./Address.sol";
import "./Context.sol";
import "./ERC165.sol";

/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC1155-isApprovedForAll}.
     */
    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[account][operator];
    }

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: transfer caller is not owner nor approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

File 5 of 23: ERC1155Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Burnable.sol)

pragma solidity ^0.8.0;

import "./ERC1155.sol";

/**
 * @dev Extension of {ERC1155} that allows token holders to destroy both their
 * own tokens and those that they have been approved to use.
 *
 * _Available since v3.1._
 */
abstract contract ERC1155Burnable is ERC1155 {
    function burn(
        address account,
        uint256 id,
        uint256 value
    ) public virtual {
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        _burn(account, id, value);
    }

    function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory values
    ) public virtual {
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        _burnBatch(account, ids, values);
    }
}

File 6 of 23: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 7 of 23: ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

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

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

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

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

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

        _balances[to] += 1;
        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

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

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 8 of 23: ERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./IERC721Enumerable.sol";

/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

File 9 of 23: IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 10 of 23: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

import "./IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

File 11 of 23: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 12 of 23: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 13 of 23: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

File 14 of 23: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 15 of 23: IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 16 of 23: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 17 of 23: IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

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 unregister(address addr) 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 18 of 23: MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 20 of 23: OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

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

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        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(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // 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) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

File 21 of 23: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

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

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

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

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

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

File 22 of 23: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

File 23 of 23: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nftID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actionID","type":"uint256"},{"indexed":false,"internalType":"string","name":"payload","type":"string"}],"name":"CustomAction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressIsAnOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addressIsOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"quantities","type":"uint256[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bytes[]","name":"datas","type":"bytes[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"canBurnToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTokenID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"what","type":"string"}],"name":"customAction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getBurners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurntTokenAmounts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurntTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenIdEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenIdStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintingOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCurrentTokenID","type":"uint256"}],"name":"setCurrentTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"setMaxPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newMinter","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"setStartEndTimesForToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"burnEnabled","type":"bool"}],"name":"setTokenIdBurnEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"toggleMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"tokenBalancesByAddress","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdBurnEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdEndTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdStartTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"tokenOwnershipsByAddress","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":"totalMinted","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":"uint256","name":"tokenId","type":"uint256"}],"name":"totalSupplyForTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"quantities","type":"uint256[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bytes[]","name":"datas","type":"bytes[]"}],"name":"transferMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6001600555600060068190556007556008805460ff60a01b1916600160a01b179055662386f26fc10000600955600a805560e0604052602e608081815290620054ad60a03980516200005a91600b9160209091019062000487565b506040518060600160405280602e8152602001620054ad602e913980516200008b91600c9160209091019062000487565b50600d80546001600160a01b03191673a5409ec958c83c3f309868babaca7c86dcb077c1179055348015620000bf57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb66001600b8054620000e6906200052d565b80601f016020809104026020016040519081016040528092919081815260200182805462000114906200052d565b8015620001655780601f10620001395761010080835404028352916020019162000165565b820191906000526020600020905b8154815290600101906020018083116200014757829003601f168201915b50505050506200017b816200037e60201b60201c565b50620001873362000397565b60016004556daaeb6d7670e522a718067333cd4e3b15620002d15780156200021f57604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200020057600080fd5b505af115801562000215573d6000803e3d6000fd5b50505050620002d1565b6001600160a01b03821615620002705760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620001e5565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620002b757600080fd5b505af1158015620002cc573d6000803e3d6000fd5b505050505b50506040805180820190915260158082527f467269656e6473204f66204e69636b204461766973000000000000000000000060209092019182526200031991600e9162000487565b50600880546001600160a01b031916331790556200033f60016363dd05506000620003e9565b6200035260026363dd05506000620003e9565b6200036560036363dd05506000620003e9565b6200037860046363dd05506000620003e9565b62000591565b80516200039390600290602084019062000487565b5050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6003546001600160a01b03163314620004485760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b60008381526016602052604090208290558062000471576200046e82620151806200056a565b90505b6000928352601760205260409092209190915550565b82805462000495906200052d565b90600052602060002090601f016020900481019282620004b9576000855562000504565b82601f10620004d457805160ff191683800117855562000504565b8280016001018555821562000504579182015b8281111562000504578251825591602001919060010190620004e7565b506200051292915062000516565b5090565b5b8082111562000512576000815560010162000517565b600181811c908216806200054257607f821691505b602082108114156200056457634e487b7160e01b600052602260045260246000fd5b50919050565b600082198211156200058c57634e487b7160e01b600052601160045260246000fd5b500190565b614f0c80620005a16000396000f3fe6080604052600436106103c15760003560e01c80638329de2f116101f2578063c87b56dd1161010d578063f242432a116100a0578063f968adbe1161006f578063f968adbe14610bab578063fafcbca414610bc1578063fb107a4f14610bd4578063fca3b5aa14610be957600080fd5b8063f242432a14610b2b578063f2fde38b14610b4b578063f5298aca14610b6b578063f7ed5a7814610b8b57600080fd5b8063d3de7933116100dc578063d3de793314610ab1578063e086e5ec14610ae1578063e8a3d48514610af6578063e985e9c514610b0b57600080fd5b8063c87b56dd146104ca578063cd7c032614610a1e578063cea65e9714610a4b578063d3d3819314610a9157600080fd5b8063a035b1fe11610185578063a22cb46511610154578063a22cb465146109b2578063a2309ff8146109d2578063bb62115e146109e8578063c6f6f216146109fe57600080fd5b8063a035b1fe14610942578063a0c09cb714610958578063a0e67e2b14610988578063a137be771461099d57600080fd5b8063938e3d7b116101c1578063938e3d7b146108da57806394d008ef146108fa5780639bf24b0c1461090d5780639f5502931461092d57600080fd5b80638329de2f1461085857806386fe8b431461087857806389404a791461089a5780638da5cb5b146108af57600080fd5b806341f43434116102e257806362eb575e116102755780636c1d2948116102445780636c1d2948146107c9578063715018a6146107e95780638022e3cd146107fe578063816f21b91461082b57600080fd5b806362eb575e14610722578063665ecccf1461074f5780636afeb9391461077c5780636b20c454146107a957600080fd5b806355c7ba14116102b157806355c7ba141461069757806355f804b3146106c9578063581e5777146106e95780635f7033e5146106fe57600080fd5b806341f43434146106125780634824a26f146106345780634b319713146106545780634e1273f41461066a57600080fd5b8063141fcdae1161035a57806321775c921161032957806321775c92146105a85780632eb2c2d6146105ca5780633ccfd60b146105ea57806340b4dd87146105f257600080fd5b8063141fcdae1461052a57806318160ddd1461054e5780631a206910146105635780631f2818ad1461057857600080fd5b8063075461721161039657806307546172146104785780630e89341c146104ca57806311d38c5d146104ea57806312b583491461051757600080fd5b8062d1bb01146103c6578062fdd58e1461040657806301ffc9a71461042657806306fdde0314610456575b600080fd5b3480156103d257600080fd5b506103f36103e13660046140a8565b60009081526016602052604090205490565b6040519081526020015b60405180910390f35b34801561041257600080fd5b506103f36104213660046140e3565b610c09565b34801561043257600080fd5b5061044661044136600461413d565b610ccf565b60405190151581526020016103fd565b34801561046257600080fd5b5061046b610db2565b6040516103fd91906141d7565b34801561048457600080fd5b506008546104a59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103fd565b3480156104d657600080fd5b5061046b6104e53660046140a8565b610e40565b3480156104f657600080fd5b506103f36105053660046140a8565b60009081526017602052604090205490565b34801561052357600080fd5b50476103f3565b34801561053657600080fd5b506005546000908152601760205260409020546103f3565b34801561055a57600080fd5b506103f3610e79565b34801561056f57600080fd5b50610446610eba565b34801561058457600080fd5b506104466105933660046140a8565b60146020526000908152604090205460ff1681565b3480156105b457600080fd5b506105c86105c33660046141ff565b610f29565b005b3480156105d657600080fd5b506105c86105e53660046143bb565b610fda565b6105c8611089565b3480156105fe57600080fd5b506105c861060d3660046144d8565b611162565b34801561061e57600080fd5b506104a56daaeb6d7670e522a718067333cd4e81565b34801561064057600080fd5b506105c861064f3660046144d8565b611333565b34801561066057600080fd5b506103f360075481565b34801561067657600080fd5b5061068a6106853660046145fd565b61155f565b6040516103fd919061469c565b3480156106a357600080fd5b506008546104469074010000000000000000000000000000000000000000900460ff1681565b3480156106d557600080fd5b506105c86106e43660046146af565b61169d565b3480156106f557600080fd5b5061068a61171b565b34801561070a57600080fd5b506005546000908152601660205260409020546103f3565b34801561072e57600080fd5b506103f361073d3660046140a8565b60166020526000908152604090205481565b34801561075b57600080fd5b506103f361076a3660046140a8565b60156020526000908152604090205481565b34801561078857600080fd5b506103f36107973660046140a8565b60176020526000908152604090205481565b3480156107b557600080fd5b506105c86107c43660046146e4565b611773565b3480156107d557600080fd5b5061068a6107e436600461475a565b6118c0565b3480156107f557600080fd5b506105c8611963565b34801561080a57600080fd5b5061081e61081936600461475a565b6119d6565b6040516103fd9190614777565b34801561083757600080fd5b506103f36108463660046140a8565b60009081526015602052604090205490565b34801561086457600080fd5b506105c86108733660046140a8565b611a7a565b34801561088457600080fd5b5061088d611ae6565b6040516103fd91906147bd565b3480156108a657600080fd5b506007546103f3565b3480156108bb57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166104a5565b3480156108e657600080fd5b506105c86108f53660046146af565b611b54565b6105c861090836600461480b565b611bce565b34801561091957600080fd5b506105c861092836600461485a565b611dc2565b34801561093957600080fd5b506103f3611e65565b34801561094e57600080fd5b506103f360095481565b34801561096457600080fd5b5061044661097336600461475a565b60136020526000908152604090205460ff1681565b34801561099457600080fd5b5061088d611e75565b3480156109a957600080fd5b5061068a611ee2565b3480156109be57600080fd5b506105c86109cd366004614886565b611f38565b3480156109de57600080fd5b506103f360065481565b3480156109f457600080fd5b506103f360055481565b348015610a0a57600080fd5b506105c8610a193660046140a8565b611f43565b348015610a2a57600080fd5b50600d546104a59073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a5757600080fd5b50610446610a6636600461475a565b73ffffffffffffffffffffffffffffffffffffffff1660009081526013602052604090205460ff1690565b348015610a9d57600080fd5b506103f3610aac36600461475a565b611faf565b348015610abd57600080fd5b50610446610acc3660046140a8565b60009081526014602052604090205460ff1690565b348015610aed57600080fd5b506105c8611fe5565b348015610b0257600080fd5b5061046b61207b565b348015610b1757600080fd5b50610446610b263660046148bb565b612104565b348015610b3757600080fd5b506105c8610b463660046148f4565b612205565b348015610b5757600080fd5b506105c8610b6636600461475a565b6122ad565b348015610b7757600080fd5b506105c8610b8636600461495d565b6123a6565b348015610b9757600080fd5b506105c8610ba6366004614992565b61247c565b348015610bb757600080fd5b506103f3600a5481565b6105c8610bcf3660046149b5565b612521565b348015610be057600080fd5b506009546103f3565b348015610bf557600080fd5b506105c8610c0436600461475a565b61260e565b600073ffffffffffffffffffffffffffffffffffffffff8316610c995760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526020818152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020545b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001480610d6257507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c00000000000000000000000000000000000000000000000000000000145b80610cc957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610cc9565b600e8054610dbf906149ef565b80601f0160208091040260200160405190810160405280929190818152602001828054610deb906149ef565b8015610e385780601f10610e0d57610100808354040283529160200191610e38565b820191906000526020600020905b815481529060010190602001808311610e1b57829003601f168201915b505050505081565b6060600b610e4d836126bc565b604051602001610e5e929190614a59565b6040516020818303038152906040529050919050565b905090565b600080805b6005548111610eb457600081815260156020526040902054610ea09083614b66565b915080610eac81614b7e565b915050610e7e565b50919050565b60085460009074010000000000000000000000000000000000000000900460ff16610ee55750600090565b600554600090815260166020526040902054421015610f045750600090565b600554600090815260176020526040902054421115610f235750600090565b50600190565b60035473ffffffffffffffffffffffffffffffffffffffff163314610f905760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b6008805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff851633148061100357506110038533612104565b6110755760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f742060448201527f6f776e6572206e6f7220617070726f76656400000000000000000000000000006064820152608401610c90565b6110828585858585612819565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146110f05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b6040514790600090339083908381818185875af1925050503d8060008114611134576040519150601f19603f3d011682016040523d82523d6000602084013e611139565b606091505b505090508061114757600080fd5b81600760008282546111599190614b66565b90915550505050565b82518451146111b35760405162461bcd60e51b815260206004820152601660248201527f6172726179732073686f756c6420626520657175616c000000000000000000006044820152606401610c90565b81518451146112045760405162461bcd60e51b815260206004820152601860248201527f6172726179732073686f756c6420626520657175616c203200000000000000006044820152606401610c90565b60085473ffffffffffffffffffffffffffffffffffffffff1633146112915760405162461bcd60e51b815260206004820152602160248201527f6f6e6c79206d696e746572206163636f756e742063616e2063616c6c2074686960448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60005b84518110156110825760008582815181106112b1576112b1614bb7565b6020026020010151905060008483815181106112cf576112cf614bb7565b6020026020010151905060008684815181106112ed576112ed614bb7565b6020026020010151905061131d3384848489898151811061131057611310614bb7565b6020026020010151612b13565b505050808061132b90614b7e565b915050611294565b82518451146113845760405162461bcd60e51b815260206004820152601660248201527f6172726179732073686f756c6420626520657175616c000000000000000000006044820152606401610c90565b81518451146113d55760405162461bcd60e51b815260206004820152601860248201527f6172726179732073686f756c6420626520657175616c203200000000000000006044820152606401610c90565b60085473ffffffffffffffffffffffffffffffffffffffff1633146114625760405162461bcd60e51b815260206004820152602160248201527f6f6e6c79206d696e746572206163636f756e742063616e2063616c6c2074686960448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60085474010000000000000000000000000000000000000000900460ff1615156001146114d15760405162461bcd60e51b815260206004820152601060248201527f6d696e74696e672064697361626c6564000000000000000000000000000000006044820152606401610c90565b60005b84518110156110825761154d8582815181106114f2576114f2614bb7565b602002602001015184838151811061150c5761150c614bb7565b602002602001015186848151811061152657611526614bb7565b602002602001015185858151811061154057611540614bb7565b6020026020010151612d2b565b8061155781614b7e565b9150506114d4565b606081518351146115d85760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152608401610c90565b6000835167ffffffffffffffff8111156115f4576115f461421a565b60405190808252806020026020018201604052801561161d578160200160208202803683370190505b50905060005b84518110156116955761166885828151811061164157611641614bb7565b602002602001015185838151811061165b5761165b614bb7565b6020026020010151610c09565b82828151811061167a5761167a614bb7565b602090810291909101015261168e81614b7e565b9050611623565b509392505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146117045760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b805161171790600b90602084019061400f565b5050565b6060601180548060200260200160405190810160405280929190818152602001828054801561176957602002820191906000526020600020905b815481526020019060010190808311611755575b5050505050905090565b60005b82518110156118af5760085473ffffffffffffffffffffffffffffffffffffffff163314611842576117d08382815181106117b3576117b3614bb7565b602002602001015160009081526014602052604090205460ff1690565b6118425760405162461bcd60e51b815260206004820152602860248201527f746f6b656e206275726e696e6720666f722074686973206964206973206e6f7460448201527f20656e61626c65640000000000000000000000000000000000000000000000006064820152608401610c90565b81818151811061185457611854614bb7565b60200260200101516015600085848151811061187257611872614bb7565b6020026020010151815260200190815260200160002060008282546118979190614be6565b909155508190506118a781614b7e565b915050611776565b506118bb838383612e86565b505050565b6060600060055460016118d39190614b66565b67ffffffffffffffff8111156118eb576118eb61421a565b604051908082528060200260200182016040528015611914578160200160208202803683370190505b50905060005b600554811161195c5761192d8482610c09565b82828151811061193f5761193f614bb7565b60209081029190910101528061195481614b7e565b91505061191a565b5092915050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146119ca5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b6119d46000612f2c565b565b6060600060055460016119e99190614b66565b67ffffffffffffffff811115611a0157611a0161421a565b604051908082528060200260200182016040528015611a2a578160200160208202803683370190505b50905060005b600554811161195c576000611a458583610c09565b11828281518110611a5857611a58614bb7565b9115156020928302919091019091015280611a7281614b7e565b915050611a30565b60035473ffffffffffffffffffffffffffffffffffffffff163314611ae15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600555565b6060600f80548060200260200160405190810160405280929190818152602001828054801561176957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611b20575050505050905090565b60035473ffffffffffffffffffffffffffffffffffffffff163314611bbb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b805161171790600c90602084019061400f565b60085474010000000000000000000000000000000000000000900460ff16611c385760405162461bcd60e51b815260206004820152601060248201527f6d696e74696e672064697361626c6564000000000000000000000000000000006044820152606401610c90565b600554600090815260166020526040902054421015611c995760405162461bcd60e51b815260206004820152601460248201527f6d696e74696e67206e6f74206f70656e207965740000000000000000000000006044820152606401610c90565b6005546000908152601760205260409020544210611cf95760405162461bcd60e51b815260206004820152600e60248201527f6d696e74696e6720636c6f7365640000000000000000000000000000000000006044820152606401610c90565b600082118015611d0b5750600a548211155b611d575760405162461bcd60e51b815260206004820152601060248201527f496e76616c6964207175616e74697479000000000000000000000000000000006044820152606401610c90565b81600954611d659190614bfd565b341015611db45760405162461bcd60e51b815260206004820152600e60248201527f4e6f7420456e6f756768204554480000000000000000000000000000000000006044820152606401610c90565b6118bb836005548484612d2b565b60035473ffffffffffffffffffffffffffffffffffffffff163314611e295760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600083815260166020526040902082905580611e4f57611e4c8262015180614b66565b90505b6000928352601760205260409092209190915550565b600047600754610e749190614b66565b606060128054806020026020016040519081016040528092919081815260200182805480156117695760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611b20575050505050905090565b606060108054806020026020016040519081016040528092919081815260200182805480156117695760200282019190600052602060002090815481526020019060010190808311611755575050505050905090565b611717338383612fa3565b60035473ffffffffffffffffffffffffffffffffffffffff163314611faa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600a55565b600080805b600554811161195c57611fc78482610c09565b611fd19083614b66565b915080611fdd81614b7e565b915050611fb4565b60035473ffffffffffffffffffffffffffffffffffffffff16331461204c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b60405133904780156108fc02916000818181858888f19350505050158015612078573d6000803e3d6000fd5b50565b6060600c805461208a906149ef565b80601f01602080910402602001604051908101604052809291908181526020018280546120b6906149ef565b80156117695780601f106120d857610100808354040283529160200191611769565b820191906000526020600020905b8154815290600101906020018083116120e657509395945050505050565b600d546040517fc455279100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009281169190841690829063c455279190602401602060405180830381865afa15801561217c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a09190614c3a565b73ffffffffffffffffffffffffffffffffffffffff1614156121c6576001915050610cc9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526001602090815260408083209387168352929052205460ff165b949350505050565b73ffffffffffffffffffffffffffffffffffffffff851633148061222e575061222e8533612104565b6122a05760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f76656400000000000000000000000000000000000000000000006064820152608401610c90565b6110828585858585612b13565b60035473ffffffffffffffffffffffffffffffffffffffff1633146123145760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b73ffffffffffffffffffffffffffffffffffffffff811661239d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c90565b61207881612f2c565b60085473ffffffffffffffffffffffffffffffffffffffff1633146124495760008281526014602052604090205460ff166124495760405162461bcd60e51b815260206004820152602860248201527f746f6b656e206275726e696e6720666f722074686973206964206973206e6f7460448201527f20656e61626c65640000000000000000000000000000000000000000000000006064820152608401610c90565b6124548383836130dd565b60008281526015602052604081208054839290612472908490614be6565b9091555050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146124e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b60009182526014602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600061252d3385610c09565b1161257a5760405162461bcd60e51b815260206004820152601660248201527f4e4654206f776e657273686970207265717569726564000000000000000000006044820152606401610c90565b6005548311156125cc5760405162461bcd60e51b815260206004820152601760248201527f746f6b656e20696420646f6573206e6f742065786973740000000000000000006044820152606401610c90565b7fc61f2c659edbf24c83f2f878b28ccaf66c4c57d5f9ca1fe88680910673e7af6e833484846040516126019493929190614c57565b60405180910390a1505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146126755760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6060816126fc57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612726578061271081614b7e565b915061271f9050600a83614c86565b9150612700565b60008167ffffffffffffffff8111156127415761274161421a565b6040519080825280601f01601f19166020018201604052801561276b576020820181803683370190505b509050815b851561281057612781600182614be6565b90506000612790600a88614c86565b61279b90600a614bfd565b6127a59088614be6565b6127b0906030614cc1565b905060008160f81b9050808484815181106127cd576127cd614bb7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612807600a89614c86565b97505050612770565b50949350505050565b81518351146128905760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152608401610c90565b73ffffffffffffffffffffffffffffffffffffffff84166129195760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610c90565b3360005b8451811015612a7057600085828151811061293a5761293a614bb7565b60200260200101519050600085838151811061295857612958614bb7565b6020908102919091018101516000848152808352604080822073ffffffffffffffffffffffffffffffffffffffff8e168352909352919091205490915081811015612a0b5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152608401610c90565b60008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8e8116855292528083208585039055908b16825281208054849290612a55908490614b66565b9250508190555050505080612a6990614b7e565b905061291d565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612ae7929190614ce6565b60405180910390a4612afd818787878787613183565b612b0b818787878787613401565b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416612b9c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610c90565b336000612ba885613647565b90506000612bb585613647565b905060008681526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8c16845290915290205485811015612c5b5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152608401610c90565b60008781526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8d8116855292528083208985039055908a16825281208054889290612ca5908490614b66565b9091555050604080518881526020810188905273ffffffffffffffffffffffffffffffffffffffff808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4612d12848a8a86868a613183565b612d20848a8a8a8a8a613692565b505050505050505050565b600554831115612d7d5760405162461bcd60e51b815260206004820152601760248201527f746f6b656e20696420646f6573206e6f742065786973740000000000000000006044820152606401610c90565b612d8984848484613825565b60008381526015602052604081208054849290612da7908490614b66565b909155505073ffffffffffffffffffffffffffffffffffffffff841660009081526013602052604090205460ff16612e80576012805460018082019092557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8716908117909155600090815260136020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316331480612eaf5750612eaf8333612104565b612f215760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f76656400000000000000000000000000000000000000000000006064820152608401610c90565b6118bb838383613982565b6003805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156130455760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152608401610c90565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831633148061310657506131068333612104565b6131785760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f76656400000000000000000000000000000000000000000000006064820152608401610c90565b6118bb838383613c65565b73ffffffffffffffffffffffffffffffffffffffff8416158015906131ce575073ffffffffffffffffffffffffffffffffffffffff841660009081526013602052604090205460ff16155b1561327a576012805460018082019092557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8716908117909155600090815260136020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790555b73ffffffffffffffffffffffffffffffffffffffff84166133c35760005b82518110156133c15760008482815181106132b5576132b5614bb7565b6020026020010151905060008483815181106132d3576132d3614bb7565b6020908102919091010151600f805460018082019092557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8c16179055601080548083019091557f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67201939093556011805493840181556000527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c689092019190915550806133b981614b7e565b915050613298565b505b73ffffffffffffffffffffffffffffffffffffffff8516158015906133ee57506133ec85611faf565b155b156133fc576133fc85613e45565b612b0b565b73ffffffffffffffffffffffffffffffffffffffff84163b15612b0b576040517fbc197c8100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063bc197c81906134789089908990889088908890600401614d0b565b6020604051808303816000875af19250505080156134d1575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526134ce91810190614d76565b60015b613587576134dd614d93565b806308c379a0141561351757506134f2614daf565b806134fd5750613519565b8060405162461bcd60e51b8152600401610c9091906141d7565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608401610c90565b7fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c81000000000000000000000000000000000000000000000000000000001461363e5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608401610c90565b50505050505050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061368157613681614bb7565b602090810291909101015292915050565b73ffffffffffffffffffffffffffffffffffffffff84163b15612b0b576040517ff23a6e6100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063f23a6e61906137099089908990889088908890600401614e57565b6020604051808303816000875af1925050508015613762575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261375f91810190614d76565b60015b61376e576134dd614d93565b7fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e61000000000000000000000000000000000000000000000000000000001461363e5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608401610c90565b73ffffffffffffffffffffffffffffffffffffffff84166138ae5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c90565b3360006138ba85613647565b905060006138c785613647565b905060008681526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8b16845290915281208054879290613906908490614b66565b9091555050604080518781526020810187905273ffffffffffffffffffffffffffffffffffffffff808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461397383600089858589613183565b61363e83600089898989613692565b73ffffffffffffffffffffffffffffffffffffffff8316613a0b5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610c90565b8051825114613a825760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152608401610c90565b604080516020810190915260009081905233905b8351811015613bc7576000848281518110613ab357613ab3614bb7565b602002602001015190506000848381518110613ad157613ad1614bb7565b6020908102919091018101516000848152808352604080822073ffffffffffffffffffffffffffffffffffffffff8c168352909352919091205490915081811015613b835760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e6365000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60009283526020838152604080852073ffffffffffffffffffffffffffffffffffffffff8b1686529091529092209103905580613bbf81614b7e565b915050613a96565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051613c3f929190614ce6565b60405180910390a4612e8081856000868660405180602001604052806000815250613183565b73ffffffffffffffffffffffffffffffffffffffff8316613cee5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610c90565b336000613cfa84613647565b90506000613d0784613647565b604080516020808201835260009182905288825281815282822073ffffffffffffffffffffffffffffffffffffffff8b1683529052205490915084811015613db65760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e6365000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60008681526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461363e84886000868660405180602001604052806000815250613183565b60005b601254811015611717578173ffffffffffffffffffffffffffffffffffffffff1660128281548110613e7c57613e7c614bb7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415613ffd5760128054613eb490600190614be6565b81548110613ec457613ec4614bb7565b6000918252602090912001546012805473ffffffffffffffffffffffffffffffffffffffff9092169183908110613efd57613efd614bb7565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506012805480613f5657613f56614ea7565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff84168252601390526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555050565b8061400781614b7e565b915050613e48565b82805461401b906149ef565b90600052602060002090601f01602090048101928261403d5760008555614083565b82601f1061405657805160ff1916838001178555614083565b82800160010185558215614083579182015b82811115614083578251825591602001919060010190614068565b5061408f929150614093565b5090565b5b8082111561408f5760008155600101614094565b6000602082840312156140ba57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461207857600080fd5b600080604083850312156140f657600080fd5b8235614101816140c1565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461207857600080fd5b60006020828403121561414f57600080fd5b813561415a8161410f565b9392505050565b60005b8381101561417c578181015183820152602001614164565b83811115612e805750506000910152565b600081518084526141a5816020860160208601614161565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061415a602083018461418d565b803580151581146141fa57600080fd5b919050565b60006020828403121561421157600080fd5b61415a826141ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff8211171561428d5761428d61421a565b6040525050565b600067ffffffffffffffff8211156142ae576142ae61421a565b5060051b60200190565b600082601f8301126142c957600080fd5b813560206142d682614294565b6040516142e38282614249565b83815260059390931b850182019282810191508684111561430357600080fd5b8286015b8481101561431e5780358352918301918301614307565b509695505050505050565b600082601f83011261433a57600080fd5b813567ffffffffffffffff8111156143545761435461421a565b60405161438960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160182614249565b81815284602083860101111561439e57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156143d357600080fd5b85356143de816140c1565b945060208601356143ee816140c1565b9350604086013567ffffffffffffffff8082111561440b57600080fd5b61441789838a016142b8565b9450606088013591508082111561442d57600080fd5b61443989838a016142b8565b9350608088013591508082111561444f57600080fd5b5061445c88828901614329565b9150509295509295909350565b600082601f83011261447a57600080fd5b8135602061448782614294565b6040516144948282614249565b83815260059390931b85018201928281019150868411156144b457600080fd5b8286015b8481101561431e5780356144cb816140c1565b83529183019183016144b8565b600080600080608085870312156144ee57600080fd5b843567ffffffffffffffff8082111561450657600080fd5b61451288838901614469565b955060209150818701358181111561452957600080fd5b61453589828a016142b8565b95505060408701358181111561454a57600080fd5b61455689828a016142b8565b94505060608701358181111561456b57600080fd5b8701601f8101891361457c57600080fd5b803561458781614294565b6040516145948282614249565b82815260059290921b830185019185810191508b8311156145b457600080fd5b8584015b838110156145ec578035868111156145d05760008081fd5b6145de8e8983890101614329565b8452509186019186016145b8565b50989b979a50959850505050505050565b6000806040838503121561461057600080fd5b823567ffffffffffffffff8082111561462857600080fd5b61463486838701614469565b9350602085013591508082111561464a57600080fd5b50614657858286016142b8565b9150509250929050565b600081518084526020808501945080840160005b8381101561469157815187529582019590820190600101614675565b509495945050505050565b60208152600061415a6020830184614661565b6000602082840312156146c157600080fd5b813567ffffffffffffffff8111156146d857600080fd5b6121fd84828501614329565b6000806000606084860312156146f957600080fd5b8335614704816140c1565b9250602084013567ffffffffffffffff8082111561472157600080fd5b61472d878388016142b8565b9350604086013591508082111561474357600080fd5b50614750868287016142b8565b9150509250925092565b60006020828403121561476c57600080fd5b813561415a816140c1565b6020808252825182820181905260009190848201906040850190845b818110156147b1578351151583529284019291840191600101614793565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147b157835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016147d9565b60008060006060848603121561482057600080fd5b833561482b816140c1565b925060208401359150604084013567ffffffffffffffff81111561484e57600080fd5b61475086828701614329565b60008060006060848603121561486f57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561489957600080fd5b82356148a4816140c1565b91506148b2602084016141ea565b90509250929050565b600080604083850312156148ce57600080fd5b82356148d9816140c1565b915060208301356148e9816140c1565b809150509250929050565b600080600080600060a0868803121561490c57600080fd5b8535614917816140c1565b94506020860135614927816140c1565b93506040860135925060608601359150608086013567ffffffffffffffff81111561495157600080fd5b61445c88828901614329565b60008060006060848603121561497257600080fd5b833561497d816140c1565b95602085013595506040909401359392505050565b600080604083850312156149a557600080fd5b823591506148b2602084016141ea565b6000806000606084860312156149ca57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561484e57600080fd5b600181811c90821680614a0357607f821691505b60208210811415610eb4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008151614a4f818560208601614161565b9290920192915050565b600080845481600182811c915080831680614a7557607f831692505b6020808410821415614aae577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015614ac25760018114614af157614b1e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650614b1e565b60008b81526020902060005b86811015614b165781548b820152908501908301614afd565b505084890196505b505050505050614b2e8185614a3d565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115614b7957614b79614b37565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614bb057614bb0614b37565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015614bf857614bf8614b37565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614c3557614c35614b37565b500290565b600060208284031215614c4c57600080fd5b815161415a816140c1565b848152836020820152826040820152608060608201526000614c7c608083018461418d565b9695505050505050565b600082614cbc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060ff821660ff84168060ff03821115614cde57614cde614b37565b019392505050565b604081526000614cf96040830185614661565b8281036020840152614b2e8185614661565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152614d4460a0830186614661565b8281036060840152614d568186614661565b90508281036080840152614d6a818561418d565b98975050505050505050565b600060208284031215614d8857600080fd5b815161415a8161410f565b600060033d1115614dac5760046000803e5060005160e01c5b90565b600060443d1015614dbd5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715614e0b57505050505090565b8285019150815181811115614e235750505050505090565b843d8701016020828501011115614e3d5750505050505090565b614e4c60208286010187614249565b509095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015283606083015260a06080830152614e9c60a083018461418d565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212206045803d74f9576bb8ac4fe6434bb9a221a55ec859d83abe9cbbf1a8b776646064736f6c634300080a003368747470733a2f2f686f7573656f6666697273742e636f6d3a313333352f747269627574652f6f70656e7365612f

Deployed Bytecode

0x6080604052600436106103c15760003560e01c80638329de2f116101f2578063c87b56dd1161010d578063f242432a116100a0578063f968adbe1161006f578063f968adbe14610bab578063fafcbca414610bc1578063fb107a4f14610bd4578063fca3b5aa14610be957600080fd5b8063f242432a14610b2b578063f2fde38b14610b4b578063f5298aca14610b6b578063f7ed5a7814610b8b57600080fd5b8063d3de7933116100dc578063d3de793314610ab1578063e086e5ec14610ae1578063e8a3d48514610af6578063e985e9c514610b0b57600080fd5b8063c87b56dd146104ca578063cd7c032614610a1e578063cea65e9714610a4b578063d3d3819314610a9157600080fd5b8063a035b1fe11610185578063a22cb46511610154578063a22cb465146109b2578063a2309ff8146109d2578063bb62115e146109e8578063c6f6f216146109fe57600080fd5b8063a035b1fe14610942578063a0c09cb714610958578063a0e67e2b14610988578063a137be771461099d57600080fd5b8063938e3d7b116101c1578063938e3d7b146108da57806394d008ef146108fa5780639bf24b0c1461090d5780639f5502931461092d57600080fd5b80638329de2f1461085857806386fe8b431461087857806389404a791461089a5780638da5cb5b146108af57600080fd5b806341f43434116102e257806362eb575e116102755780636c1d2948116102445780636c1d2948146107c9578063715018a6146107e95780638022e3cd146107fe578063816f21b91461082b57600080fd5b806362eb575e14610722578063665ecccf1461074f5780636afeb9391461077c5780636b20c454146107a957600080fd5b806355c7ba14116102b157806355c7ba141461069757806355f804b3146106c9578063581e5777146106e95780635f7033e5146106fe57600080fd5b806341f43434146106125780634824a26f146106345780634b319713146106545780634e1273f41461066a57600080fd5b8063141fcdae1161035a57806321775c921161032957806321775c92146105a85780632eb2c2d6146105ca5780633ccfd60b146105ea57806340b4dd87146105f257600080fd5b8063141fcdae1461052a57806318160ddd1461054e5780631a206910146105635780631f2818ad1461057857600080fd5b8063075461721161039657806307546172146104785780630e89341c146104ca57806311d38c5d146104ea57806312b583491461051757600080fd5b8062d1bb01146103c6578062fdd58e1461040657806301ffc9a71461042657806306fdde0314610456575b600080fd5b3480156103d257600080fd5b506103f36103e13660046140a8565b60009081526016602052604090205490565b6040519081526020015b60405180910390f35b34801561041257600080fd5b506103f36104213660046140e3565b610c09565b34801561043257600080fd5b5061044661044136600461413d565b610ccf565b60405190151581526020016103fd565b34801561046257600080fd5b5061046b610db2565b6040516103fd91906141d7565b34801561048457600080fd5b506008546104a59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103fd565b3480156104d657600080fd5b5061046b6104e53660046140a8565b610e40565b3480156104f657600080fd5b506103f36105053660046140a8565b60009081526017602052604090205490565b34801561052357600080fd5b50476103f3565b34801561053657600080fd5b506005546000908152601760205260409020546103f3565b34801561055a57600080fd5b506103f3610e79565b34801561056f57600080fd5b50610446610eba565b34801561058457600080fd5b506104466105933660046140a8565b60146020526000908152604090205460ff1681565b3480156105b457600080fd5b506105c86105c33660046141ff565b610f29565b005b3480156105d657600080fd5b506105c86105e53660046143bb565b610fda565b6105c8611089565b3480156105fe57600080fd5b506105c861060d3660046144d8565b611162565b34801561061e57600080fd5b506104a56daaeb6d7670e522a718067333cd4e81565b34801561064057600080fd5b506105c861064f3660046144d8565b611333565b34801561066057600080fd5b506103f360075481565b34801561067657600080fd5b5061068a6106853660046145fd565b61155f565b6040516103fd919061469c565b3480156106a357600080fd5b506008546104469074010000000000000000000000000000000000000000900460ff1681565b3480156106d557600080fd5b506105c86106e43660046146af565b61169d565b3480156106f557600080fd5b5061068a61171b565b34801561070a57600080fd5b506005546000908152601660205260409020546103f3565b34801561072e57600080fd5b506103f361073d3660046140a8565b60166020526000908152604090205481565b34801561075b57600080fd5b506103f361076a3660046140a8565b60156020526000908152604090205481565b34801561078857600080fd5b506103f36107973660046140a8565b60176020526000908152604090205481565b3480156107b557600080fd5b506105c86107c43660046146e4565b611773565b3480156107d557600080fd5b5061068a6107e436600461475a565b6118c0565b3480156107f557600080fd5b506105c8611963565b34801561080a57600080fd5b5061081e61081936600461475a565b6119d6565b6040516103fd9190614777565b34801561083757600080fd5b506103f36108463660046140a8565b60009081526015602052604090205490565b34801561086457600080fd5b506105c86108733660046140a8565b611a7a565b34801561088457600080fd5b5061088d611ae6565b6040516103fd91906147bd565b3480156108a657600080fd5b506007546103f3565b3480156108bb57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166104a5565b3480156108e657600080fd5b506105c86108f53660046146af565b611b54565b6105c861090836600461480b565b611bce565b34801561091957600080fd5b506105c861092836600461485a565b611dc2565b34801561093957600080fd5b506103f3611e65565b34801561094e57600080fd5b506103f360095481565b34801561096457600080fd5b5061044661097336600461475a565b60136020526000908152604090205460ff1681565b34801561099457600080fd5b5061088d611e75565b3480156109a957600080fd5b5061068a611ee2565b3480156109be57600080fd5b506105c86109cd366004614886565b611f38565b3480156109de57600080fd5b506103f360065481565b3480156109f457600080fd5b506103f360055481565b348015610a0a57600080fd5b506105c8610a193660046140a8565b611f43565b348015610a2a57600080fd5b50600d546104a59073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a5757600080fd5b50610446610a6636600461475a565b73ffffffffffffffffffffffffffffffffffffffff1660009081526013602052604090205460ff1690565b348015610a9d57600080fd5b506103f3610aac36600461475a565b611faf565b348015610abd57600080fd5b50610446610acc3660046140a8565b60009081526014602052604090205460ff1690565b348015610aed57600080fd5b506105c8611fe5565b348015610b0257600080fd5b5061046b61207b565b348015610b1757600080fd5b50610446610b263660046148bb565b612104565b348015610b3757600080fd5b506105c8610b463660046148f4565b612205565b348015610b5757600080fd5b506105c8610b6636600461475a565b6122ad565b348015610b7757600080fd5b506105c8610b8636600461495d565b6123a6565b348015610b9757600080fd5b506105c8610ba6366004614992565b61247c565b348015610bb757600080fd5b506103f3600a5481565b6105c8610bcf3660046149b5565b612521565b348015610be057600080fd5b506009546103f3565b348015610bf557600080fd5b506105c8610c0436600461475a565b61260e565b600073ffffffffffffffffffffffffffffffffffffffff8316610c995760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526020818152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020545b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001480610d6257507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c00000000000000000000000000000000000000000000000000000000145b80610cc957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610cc9565b600e8054610dbf906149ef565b80601f0160208091040260200160405190810160405280929190818152602001828054610deb906149ef565b8015610e385780601f10610e0d57610100808354040283529160200191610e38565b820191906000526020600020905b815481529060010190602001808311610e1b57829003601f168201915b505050505081565b6060600b610e4d836126bc565b604051602001610e5e929190614a59565b6040516020818303038152906040529050919050565b905090565b600080805b6005548111610eb457600081815260156020526040902054610ea09083614b66565b915080610eac81614b7e565b915050610e7e565b50919050565b60085460009074010000000000000000000000000000000000000000900460ff16610ee55750600090565b600554600090815260166020526040902054421015610f045750600090565b600554600090815260176020526040902054421115610f235750600090565b50600190565b60035473ffffffffffffffffffffffffffffffffffffffff163314610f905760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b6008805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff851633148061100357506110038533612104565b6110755760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f742060448201527f6f776e6572206e6f7220617070726f76656400000000000000000000000000006064820152608401610c90565b6110828585858585612819565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146110f05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b6040514790600090339083908381818185875af1925050503d8060008114611134576040519150601f19603f3d011682016040523d82523d6000602084013e611139565b606091505b505090508061114757600080fd5b81600760008282546111599190614b66565b90915550505050565b82518451146111b35760405162461bcd60e51b815260206004820152601660248201527f6172726179732073686f756c6420626520657175616c000000000000000000006044820152606401610c90565b81518451146112045760405162461bcd60e51b815260206004820152601860248201527f6172726179732073686f756c6420626520657175616c203200000000000000006044820152606401610c90565b60085473ffffffffffffffffffffffffffffffffffffffff1633146112915760405162461bcd60e51b815260206004820152602160248201527f6f6e6c79206d696e746572206163636f756e742063616e2063616c6c2074686960448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60005b84518110156110825760008582815181106112b1576112b1614bb7565b6020026020010151905060008483815181106112cf576112cf614bb7565b6020026020010151905060008684815181106112ed576112ed614bb7565b6020026020010151905061131d3384848489898151811061131057611310614bb7565b6020026020010151612b13565b505050808061132b90614b7e565b915050611294565b82518451146113845760405162461bcd60e51b815260206004820152601660248201527f6172726179732073686f756c6420626520657175616c000000000000000000006044820152606401610c90565b81518451146113d55760405162461bcd60e51b815260206004820152601860248201527f6172726179732073686f756c6420626520657175616c203200000000000000006044820152606401610c90565b60085473ffffffffffffffffffffffffffffffffffffffff1633146114625760405162461bcd60e51b815260206004820152602160248201527f6f6e6c79206d696e746572206163636f756e742063616e2063616c6c2074686960448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60085474010000000000000000000000000000000000000000900460ff1615156001146114d15760405162461bcd60e51b815260206004820152601060248201527f6d696e74696e672064697361626c6564000000000000000000000000000000006044820152606401610c90565b60005b84518110156110825761154d8582815181106114f2576114f2614bb7565b602002602001015184838151811061150c5761150c614bb7565b602002602001015186848151811061152657611526614bb7565b602002602001015185858151811061154057611540614bb7565b6020026020010151612d2b565b8061155781614b7e565b9150506114d4565b606081518351146115d85760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152608401610c90565b6000835167ffffffffffffffff8111156115f4576115f461421a565b60405190808252806020026020018201604052801561161d578160200160208202803683370190505b50905060005b84518110156116955761166885828151811061164157611641614bb7565b602002602001015185838151811061165b5761165b614bb7565b6020026020010151610c09565b82828151811061167a5761167a614bb7565b602090810291909101015261168e81614b7e565b9050611623565b509392505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146117045760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b805161171790600b90602084019061400f565b5050565b6060601180548060200260200160405190810160405280929190818152602001828054801561176957602002820191906000526020600020905b815481526020019060010190808311611755575b5050505050905090565b60005b82518110156118af5760085473ffffffffffffffffffffffffffffffffffffffff163314611842576117d08382815181106117b3576117b3614bb7565b602002602001015160009081526014602052604090205460ff1690565b6118425760405162461bcd60e51b815260206004820152602860248201527f746f6b656e206275726e696e6720666f722074686973206964206973206e6f7460448201527f20656e61626c65640000000000000000000000000000000000000000000000006064820152608401610c90565b81818151811061185457611854614bb7565b60200260200101516015600085848151811061187257611872614bb7565b6020026020010151815260200190815260200160002060008282546118979190614be6565b909155508190506118a781614b7e565b915050611776565b506118bb838383612e86565b505050565b6060600060055460016118d39190614b66565b67ffffffffffffffff8111156118eb576118eb61421a565b604051908082528060200260200182016040528015611914578160200160208202803683370190505b50905060005b600554811161195c5761192d8482610c09565b82828151811061193f5761193f614bb7565b60209081029190910101528061195481614b7e565b91505061191a565b5092915050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146119ca5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b6119d46000612f2c565b565b6060600060055460016119e99190614b66565b67ffffffffffffffff811115611a0157611a0161421a565b604051908082528060200260200182016040528015611a2a578160200160208202803683370190505b50905060005b600554811161195c576000611a458583610c09565b11828281518110611a5857611a58614bb7565b9115156020928302919091019091015280611a7281614b7e565b915050611a30565b60035473ffffffffffffffffffffffffffffffffffffffff163314611ae15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600555565b6060600f80548060200260200160405190810160405280929190818152602001828054801561176957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611b20575050505050905090565b60035473ffffffffffffffffffffffffffffffffffffffff163314611bbb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b805161171790600c90602084019061400f565b60085474010000000000000000000000000000000000000000900460ff16611c385760405162461bcd60e51b815260206004820152601060248201527f6d696e74696e672064697361626c6564000000000000000000000000000000006044820152606401610c90565b600554600090815260166020526040902054421015611c995760405162461bcd60e51b815260206004820152601460248201527f6d696e74696e67206e6f74206f70656e207965740000000000000000000000006044820152606401610c90565b6005546000908152601760205260409020544210611cf95760405162461bcd60e51b815260206004820152600e60248201527f6d696e74696e6720636c6f7365640000000000000000000000000000000000006044820152606401610c90565b600082118015611d0b5750600a548211155b611d575760405162461bcd60e51b815260206004820152601060248201527f496e76616c6964207175616e74697479000000000000000000000000000000006044820152606401610c90565b81600954611d659190614bfd565b341015611db45760405162461bcd60e51b815260206004820152600e60248201527f4e6f7420456e6f756768204554480000000000000000000000000000000000006044820152606401610c90565b6118bb836005548484612d2b565b60035473ffffffffffffffffffffffffffffffffffffffff163314611e295760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600083815260166020526040902082905580611e4f57611e4c8262015180614b66565b90505b6000928352601760205260409092209190915550565b600047600754610e749190614b66565b606060128054806020026020016040519081016040528092919081815260200182805480156117695760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611b20575050505050905090565b606060108054806020026020016040519081016040528092919081815260200182805480156117695760200282019190600052602060002090815481526020019060010190808311611755575050505050905090565b611717338383612fa3565b60035473ffffffffffffffffffffffffffffffffffffffff163314611faa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600a55565b600080805b600554811161195c57611fc78482610c09565b611fd19083614b66565b915080611fdd81614b7e565b915050611fb4565b60035473ffffffffffffffffffffffffffffffffffffffff16331461204c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b60405133904780156108fc02916000818181858888f19350505050158015612078573d6000803e3d6000fd5b50565b6060600c805461208a906149ef565b80601f01602080910402602001604051908101604052809291908181526020018280546120b6906149ef565b80156117695780601f106120d857610100808354040283529160200191611769565b820191906000526020600020905b8154815290600101906020018083116120e657509395945050505050565b600d546040517fc455279100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009281169190841690829063c455279190602401602060405180830381865afa15801561217c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a09190614c3a565b73ffffffffffffffffffffffffffffffffffffffff1614156121c6576001915050610cc9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526001602090815260408083209387168352929052205460ff165b949350505050565b73ffffffffffffffffffffffffffffffffffffffff851633148061222e575061222e8533612104565b6122a05760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f76656400000000000000000000000000000000000000000000006064820152608401610c90565b6110828585858585612b13565b60035473ffffffffffffffffffffffffffffffffffffffff1633146123145760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b73ffffffffffffffffffffffffffffffffffffffff811661239d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c90565b61207881612f2c565b60085473ffffffffffffffffffffffffffffffffffffffff1633146124495760008281526014602052604090205460ff166124495760405162461bcd60e51b815260206004820152602860248201527f746f6b656e206275726e696e6720666f722074686973206964206973206e6f7460448201527f20656e61626c65640000000000000000000000000000000000000000000000006064820152608401610c90565b6124548383836130dd565b60008281526015602052604081208054839290612472908490614be6565b9091555050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146124e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b60009182526014602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600061252d3385610c09565b1161257a5760405162461bcd60e51b815260206004820152601660248201527f4e4654206f776e657273686970207265717569726564000000000000000000006044820152606401610c90565b6005548311156125cc5760405162461bcd60e51b815260206004820152601760248201527f746f6b656e20696420646f6573206e6f742065786973740000000000000000006044820152606401610c90565b7fc61f2c659edbf24c83f2f878b28ccaf66c4c57d5f9ca1fe88680910673e7af6e833484846040516126019493929190614c57565b60405180910390a1505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146126755760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c90565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6060816126fc57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612726578061271081614b7e565b915061271f9050600a83614c86565b9150612700565b60008167ffffffffffffffff8111156127415761274161421a565b6040519080825280601f01601f19166020018201604052801561276b576020820181803683370190505b509050815b851561281057612781600182614be6565b90506000612790600a88614c86565b61279b90600a614bfd565b6127a59088614be6565b6127b0906030614cc1565b905060008160f81b9050808484815181106127cd576127cd614bb7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612807600a89614c86565b97505050612770565b50949350505050565b81518351146128905760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152608401610c90565b73ffffffffffffffffffffffffffffffffffffffff84166129195760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610c90565b3360005b8451811015612a7057600085828151811061293a5761293a614bb7565b60200260200101519050600085838151811061295857612958614bb7565b6020908102919091018101516000848152808352604080822073ffffffffffffffffffffffffffffffffffffffff8e168352909352919091205490915081811015612a0b5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152608401610c90565b60008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8e8116855292528083208585039055908b16825281208054849290612a55908490614b66565b9250508190555050505080612a6990614b7e565b905061291d565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612ae7929190614ce6565b60405180910390a4612afd818787878787613183565b612b0b818787878787613401565b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416612b9c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610c90565b336000612ba885613647565b90506000612bb585613647565b905060008681526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8c16845290915290205485811015612c5b5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152608401610c90565b60008781526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8d8116855292528083208985039055908a16825281208054889290612ca5908490614b66565b9091555050604080518881526020810188905273ffffffffffffffffffffffffffffffffffffffff808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4612d12848a8a86868a613183565b612d20848a8a8a8a8a613692565b505050505050505050565b600554831115612d7d5760405162461bcd60e51b815260206004820152601760248201527f746f6b656e20696420646f6573206e6f742065786973740000000000000000006044820152606401610c90565b612d8984848484613825565b60008381526015602052604081208054849290612da7908490614b66565b909155505073ffffffffffffffffffffffffffffffffffffffff841660009081526013602052604090205460ff16612e80576012805460018082019092557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8716908117909155600090815260136020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316331480612eaf5750612eaf8333612104565b612f215760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f76656400000000000000000000000000000000000000000000006064820152608401610c90565b6118bb838383613982565b6003805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156130455760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152608401610c90565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831633148061310657506131068333612104565b6131785760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f76656400000000000000000000000000000000000000000000006064820152608401610c90565b6118bb838383613c65565b73ffffffffffffffffffffffffffffffffffffffff8416158015906131ce575073ffffffffffffffffffffffffffffffffffffffff841660009081526013602052604090205460ff16155b1561327a576012805460018082019092557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8716908117909155600090815260136020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790555b73ffffffffffffffffffffffffffffffffffffffff84166133c35760005b82518110156133c15760008482815181106132b5576132b5614bb7565b6020026020010151905060008483815181106132d3576132d3614bb7565b6020908102919091010151600f805460018082019092557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8c16179055601080548083019091557f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67201939093556011805493840181556000527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c689092019190915550806133b981614b7e565b915050613298565b505b73ffffffffffffffffffffffffffffffffffffffff8516158015906133ee57506133ec85611faf565b155b156133fc576133fc85613e45565b612b0b565b73ffffffffffffffffffffffffffffffffffffffff84163b15612b0b576040517fbc197c8100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063bc197c81906134789089908990889088908890600401614d0b565b6020604051808303816000875af19250505080156134d1575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526134ce91810190614d76565b60015b613587576134dd614d93565b806308c379a0141561351757506134f2614daf565b806134fd5750613519565b8060405162461bcd60e51b8152600401610c9091906141d7565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608401610c90565b7fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c81000000000000000000000000000000000000000000000000000000001461363e5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608401610c90565b50505050505050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061368157613681614bb7565b602090810291909101015292915050565b73ffffffffffffffffffffffffffffffffffffffff84163b15612b0b576040517ff23a6e6100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063f23a6e61906137099089908990889088908890600401614e57565b6020604051808303816000875af1925050508015613762575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261375f91810190614d76565b60015b61376e576134dd614d93565b7fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e61000000000000000000000000000000000000000000000000000000001461363e5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608401610c90565b73ffffffffffffffffffffffffffffffffffffffff84166138ae5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c90565b3360006138ba85613647565b905060006138c785613647565b905060008681526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8b16845290915281208054879290613906908490614b66565b9091555050604080518781526020810187905273ffffffffffffffffffffffffffffffffffffffff808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461397383600089858589613183565b61363e83600089898989613692565b73ffffffffffffffffffffffffffffffffffffffff8316613a0b5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610c90565b8051825114613a825760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152608401610c90565b604080516020810190915260009081905233905b8351811015613bc7576000848281518110613ab357613ab3614bb7565b602002602001015190506000848381518110613ad157613ad1614bb7565b6020908102919091018101516000848152808352604080822073ffffffffffffffffffffffffffffffffffffffff8c168352909352919091205490915081811015613b835760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e6365000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60009283526020838152604080852073ffffffffffffffffffffffffffffffffffffffff8b1686529091529092209103905580613bbf81614b7e565b915050613a96565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051613c3f929190614ce6565b60405180910390a4612e8081856000868660405180602001604052806000815250613183565b73ffffffffffffffffffffffffffffffffffffffff8316613cee5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610c90565b336000613cfa84613647565b90506000613d0784613647565b604080516020808201835260009182905288825281815282822073ffffffffffffffffffffffffffffffffffffffff8b1683529052205490915084811015613db65760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e6365000000000000000000000000000000000000000000000000000000006064820152608401610c90565b60008681526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461363e84886000868660405180602001604052806000815250613183565b60005b601254811015611717578173ffffffffffffffffffffffffffffffffffffffff1660128281548110613e7c57613e7c614bb7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415613ffd5760128054613eb490600190614be6565b81548110613ec457613ec4614bb7565b6000918252602090912001546012805473ffffffffffffffffffffffffffffffffffffffff9092169183908110613efd57613efd614bb7565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506012805480613f5657613f56614ea7565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff84168252601390526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555050565b8061400781614b7e565b915050613e48565b82805461401b906149ef565b90600052602060002090601f01602090048101928261403d5760008555614083565b82601f1061405657805160ff1916838001178555614083565b82800160010185558215614083579182015b82811115614083578251825591602001919060010190614068565b5061408f929150614093565b5090565b5b8082111561408f5760008155600101614094565b6000602082840312156140ba57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461207857600080fd5b600080604083850312156140f657600080fd5b8235614101816140c1565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461207857600080fd5b60006020828403121561414f57600080fd5b813561415a8161410f565b9392505050565b60005b8381101561417c578181015183820152602001614164565b83811115612e805750506000910152565b600081518084526141a5816020860160208601614161565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061415a602083018461418d565b803580151581146141fa57600080fd5b919050565b60006020828403121561421157600080fd5b61415a826141ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff8211171561428d5761428d61421a565b6040525050565b600067ffffffffffffffff8211156142ae576142ae61421a565b5060051b60200190565b600082601f8301126142c957600080fd5b813560206142d682614294565b6040516142e38282614249565b83815260059390931b850182019282810191508684111561430357600080fd5b8286015b8481101561431e5780358352918301918301614307565b509695505050505050565b600082601f83011261433a57600080fd5b813567ffffffffffffffff8111156143545761435461421a565b60405161438960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160182614249565b81815284602083860101111561439e57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156143d357600080fd5b85356143de816140c1565b945060208601356143ee816140c1565b9350604086013567ffffffffffffffff8082111561440b57600080fd5b61441789838a016142b8565b9450606088013591508082111561442d57600080fd5b61443989838a016142b8565b9350608088013591508082111561444f57600080fd5b5061445c88828901614329565b9150509295509295909350565b600082601f83011261447a57600080fd5b8135602061448782614294565b6040516144948282614249565b83815260059390931b85018201928281019150868411156144b457600080fd5b8286015b8481101561431e5780356144cb816140c1565b83529183019183016144b8565b600080600080608085870312156144ee57600080fd5b843567ffffffffffffffff8082111561450657600080fd5b61451288838901614469565b955060209150818701358181111561452957600080fd5b61453589828a016142b8565b95505060408701358181111561454a57600080fd5b61455689828a016142b8565b94505060608701358181111561456b57600080fd5b8701601f8101891361457c57600080fd5b803561458781614294565b6040516145948282614249565b82815260059290921b830185019185810191508b8311156145b457600080fd5b8584015b838110156145ec578035868111156145d05760008081fd5b6145de8e8983890101614329565b8452509186019186016145b8565b50989b979a50959850505050505050565b6000806040838503121561461057600080fd5b823567ffffffffffffffff8082111561462857600080fd5b61463486838701614469565b9350602085013591508082111561464a57600080fd5b50614657858286016142b8565b9150509250929050565b600081518084526020808501945080840160005b8381101561469157815187529582019590820190600101614675565b509495945050505050565b60208152600061415a6020830184614661565b6000602082840312156146c157600080fd5b813567ffffffffffffffff8111156146d857600080fd5b6121fd84828501614329565b6000806000606084860312156146f957600080fd5b8335614704816140c1565b9250602084013567ffffffffffffffff8082111561472157600080fd5b61472d878388016142b8565b9350604086013591508082111561474357600080fd5b50614750868287016142b8565b9150509250925092565b60006020828403121561476c57600080fd5b813561415a816140c1565b6020808252825182820181905260009190848201906040850190845b818110156147b1578351151583529284019291840191600101614793565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147b157835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016147d9565b60008060006060848603121561482057600080fd5b833561482b816140c1565b925060208401359150604084013567ffffffffffffffff81111561484e57600080fd5b61475086828701614329565b60008060006060848603121561486f57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561489957600080fd5b82356148a4816140c1565b91506148b2602084016141ea565b90509250929050565b600080604083850312156148ce57600080fd5b82356148d9816140c1565b915060208301356148e9816140c1565b809150509250929050565b600080600080600060a0868803121561490c57600080fd5b8535614917816140c1565b94506020860135614927816140c1565b93506040860135925060608601359150608086013567ffffffffffffffff81111561495157600080fd5b61445c88828901614329565b60008060006060848603121561497257600080fd5b833561497d816140c1565b95602085013595506040909401359392505050565b600080604083850312156149a557600080fd5b823591506148b2602084016141ea565b6000806000606084860312156149ca57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561484e57600080fd5b600181811c90821680614a0357607f821691505b60208210811415610eb4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008151614a4f818560208601614161565b9290920192915050565b600080845481600182811c915080831680614a7557607f831692505b6020808410821415614aae577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015614ac25760018114614af157614b1e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650614b1e565b60008b81526020902060005b86811015614b165781548b820152908501908301614afd565b505084890196505b505050505050614b2e8185614a3d565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115614b7957614b79614b37565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614bb057614bb0614b37565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015614bf857614bf8614b37565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614c3557614c35614b37565b500290565b600060208284031215614c4c57600080fd5b815161415a816140c1565b848152836020820152826040820152608060608201526000614c7c608083018461418d565b9695505050505050565b600082614cbc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060ff821660ff84168060ff03821115614cde57614cde614b37565b019392505050565b604081526000614cf96040830185614661565b8281036020840152614b2e8185614661565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152614d4460a0830186614661565b8281036060840152614d568186614661565b90508281036080840152614d6a818561418d565b98975050505050505050565b600060208284031215614d8857600080fd5b815161415a8161410f565b600060033d1115614dac5760046000803e5060005160e01c5b90565b600060443d1015614dbd5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715614e0b57505050505090565b8285019150815181811115614e235750505050505090565b843d8701016020828501011115614e3d5750505050505090565b614e4c60208286010187614249565b509095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015283606083015260a06080830152614e9c60a083018461418d565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212206045803d74f9576bb8ac4fe6434bb9a221a55ec859d83abe9cbbf1a8b776646064736f6c634300080a0033

Deployed Bytecode Sourcemap

717:12469:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3729:128;;;;;;;;;;-1:-1:-1;3729:128:18;;;;;:::i;:::-;3796:7;3823:26;;;:17;:26;;;;;;;3729:128;;;;345:25:23;;;333:2;318:18;3729:128:18;;;;;;;;2130:228:3;;;;;;;;;;-1:-1:-1;2130:228:3;;;;;:::i;:::-;;:::i;1181:305::-;;;;;;;;;;-1:-1:-1;1181:305:3;;;;;:::i;:::-;;:::i;:::-;;;1457:14:23;;1450:22;1432:41;;1420:2;1405:18;1181:305:3;1292:187:23;1495:18:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;968:21::-;;;;;;;;;;-1:-1:-1;968:21:18;;;;;;;;;;;2492:42:23;2480:55;;;2462:74;;2450:2;2435:18;968:21:18;2316:226:23;8081:150:18;;;;;;;;;;-1:-1:-1;8081:150:18;;;;;:::i;:::-;;:::i;3865:124::-;;;;;;;;;;-1:-1:-1;3865:124:18;;;;;:::i;:::-;3930:7;3957:24;;;:15;:24;;;;;;;3865:124;12084:104;;;;;;;;;;-1:-1:-1;12159:21:18;12084:104;;4127:118;;;;;;;;;;-1:-1:-1;4222:14:18;;4177:7;3957:24;;;:15;:24;;;;;;4127:118;;2268:244;;;;;;;;;;;;;:::i;5457:336::-;;;;;;;;;;;;;:::i;2043:50::-;;;;;;;;;;-1:-1:-1;2043:50:18;;;;;:::i;:::-;;;;;;;;;;;;;;;;8519:92;;;;;;;;;;-1:-1:-1;8519:92:18;;;;;:::i;:::-;;:::i;:::-;;4005:430:3;;;;;;;;;;-1:-1:-1;4005:430:3;;;;;:::i;:::-;;:::i;12407:273:18:-;;;:::i;6821:669::-;;;;;;;;;;-1:-1:-1;6821:669:18;;;;;:::i;:::-;;:::i;752:143:19:-;;;;;;;;;;;;852:42;752:143;;5819:564:18;;;;;;;;;;-1:-1:-1;5819:564:18;;;;;:::i;:::-;;:::i;925:33::-;;;;;;;;;;;;;;;;2515:508:3;;;;;;;;;;-1:-1:-1;2515:508:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;993:35:18:-;;;;;;;;;;-1:-1:-1;993:35:18;;;;;;;;;;;8815:99;;;;;;;;;;-1:-1:-1;8815:99:18;;;;;:::i;:::-;;:::i;3014:117::-;;;;;;;;;;;;;:::i;3997:122::-;;;;;;;;;;-1:-1:-1;4096:14:18;;4049:7;3823:26;;;:17;:26;;;;;;3997:122;4127:118;2154:52;;;;;;;;;;-1:-1:-1;2154:52:18;;;;;:::i;:::-;;;;;;;;;;;;;;2097:53;;;;;;;;;;-1:-1:-1;2097:53:18;;;;;:::i;:::-;;;;;;;;;;;;;;2210:50;;;;;;;;;;-1:-1:-1;2210:50:18;;;;;:::i;:::-;;;;;;;;;;;;;;11569:400;;;;;;;;;;-1:-1:-1;11569:400:18;;;;;:::i;:::-;;:::i;4250:301::-;;;;;;;;;;-1:-1:-1;4250:301:18;;;;;:::i;:::-;;:::i;1661:101:20:-;;;;;;;;;;;;;:::i;4556:316:18:-;;;;;;;;;;-1:-1:-1;4556:316:18;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2517:133::-;;;;;;;;;;-1:-1:-1;2517:133:18;;;;;:::i;:::-;2594:7;2615:27;;;:18;:27;;;;;;;2517:133;3139:115;;;;;;;;;;-1:-1:-1;3139:115:18;;;;;:::i;:::-;;:::i;2792:97::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;11977:99::-;;;;;;;;;;-1:-1:-1;12054:14:18;;11977:99;;1029:85:20;;;;;;;;;;-1:-1:-1;1101:6:20;;;;1029:85;;8919:94:18;;;;;;;;;;-1:-1:-1;8919:94:18;;;;;:::i;:::-;;:::i;4933:516::-;;;;;;:::i;:::-;;:::i;9110:294::-;;;;;;;;;;-1:-1:-1;9110:294:18;;;;;:::i;:::-;;:::i;12196:121::-;;;;;;;;;;;;;:::i;1037:33::-;;;;;;;;;;;;;;;;1991:48;;;;;;;;;;-1:-1:-1;1991:48:18;;;;;:::i;:::-;;;;;;;;;;;;;;;;2689:95;;;;;;;;;;;;;:::i;2897:109::-;;;;;;;;;;;;;:::i;3091:153:3:-;;;;;;;;;;-1:-1:-1;3091:153:3;;;;;:::i;:::-;;:::i;888:30:18:-;;;;;;;;;;;;;;;;851:33;;;;;;;;;;;;;;;;9021:81;;;;;;;;;;-1:-1:-1;9021:81:18;;;;;:::i;:::-;;:::i;1281:80::-;;;;;;;;;;-1:-1:-1;1281:80:18;;;;;;;;3516:113;;;;;;;;;;-1:-1:-1;3516:113:18;;;;;:::i;:::-;3599:22;;3575:4;3599:22;;;:16;:22;;;;;;;;;3516:113;7807:269;;;;;;;;;;-1:-1:-1;7807:269:18;;;;;:::i;:::-;;:::i;3398:110::-;;;;;;;;;;-1:-1:-1;3398:110:18;;;;;:::i;:::-;3458:4;3476:27;;;:18;:27;;;;;;;;;3398:110;8709:101;;;;;;;;;;;;;:::i;8616:88::-;;;;;;;;;;;;;:::i;12781:402::-;;;;;;;;;;-1:-1:-1;12781:402:18;;;;;:::i;:::-;;:::i;3544:389:3:-;;;;;;;;;;-1:-1:-1;3544:389:3;;;;;:::i;:::-;;:::i;1911:198:20:-;;;;;;;;;;-1:-1:-1;1911:198:20;;;;;:::i;:::-;;:::i;11262:302:18:-;;;;;;;;;;-1:-1:-1;11262:302:18;;;;;:::i;:::-;;:::i;3259:134::-;;;;;;;;;;-1:-1:-1;3259:134:18;;;;;:::i;:::-;;:::i;1077:28::-;;;;;;;;;;;;;;;;7495:304;;;;;;:::i;:::-;;:::i;3637:84::-;;;;;;;;;;-1:-1:-1;3708:5:18;;3637:84;;8429:85;;;;;;;;;;-1:-1:-1;8429:85:18;;;;;:::i;:::-;;:::i;2130:228:3:-;2216:7;2243:21;;;2235:77;;;;-1:-1:-1;;;2235:77:3;;16513:2:23;2235:77:3;;;16495:21:23;16552:2;16532:18;;;16525:30;16591:34;16571:18;;;16564:62;16662:13;16642:18;;;16635:41;16693:19;;2235:77:3;;;;;;;;;-1:-1:-1;2329:9:3;:13;;;;;;;;;;;:22;;;;;;;;;;;2130:228;;;;;:::o;1181:305::-;1283:4;1318:41;;;1333:26;1318:41;;:109;;-1:-1:-1;1375:52:3;;;1390:37;1375:52;1318:109;:161;;;-1:-1:-1;952:25:5;937:40;;;;1443:36:3;829:155:5;1495:18:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;8081:150::-;8141:13;8192;8207:17;8216:7;8207:8;:17::i;:::-;8175:50;;;;;;;;;:::i;:::-;;;;;;;;;;;;;8161:65;;8081:150;;;:::o;4204:33::-;4197:40;;4127:118;:::o;2268:244::-;2320:7;;;2362:126;2398:14;;2387:7;:25;2362:126;;2449:27;;;;:18;:27;;;;;;2440:36;;;;:::i;:::-;;-1:-1:-1;2414:9:18;;;;:::i;:::-;;;;2362:126;;;-1:-1:-1;2499:5:18;2268:244;-1:-1:-1;2268:244:18:o;5457:336::-;5523:16;;5502:4;;5523:16;;;;;5519:61;;-1:-1:-1;5563:5:18;;5457:336::o;5519:61::-;4096:14;;4049:7;3823:26;;;:17;:26;;;;;;5593:15;:39;5590:83;;;-1:-1:-1;5656:5:18;;5457:336::o;5590:83::-;4222:14;;4177:7;3957:24;;;:15;:24;;;;;;5686:15;:37;5683:81;;;-1:-1:-1;5747:5:18;;5457:336::o;5683:81::-;-1:-1:-1;5781:4:18;;5457:336::o;8519:92::-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;8579:16:18::1;:27:::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8519:92::o;4005:430:3:-;4230:20;;;719:10:1;4230:20:3;;:60;;-1:-1:-1;4254:36:3;4271:4;719:10:1;12781:402:18;:::i;4254:36:3:-;4209:157;;;;-1:-1:-1;;;4209:157:3;;19860:2:23;4209:157:3;;;19842:21:23;19899:2;19879:18;;;19872:30;19938:34;19918:18;;;19911:62;20009:20;19989:18;;;19982:48;20047:19;;4209:157:3;19658:414:23;4209:157:3;4376:52;4399:4;4405:2;4409:3;4414:7;4423:4;4376:22;:52::i;:::-;4005:430;;;;;:::o;12407:273:18:-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;12528:64:18::1;::::0;12477:21:::1;::::0;12463:11:::1;::::0;12536:10:::1;::::0;12477:21;;12463:11;12528:64;12463:11;12528:64;12477:21;12536:10;12528:64:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12509:83;;;12611:7;12603:16;;;::::0;::::1;;12648:3;12630:14;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;12407:273:18:o;6821:669::-;7016:10;:17;6996:9;:16;:37;6988:72;;;;-1:-1:-1;;;6988:72:18;;20489:2:23;6988:72:18;;;20471:21:23;20528:2;20508:18;;;20501:30;20567:24;20547:18;;;20540:52;20609:18;;6988:72:18;20287:346:23;6988:72:18;7093:8;:15;7073:9;:16;:35;7065:72;;;;-1:-1:-1;;;7065:72:18;;20840:2:23;7065:72:18;;;20822:21:23;20879:2;20859:18;;;20852:30;20918:26;20898:18;;;20891:54;20962:18;;7065:72:18;20638:348:23;7065:72:18;7164:6;;;;7150:10;:20;7142:66;;;;-1:-1:-1;;;7142:66:18;;21193:2:23;7142:66:18;;;21175:21:23;21232:2;21212:18;;;21205:30;21271:34;21251:18;;;21244:62;21342:3;21322:18;;;21315:31;21363:19;;7142:66:18;20991:397:23;7142:66:18;7218:9;7213:273;7237:9;:16;7233:1;:20;7213:273;;;7275:16;7294:9;7304:1;7294:12;;;;;;;;:::i;:::-;;;;;;;7275:31;;7321:15;7339:8;7348:1;7339:11;;;;;;;;:::i;:::-;;;;;;;7321:29;;7365:16;7384:10;7395:1;7384:13;;;;;;;;:::i;:::-;;;;;;;7365:32;;7412:68;7430:10;7442:8;7452:7;7461:8;7471:5;7477:1;7471:8;;;;;;;;:::i;:::-;;;;;;;7412:17;:68::i;:::-;7260:226;;;7255:3;;;;;:::i;:::-;;;;7213:273;;5819:564;6008:10;:17;5988:9;:16;:37;5980:72;;;;-1:-1:-1;;;5980:72:18;;20489:2:23;5980:72:18;;;20471:21:23;20528:2;20508:18;;;20501:30;20567:24;20547:18;;;20540:52;20609:18;;5980:72:18;20287:346:23;5980:72:18;6085:8;:15;6065:9;:16;:35;6057:72;;;;-1:-1:-1;;;6057:72:18;;20840:2:23;6057:72:18;;;20822:21:23;20879:2;20859:18;;;20852:30;20918:26;20898:18;;;20891:54;20962:18;;6057:72:18;20638:348:23;6057:72:18;6156:6;;;;6142:10;:20;6134:66;;;;-1:-1:-1;;;6134:66:18;;21193:2:23;6134:66:18;;;21175:21:23;21232:2;21212:18;;;21205:30;21271:34;21251:18;;;21244:62;21342:3;21322:18;;;21315:31;21363:19;;6134:66:18;20991:397:23;6134:66:18;6213:16;;;;;;;:24;;6233:4;6213:24;6205:53;;;;-1:-1:-1;;;6205:53:18;;21784:2:23;6205:53:18;;;21766:21:23;21823:2;21803:18;;;21796:30;21862:18;21842;;;21835:46;21898:18;;6205:53:18;21582:340:23;6205:53:18;6268:9;6263:116;6287:9;:16;6283:1;:20;6263:116;;;6316:57;6322:9;6332:1;6322:12;;;;;;;;:::i;:::-;;;;;;;6336:8;6345:1;6336:11;;;;;;;;:::i;:::-;;;;;;;6349:10;6360:1;6349:13;;;;;;;;:::i;:::-;;;;;;;6364:5;6370:1;6364:8;;;;;;;;:::i;:::-;;;;;;;6316:5;:57::i;:::-;6305:3;;;;:::i;:::-;;;;6263:116;;2515:508:3;2666:16;2725:3;:10;2706:8;:15;:29;2698:83;;;;-1:-1:-1;;;2698:83:3;;22129:2:23;2698:83:3;;;22111:21:23;22168:2;22148:18;;;22141:30;22207:34;22187:18;;;22180:62;22278:11;22258:18;;;22251:39;22307:19;;2698:83:3;21927:405:23;2698:83:3;2792:30;2839:8;:15;2825:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2825:30:3;;2792:63;;2871:9;2866:120;2890:8;:15;2886:1;:19;2866:120;;;2945:30;2955:8;2964:1;2955:11;;;;;;;;:::i;:::-;;;;;;;2968:3;2972:1;2968:6;;;;;;;;:::i;:::-;;;;;;;2945:9;:30::i;:::-;2926:13;2940:1;2926:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;2907:3;;;:::i;:::-;;;2866:120;;;-1:-1:-1;3003:13:3;2515:508;-1:-1:-1;;;2515:508:3:o;8815:99:18:-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;8883:26:18;;::::1;::::0;:13:::1;::::0;:26:::1;::::0;::::1;::::0;::::1;:::i;:::-;;8815:99:::0;:::o;3014:117::-;3069:16;3105:18;3098:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3014:117;:::o;11569:400::-;11719:9;11715:208;11738:3;:10;11734:1;:14;11715:208;;;11778:6;;;;11764:10;:20;11761:112;;11801:20;11814:3;11818:1;11814:6;;;;;;;;:::i;:::-;;;;;;;3458:4;3476:27;;;:18;:27;;;;;;;;;3398:110;11801:20;11793:73;;;;-1:-1:-1;;;11793:73:18;;22539:2:23;11793:73:18;;;22521:21:23;22578:2;22558:18;;;22551:30;22617:34;22597:18;;;22590:62;22688:10;22668:18;;;22661:38;22716:19;;11793:73:18;22337:404:23;11793:73:18;11908:6;11915:1;11908:9;;;;;;;;:::i;:::-;;;;;;;11878:18;:26;11897:3;11901:1;11897:6;;;;;;;;:::i;:::-;;;;;;;11878:26;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;11750:3:18;;-1:-1:-1;11750:3:18;;;:::i;:::-;;;;11715:208;;;;11927:37;11943:7;11952:3;11957:6;11927:15;:37::i;:::-;11569:400;;;:::o;4250:301::-;4316:16;4339:26;4382:14;;4399:1;4382:18;;;;:::i;:::-;4368:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4368:33:18;;4339:62;;4410:15;4406:120;4442:14;;4431:7;:25;4406:120;;4496:24;4506:4;4512:7;4496:9;:24::i;:::-;4475:9;4485:7;4475:18;;;;;;;;:::i;:::-;;;;;;;;;;:45;4458:9;;;;:::i;:::-;;;;4406:120;;;-1:-1:-1;4537:9:18;4250:301;-1:-1:-1;;4250:301:18:o;1661:101:20:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;1725:30:::1;1752:1;1725:18;:30::i;:::-;1661:101::o:0;4556:316:18:-;4624:13;4644:29;4687:14;;4704:1;4687:18;;;;:::i;:::-;4676:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4676:30:18;;4644:62;;4715:15;4711:130;4747:14;;4736:7;:25;4711:130;;4834:1;4807:24;4817:4;4823:7;4807:9;:24::i;:::-;:28;4780:15;4796:7;4780:24;;;;;;;;:::i;:::-;:55;;;:24;;;;;;;;;;;:55;4763:9;;;;:::i;:::-;;;;4711:130;;3139:115;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;3215:14:18::1;:34:::0;3139:115::o;2792:97::-;2837:16;2873:8;2866:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2792:97;:::o;8919:94::-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;8987:21:18;;::::1;::::0;:12:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;4933:516::-:0;5053:16;;;;;;;5045:45;;;;-1:-1:-1;;;5045:45:18;;21784:2:23;5045:45:18;;;21766:21:23;21823:2;21803:18;;;21796:30;21862:18;21842;;;21835:46;21898:18;;5045:45:18;21582:340:23;5045:45:18;4096:14;;4049:7;3823:26;;;:17;:26;;;;;;5109:15;:40;;5101:73;;;;-1:-1:-1;;;5101:73:18;;23078:2:23;5101:73:18;;;23060:21:23;23117:2;23097:18;;;23090:30;23156:22;23136:18;;;23129:50;23196:18;;5101:73:18;22876:344:23;5101:73:18;4222:14;;4177:7;3957:24;;;:15;:24;;;;;;5193:15;:37;5185:64;;;;-1:-1:-1;;;5185:64:18;;23427:2:23;5185:64:18;;;23409:21:23;23466:2;23446:18;;;23439:30;23505:16;23485:18;;;23478:44;23539:18;;5185:64:18;23225:338:23;5185:64:18;5279:1;5268:8;:12;:36;;;;;5296:8;;5284;:20;;5268:36;5260:65;;;;-1:-1:-1;;;5260:65:18;;23770:2:23;5260:65:18;;;23752:21:23;23809:2;23789:18;;;23782:30;23848:18;23828;;;23821:46;23884:18;;5260:65:18;23568:340:23;5260:65:18;5365:8;5357:5;;:16;;;;:::i;:::-;5344:9;:29;;5336:56;;;;-1:-1:-1;;;5336:56:18;;24348:2:23;5336:56:18;;;24330:21:23;24387:2;24367:18;;;24360:30;24426:16;24406:18;;;24399:44;24460:18;;5336:56:18;24146:338:23;5336:56:18;5397:47;5403:8;5413:14;;5429:8;5439:4;5397:5;:47::i;9110:294::-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;9225:26:18::1;::::0;;;:17:::1;:26;::::0;;;;:38;;;9277:12;9274:78:::1;;9316:24;:9:::0;9328:12:::1;9316:24;:::i;:::-;9306:34;;9274:78;9362:24;::::0;;;:15:::1;:24;::::0;;;;;:34;;;;-1:-1:-1;9110:294:18:o;12196:121::-;12243:7;12159:21;12054:14;;12270:39;;;;:::i;2689:95::-;2733:16;2769:7;2762:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2689:95;:::o;2897:109::-;2948:16;2984:14;2977:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2897:109;:::o;3091:153:3:-;3185:52;719:10:1;3218:8:3;3228;3185:18;:52::i;9021:81:18:-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;9080:8:18::1;:17:::0;9021:81::o;7807:269::-;7866:7;;;7917:126;7953:14;;7942:7;:25;7917:126;;8007:24;8017:4;8023:7;8007:9;:24::i;:::-;7995:36;;;;:::i;:::-;;-1:-1:-1;7969:9:18;;;;:::i;:::-;;;;7917:126;;8709:101;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;8754:51:18::1;::::0;8762:10:::1;::::0;8783:21:::1;8754:51:::0;::::1;;;::::0;::::1;::::0;;;8783:21;8762:10;8754:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;8709:101::o:0;8616:88::-;8660:13;8687:12;8680:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8680:19:18;;8616:88;-1:-1:-1;;;;;8616:88:18:o;12781:402::-;12994:20;;13038:28;;;;;12994:20;2480:55:23;;;13038:28:18;;;2462:74:23;12870:4:18;;12994:20;;;13030:49;;;;12994:20;;13038:21;;2435:18:23;;13038:28:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13030:49;;;13026:93;;;13103:4;13096:11;;;;;13026:93;3433:27:3;;;;3410:4;3433:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;13136:39:18;13129:46;12781:402;-1:-1:-1;;;;12781:402:18:o;3544:389:3:-;3744:20;;;719:10:1;3744:20:3;;:60;;-1:-1:-1;3768:36:3;3785:4;719:10:1;12781:402:18;:::i;3768:36:3:-;3723:148;;;;-1:-1:-1;;;3723:148:3;;24976:2:23;3723:148:3;;;24958:21:23;25015:2;24995:18;;;24988:30;25054:34;25034:18;;;25027:62;25125:11;25105:18;;;25098:39;25154:19;;3723:148:3;24774:405:23;3723:148:3;3881:45;3899:4;3905:2;3909;3913:6;3921:4;3881:17;:45::i;1911:198:20:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;1999:22:::1;::::0;::::1;1991:73;;;::::0;-1:-1:-1;;;1991:73:20;;25386:2:23;1991:73:20::1;::::0;::::1;25368:21:23::0;25425:2;25405:18;;;25398:30;25464:34;25444:18;;;25437:62;25535:8;25515:18;;;25508:36;25561:19;;1991:73:20::1;25184:402:23::0;1991:73:20::1;2074:28;2093:8;2074:18;:28::i;11262:302:18:-:0;11400:6;;;;11386:10;:20;11383:106;;3458:4;3476:27;;;:18;:27;;;;;;;;11414:69;;;;-1:-1:-1;;;11414:69:18;;22539:2:23;11414:69:18;;;22521:21:23;22578:2;22558:18;;;22551:30;22617:34;22597:18;;;22590:62;22688:10;22668:18;;;22661:38;22716:19;;11414:69:18;22337:404:23;11414:69:18;11493:30;11504:7;11513:2;11517:5;11493:10;:30::i;:::-;11528:22;;;;:18;:22;;;;;:31;;11554:5;;11528:22;:31;;11554:5;;11528:31;:::i;:::-;;;;-1:-1:-1;;;;;11262:302:18:o;3259:134::-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;3347:27:18::1;::::0;;;:18:::1;:27;::::0;;;;;:41;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;3259:134::o;7495:304::-;7642:1;7609:30;7619:10;7631:7;7609:9;:30::i;:::-;:34;7601:69;;;;-1:-1:-1;;;7601:69:18;;25793:2:23;7601:69:18;;;25775:21:23;25832:2;25812:18;;;25805:30;25871:24;25851:18;;;25844:52;25913:18;;7601:69:18;25591:346:23;7601:69:18;7700:14;;7689:7;:25;;7681:61;;;;-1:-1:-1;;;7681:61:18;;26144:2:23;7681:61:18;;;26126:21:23;26183:2;26163:18;;;26156:30;26222:25;26202:18;;;26195:53;26265:18;;7681:61:18;25942:347:23;7681:61:18;7752:42;7765:7;7774:9;7785:2;7789:4;7752:42;;;;;;;;;:::i;:::-;;;;;;;;7495:304;;;:::o;8429:85::-;1101:6:20;;1241:23;1101:6;719:10:1;1241:23:20;1233:68;;;;-1:-1:-1;;;1233:68:20;;19499:2:23;1233:68:20;;;19481:21:23;;;19518:18;;;19511:30;19577:34;19557:18;;;19550:62;19629:18;;1233:68:20;19297:356:23;1233:68:20;8490:6:18::1;:19:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;8429:85::o;9409:448::-;9462:27;9500:7;9496:35;;-1:-1:-1;;9515:10:18;;;;;;;;;;;;;;;;;;9409:448::o;9496:35::-;9547:2;9535:9;9570:45;9577:6;;9570:45;;9591:5;;;;:::i;:::-;;-1:-1:-1;9602:7:18;;-1:-1:-1;9607:2:18;9602:7;;:::i;:::-;;;9570:45;;;9619:17;9649:3;9639:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9639:14:18;-1:-1:-1;9619:34:18;-1:-1:-1;9670:3:18;9678:151;9685:7;;9678:151;;9704:5;9708:1;9704;:5;:::i;:::-;9700:9;-1:-1:-1;9715:10:18;9746:7;9751:2;9746;:7;:::i;:::-;9745:14;;9757:2;9745:14;:::i;:::-;9740:19;;:2;:19;:::i;:::-;9729:31;;:2;:31;:::i;:::-;9715:46;;9767:9;9786:4;9779:12;;9767:24;;9807:2;9797:4;9802:1;9797:7;;;;;;;;:::i;:::-;;;;:12;;;;;;;;;;-1:-1:-1;9815:8:18;9821:2;9815:8;;:::i;:::-;;;9694:135;;9678:151;;;-1:-1:-1;9847:4:18;9409:448;-1:-1:-1;;;;9409:448:18:o;6178:1115:3:-;6398:7;:14;6384:3;:10;:28;6376:81;;;;-1:-1:-1;;;6376:81:3;;27435:2:23;6376:81:3;;;27417:21:23;27474:2;27454:18;;;27447:30;27513:34;27493:18;;;27486:62;27584:10;27564:18;;;27557:38;27612:19;;6376:81:3;27233:404:23;6376:81:3;6475:16;;;6467:66;;;;-1:-1:-1;;;6467:66:3;;27844:2:23;6467:66:3;;;27826:21:23;27883:2;27863:18;;;27856:30;27922:34;27902:18;;;27895:62;27993:7;27973:18;;;27966:35;28018:19;;6467:66:3;27642:401:23;6467:66:3;719:10:1;6544:16:3;6657:411;6681:3;:10;6677:1;:14;6657:411;;;6712:10;6725:3;6729:1;6725:6;;;;;;;;:::i;:::-;;;;;;;6712:19;;6745:14;6762:7;6770:1;6762:10;;;;;;;;:::i;:::-;;;;;;;;;;;;6787:19;6809:13;;;;;;;;;;:19;;;;;;;;;;;;;6762:10;;-1:-1:-1;6850:21:3;;;;6842:76;;;;-1:-1:-1;;;6842:76:3;;28250:2:23;6842:76:3;;;28232:21:23;28289:2;28269:18;;;28262:30;28328:34;28308:18;;;28301:62;28399:12;28379:18;;;28372:40;28429:19;;6842:76:3;28048:406:23;6842:76:3;6960:9;:13;;;;;;;;;;;:19;;;;;;;;;;;6982:20;;;6960:42;;7030:17;;;;;;;:27;;6982:20;;6960:9;7030:27;;6982:20;;7030:27;:::i;:::-;;;;;;;;6698:370;;;6693:3;;;;:::i;:::-;;;6657:411;;;;7113:2;7083:47;;7107:4;7083:47;;7097:8;7083:47;;;7117:3;7122:7;7083:47;;;;;;;:::i;:::-;;;;;;;;7141:59;7161:8;7171:4;7177:2;7181:3;7186:7;7195:4;7141:19;:59::i;:::-;7211:75;7247:8;7257:4;7263:2;7267:3;7272:7;7281:4;7211:35;:75::i;:::-;6366:927;6178:1115;;;;;:::o;4885:947::-;5066:16;;;5058:66;;;;-1:-1:-1;;;5058:66:3;;27844:2:23;5058:66:3;;;27826:21:23;27883:2;27863:18;;;27856:30;27922:34;27902:18;;;27895:62;27993:7;27973:18;;;27966:35;28018:19;;5058:66:3;27642:401:23;5058:66:3;719:10:1;5135:16:3;5199:21;5217:2;5199:17;:21::i;:::-;5176:44;;5230:24;5257:25;5275:6;5257:17;:25::i;:::-;5230:52;;5364:19;5386:13;;;;;;;;;;;:19;;;;;;;;;;;5423:21;;;;5415:76;;;;-1:-1:-1;;;5415:76:3;;28250:2:23;5415:76:3;;;28232:21:23;28289:2;28269:18;;;28262:30;28328:34;28308:18;;;28301:62;28399:12;28379:18;;;28372:40;28429:19;;5415:76:3;28048:406:23;5415:76:3;5525:9;:13;;;;;;;;;;;:19;;;;;;;;;;;5547:20;;;5525:42;;5587:17;;;;;;;:27;;5547:20;;5525:9;5587:27;;5547:20;;5587:27;:::i;:::-;;;;-1:-1:-1;;5630:46:3;;;29103:25:23;;;29159:2;29144:18;;29137:34;;;5630:46:3;;;;;;;;;;;;;;;29076:18:23;5630:46:3;;;;;;;5687:59;5707:8;5717:4;5723:2;5727:3;5732:7;5741:4;5687:19;:59::i;:::-;5757:68;5788:8;5798:4;5804:2;5808;5812:6;5820:4;5757:30;:68::i;:::-;5048:784;;;;4885:947;;;;;:::o;6388:405:18:-;6550:14;;6544:2;:20;;6536:56;;;;-1:-1:-1;;;6536:56:18;;26144:2:23;6536:56:18;;;26126:21:23;26183:2;26163:18;;;26156:30;26222:25;26202:18;;;26195:53;26265:18;;6536:56:18;25942:347:23;6536:56:18;6597:33;6609:2;6613;6617:6;6625:4;6597:11;:33::i;:::-;6635:22;;;;:18;:22;;;;;:32;;6661:6;;6635:22;:32;;6661:6;;6635:32;:::i;:::-;;;;-1:-1:-1;;6682:20:18;;;;;;;:16;:20;;;;;;;;6678:111;;6719:7;:16;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6750:20:18;;;:16;6719;6750:20;;;;:27;;;;;;;;;6678:111;6388:405;;;;:::o;708:342:4:-;867:23;;;719:10:1;867:23:4;;:66;;-1:-1:-1;894:39:4;911:7;719:10:1;12781:402:18;:::i;894:39:4:-;846:154;;;;-1:-1:-1;;;846:154:4;;24976:2:23;846:154:4;;;24958:21:23;25015:2;24995:18;;;24988:30;25054:34;25034:18;;;25027:62;25125:11;25105:18;;;25098:39;25154:19;;846:154:4;24774:405:23;846:154:4;1011:32;1022:7;1031:3;1036:6;1011:10;:32::i;2263:187:20:-;2355:6;;;;2371:17;;;;;;;;;;;2403:40;;2355:6;;;2371:17;2355:6;;2403:40;;2336:16;;2403:40;2326:124;2263:187;:::o;12718:323:3:-;12868:8;12859:17;;:5;:17;;;;12851:71;;;;-1:-1:-1;;;12851:71:3;;29384:2:23;12851:71:3;;;29366:21:23;29423:2;29403:18;;;29396:30;29462:34;29442:18;;;29435:62;29533:11;29513:18;;;29506:39;29562:19;;12851:71:3;29182:405:23;12851:71:3;12932:25;;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;;;;;;;;;;;;12993:41;;1432::23;;;12993::3;;1405:18:23;12993:41:3;;;;;;;12718:323;;;:::o;392:310:4:-;526:23;;;719:10:1;526:23:4;;:66;;-1:-1:-1;553:39:4;570:7;719:10:1;12781:402:18;:::i;553:39:4:-;505:154;;;;-1:-1:-1;;;505:154:4;;24976:2:23;505:154:4;;;24958:21:23;25015:2;24995:18;;;24988:30;25054:34;25034:18;;;25027:62;25125:11;25105:18;;;25098:39;25154:19;;505:154:4;24774:405:23;505:154:4;670:25;676:7;685:2;689:5;670;:25::i;10218:1039:18:-;10503:16;;;;;;;:41;;-1:-1:-1;10524:20:18;;;;;;;:16;:20;;;;;;;;10523:21;10503:41;10500:131;;;10561:7;:16;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10592:20:18;;;:16;10561;10592:20;;;;:27;;;;;;;;;10500:131;10686:16;;;10683:315;;10723:9;10719:268;10742:7;:14;10738:1;:18;10719:268;;;10782:10;10795:3;10799:1;10795:6;;;;;;;;:::i;:::-;;;;;;;10782:19;;10820:11;10834:7;10842:1;10834:10;;;;;;;;:::i;:::-;;;;;;;;;;;10863:8;:19;;;;;;;;;;;;;;;;;;;;;10901:14;:23;;;;;;;;;;;;;;10943:18;:28;;;;;;;-1:-1:-1;10943:28:18;;;;;;;;;-1:-1:-1;10758:3:18;;;;:::i;:::-;;;;10719:268;;;;10683:315;11068:18;;;;;;;:48;;;11090:21;11106:4;11090:15;:21::i;:::-;:26;11068:48;11065:109;;;11133:29;11157:4;11133:23;:29::i;:::-;11184:65;6178:1115:3;16072:792;16304:13;;;1465:19:0;:23;16300:558:3;;16339:79;;;;;:43;;;;;;:79;;16383:8;;16393:4;;16399:3;;16404:7;;16413:4;;16339:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16339:79:3;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;16335:513;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;16724:6;16717:14;;-1:-1:-1;;;16717:14:3;;;;;;;;:::i;16335:513::-;;;16771:62;;-1:-1:-1;;;16771:62:3;;31834:2:23;16771:62:3;;;31816:21:23;31873:2;31853:18;;;31846:30;31912:34;31892:18;;;31885:62;31983:22;31963:18;;;31956:50;32023:19;;16771:62:3;31632:416:23;16335:513:3;16497:60;;;16509:48;16497:60;16493:157;;16581:50;;-1:-1:-1;;;16581:50:3;;32255:2:23;16581:50:3;;;32237:21:23;32294:2;32274:18;;;32267:30;32333:34;32313:18;;;32306:62;32404:10;32384:18;;;32377:38;32432:19;;16581:50:3;32053:404:23;16493:157:3;16419:245;16072:792;;;;;;:::o;16870:193::-;16989:16;;;17003:1;16989:16;;;;;;;;;16936;;16964:22;;16989:16;;;;;;;;;;;;-1:-1:-1;16989:16:3;16964:41;;17026:7;17015:5;17021:1;17015:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;17051:5;16870:193;-1:-1:-1;;16870:193:3:o;15341:725::-;15548:13;;;1465:19:0;:23;15544:516:3;;15583:72;;;;;:38;;;;;;:72;;15622:8;;15632:4;;15638:2;;15642:6;;15650:4;;15583:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15583:72:3;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;15579:471;;;;:::i;:::-;15704:55;;;15716:43;15704:55;15700:152;;15783:50;;-1:-1:-1;;;15783:50:3;;32255:2:23;15783:50:3;;;32237:21:23;32294:2;32274:18;;;32267:30;32333:34;32313:18;;;32306:62;32404:10;32384:18;;;32377:38;32432:19;;15783:50:3;32053:404:23;8575:709:3;8722:16;;;8714:62;;;;-1:-1:-1;;;8714:62:3;;33264:2:23;8714:62:3;;;33246:21:23;33303:2;33283:18;;;33276:30;33342:34;33322:18;;;33315:62;33413:3;33393:18;;;33386:31;33434:19;;8714:62:3;33062:397:23;8714:62:3;719:10:1;8787:16:3;8851:21;8869:2;8851:17;:21::i;:::-;8828:44;;8882:24;8909:25;8927:6;8909:17;:25::i;:::-;8882:52;;9022:9;:13;;;;;;;;;;;:17;;;;;;;;;;:27;;9043:6;;9022:9;:27;;9043:6;;9022:27;:::i;:::-;;;;-1:-1:-1;;9064:52:3;;;29103:25:23;;;29159:2;29144:18;;29137:34;;;9064:52:3;;;;;9097:1;;9064:52;;;;;;29076:18:23;9064:52:3;;;;;;;9127:65;9147:8;9165:1;9169:2;9173:3;9178:7;9187:4;9127:19;:65::i;:::-;9203:74;9234:8;9252:1;9256:2;9260;9264:6;9272:4;9203:30;:74::i;11640:943::-;11787:18;;;11779:66;;;;-1:-1:-1;;;11779:66:3;;33666:2:23;11779:66:3;;;33648:21:23;33705:2;33685:18;;;33678:30;33744:34;33724:18;;;33717:62;33815:5;33795:18;;;33788:33;33838:19;;11779:66:3;33464:399:23;11779:66:3;11877:7;:14;11863:3;:10;:28;11855:81;;;;-1:-1:-1;;;11855:81:3;;27435:2:23;11855:81:3;;;27417:21:23;27474:2;27454:18;;;27447:30;27513:34;27493:18;;;27486:62;27584:10;27564:18;;;27557:38;27612:19;;11855:81:3;27233:404:23;11855:81:3;11989:66;;;;;;;;;11947:16;11989:66;;;;719:10:1;;12066:364:3;12090:3;:10;12086:1;:14;12066:364;;;12121:10;12134:3;12138:1;12134:6;;;;;;;;:::i;:::-;;;;;;;12121:19;;12154:14;12171:7;12179:1;12171:10;;;;;;;;:::i;:::-;;;;;;;;;;;;12196:19;12218:13;;;;;;;;;;:19;;;;;;;;;;;;;12171:10;;-1:-1:-1;12259:21:3;;;;12251:70;;;;-1:-1:-1;;;12251:70:3;;34070:2:23;12251:70:3;;;34052:21:23;34109:2;34089:18;;;34082:30;34148:34;34128:18;;;34121:62;34219:6;34199:18;;;34192:34;34243:19;;12251:70:3;33868:400:23;12251:70:3;12363:9;:13;;;;;;;;;;;:19;;;;;;;;;;;12385:20;;12363:42;;12102:3;;;;:::i;:::-;;;;12066:364;;;;12483:1;12445:55;;12469:4;12445:55;;12459:8;12445:55;;;12487:3;12492:7;12445:55;;;;;;;:::i;:::-;;;;;;;;12511:65;12531:8;12541:4;12555:1;12559:3;12564:7;12511:65;;;;;;;;;;;;:19;:65::i;10660:786::-;10782:18;;;10774:66;;;;-1:-1:-1;;;10774:66:3;;33666:2:23;10774:66:3;;;33648:21:23;33705:2;33685:18;;;33678:30;33744:34;33724:18;;;33717:62;33815:5;33795:18;;;33788:33;33838:19;;10774:66:3;33464:399:23;10774:66:3;719:10:1;10851:16:3;10915:21;10933:2;10915:17;:21::i;:::-;10892:44;;10946:24;10973:25;10991:6;10973:17;:25::i;:::-;11009:66;;;;;;;;;-1:-1:-1;11009:66:3;;;;11108:13;;;;;;;;;:19;;;;;;;;;10946:52;;-1:-1:-1;11145:21:3;;;;11137:70;;;;-1:-1:-1;;;11137:70:3;;34070:2:23;11137:70:3;;;34052:21:23;34109:2;34089:18;;;34082:30;34148:34;34128:18;;;34121:62;34219:6;34199:18;;;34192:34;34243:19;;11137:70:3;33868:400:23;11137:70:3;11241:9;:13;;;;;;;;;;;:19;;;;;;;;;;;;;11263:20;;;11241:42;;11309:54;;29103:25:23;;;29144:18;;;29137:34;;;11241:19:3;;11309:54;;;;;;29076:18:23;11309:54:3;;;;;;;11374:65;11394:8;11404:4;11418:1;11422:3;11427:7;11374:65;;;;;;;;;;;;:19;:65::i;9865:345:18:-;9937:9;9932:271;9952:7;:14;9948:18;;9932:271;;;10006:4;9992:18;;:7;10000:1;9992:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;:18;9988:204;;;10044:7;10052:14;;:18;;10069:1;;10052:18;:::i;:::-;10044:27;;;;;;;;:::i;:::-;;;;;;;;;;;10031:7;:10;;10044:27;;;;;10039:1;;10031:10;;;;;;:::i;:::-;;;;;;;;;:40;;;;;;;;;;;;;;;;;;10090:7;:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;10122:22;;;;:16;:22;;;;;:30;;;;;;8883:26:::1;8815:99:::0;:::o;9988:204::-;9968:3;;;;:::i;:::-;;;;9932:271;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:180:23;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:23;;14:180;-1:-1:-1;14:180:23:o;381:154::-;467:42;460:5;456:54;449:5;446:65;436:93;;525:1;522;515:12;540:315;608:6;616;669:2;657:9;648:7;644:23;640:32;637:52;;;685:1;682;675:12;637:52;724:9;711:23;743:31;768:5;743:31;:::i;:::-;793:5;845:2;830:18;;;;817:32;;-1:-1:-1;;;540:315:23:o;860:177::-;945:66;938:5;934:78;927:5;924:89;914:117;;1027:1;1024;1017:12;1042:245;1100:6;1153:2;1141:9;1132:7;1128:23;1124:32;1121:52;;;1169:1;1166;1159:12;1121:52;1208:9;1195:23;1227:30;1251:5;1227:30;:::i;:::-;1276:5;1042:245;-1:-1:-1;;;1042:245:23:o;1484:258::-;1556:1;1566:113;1580:6;1577:1;1574:13;1566:113;;;1656:11;;;1650:18;1637:11;;;1630:39;1602:2;1595:10;1566:113;;;1697:6;1694:1;1691:13;1688:48;;;-1:-1:-1;;1732:1:23;1714:16;;1707:27;1484:258::o;1747:328::-;1800:3;1838:5;1832:12;1865:6;1860:3;1853:19;1881:63;1937:6;1930:4;1925:3;1921:14;1914:4;1907:5;1903:16;1881:63;:::i;:::-;1989:2;1977:15;1994:66;1973:88;1964:98;;;;2064:4;1960:109;;1747:328;-1:-1:-1;;1747:328:23:o;2080:231::-;2229:2;2218:9;2211:21;2192:4;2249:56;2301:2;2290:9;2286:18;2278:6;2249:56;:::i;2547:160::-;2612:20;;2668:13;;2661:21;2651:32;;2641:60;;2697:1;2694;2687:12;2641:60;2547:160;;;:::o;2712:180::-;2768:6;2821:2;2809:9;2800:7;2796:23;2792:32;2789:52;;;2837:1;2834;2827:12;2789:52;2860:26;2876:9;2860:26;:::i;2897:184::-;2949:77;2946:1;2939:88;3046:4;3043:1;3036:15;3070:4;3067:1;3060:15;3086:308;3192:66;3187:2;3181:4;3177:13;3173:86;3165:6;3161:99;3326:6;3314:10;3311:22;3290:18;3278:10;3275:34;3272:62;3269:88;;;3337:18;;:::i;:::-;3373:2;3366:22;-1:-1:-1;;3086:308:23:o;3399:183::-;3459:4;3492:18;3484:6;3481:30;3478:56;;;3514:18;;:::i;:::-;-1:-1:-1;3559:1:23;3555:14;3571:4;3551:25;;3399:183::o;3587:724::-;3641:5;3694:3;3687:4;3679:6;3675:17;3671:27;3661:55;;3712:1;3709;3702:12;3661:55;3748:6;3735:20;3774:4;3797:43;3837:2;3797:43;:::i;:::-;3869:2;3863:9;3881:31;3909:2;3901:6;3881:31;:::i;:::-;3947:18;;;4039:1;4035:10;;;;4023:23;;4019:32;;;3981:15;;;;-1:-1:-1;4063:15:23;;;4060:35;;;4091:1;4088;4081:12;4060:35;4127:2;4119:6;4115:15;4139:142;4155:6;4150:3;4147:15;4139:142;;;4221:17;;4209:30;;4259:12;;;;4172;;4139:142;;;-1:-1:-1;4299:6:23;3587:724;-1:-1:-1;;;;;;3587:724:23:o;4316:614::-;4358:5;4411:3;4404:4;4396:6;4392:17;4388:27;4378:55;;4429:1;4426;4419:12;4378:55;4465:6;4452:20;4491:18;4487:2;4484:26;4481:52;;;4513:18;;:::i;:::-;4562:2;4556:9;4574:126;4694:4;4625:66;4618:4;4614:2;4610:13;4606:86;4602:97;4594:6;4574:126;:::i;:::-;4724:2;4716:6;4709:18;4770:3;4763:4;4758:2;4750:6;4746:15;4742:26;4739:35;4736:55;;;4787:1;4784;4777:12;4736:55;4851:2;4844:4;4836:6;4832:17;4825:4;4817:6;4813:17;4800:54;4898:1;4874:15;;;4891:4;4870:26;4863:37;;;;4878:6;4316:614;-1:-1:-1;;;4316:614:23:o;4935:1071::-;5089:6;5097;5105;5113;5121;5174:3;5162:9;5153:7;5149:23;5145:33;5142:53;;;5191:1;5188;5181:12;5142:53;5230:9;5217:23;5249:31;5274:5;5249:31;:::i;:::-;5299:5;-1:-1:-1;5356:2:23;5341:18;;5328:32;5369:33;5328:32;5369:33;:::i;:::-;5421:7;-1:-1:-1;5479:2:23;5464:18;;5451:32;5502:18;5532:14;;;5529:34;;;5559:1;5556;5549:12;5529:34;5582:61;5635:7;5626:6;5615:9;5611:22;5582:61;:::i;:::-;5572:71;;5696:2;5685:9;5681:18;5668:32;5652:48;;5725:2;5715:8;5712:16;5709:36;;;5741:1;5738;5731:12;5709:36;5764:63;5819:7;5808:8;5797:9;5793:24;5764:63;:::i;:::-;5754:73;;5880:3;5869:9;5865:19;5852:33;5836:49;;5910:2;5900:8;5897:16;5894:36;;;5926:1;5923;5916:12;5894:36;;5949:51;5992:7;5981:8;5970:9;5966:24;5949:51;:::i;:::-;5939:61;;;4935:1071;;;;;;;;:::o;6011:799::-;6065:5;6118:3;6111:4;6103:6;6099:17;6095:27;6085:55;;6136:1;6133;6126:12;6085:55;6172:6;6159:20;6198:4;6221:43;6261:2;6221:43;:::i;:::-;6293:2;6287:9;6305:31;6333:2;6325:6;6305:31;:::i;:::-;6371:18;;;6463:1;6459:10;;;;6447:23;;6443:32;;;6405:15;;;;-1:-1:-1;6487:15:23;;;6484:35;;;6515:1;6512;6505:12;6484:35;6551:2;6543:6;6539:15;6563:217;6579:6;6574:3;6571:15;6563:217;;;6659:3;6646:17;6676:31;6701:5;6676:31;:::i;:::-;6720:18;;6758:12;;;;6596;;6563:217;;6815:1872;7010:6;7018;7026;7034;7087:3;7075:9;7066:7;7062:23;7058:33;7055:53;;;7104:1;7101;7094:12;7055:53;7144:9;7131:23;7173:18;7214:2;7206:6;7203:14;7200:34;;;7230:1;7227;7220:12;7200:34;7253:61;7306:7;7297:6;7286:9;7282:22;7253:61;:::i;:::-;7243:71;;7333:2;7323:12;;7388:2;7377:9;7373:18;7360:32;7417:2;7407:8;7404:16;7401:36;;;7433:1;7430;7423:12;7401:36;7456:63;7511:7;7500:8;7489:9;7485:24;7456:63;:::i;:::-;7446:73;;;7572:2;7561:9;7557:18;7544:32;7601:2;7591:8;7588:16;7585:36;;;7617:1;7614;7607:12;7585:36;7640:63;7695:7;7684:8;7673:9;7669:24;7640:63;:::i;:::-;7630:73;;;7756:2;7745:9;7741:18;7728:32;7785:2;7775:8;7772:16;7769:36;;;7801:1;7798;7791:12;7769:36;7824:24;;7879:4;7871:13;;7867:27;-1:-1:-1;7857:55:23;;7908:1;7905;7898:12;7857:55;7944:2;7931:16;7966:43;8006:2;7966:43;:::i;:::-;8038:2;8032:9;8050:31;8078:2;8070:6;8050:31;:::i;:::-;8116:18;;;8204:1;8200:10;;;;8192:19;;8188:28;;;8150:15;;;;-1:-1:-1;8228:19:23;;;8225:39;;;8260:1;8257;8250:12;8225:39;8292:2;8288;8284:11;8304:352;8320:6;8315:3;8312:15;8304:352;;;8406:3;8393:17;8442:2;8429:11;8426:19;8423:109;;;8486:1;8515:2;8511;8504:14;8423:109;8557:56;8605:7;8600:2;8586:11;8582:2;8578:20;8574:29;8557:56;:::i;:::-;8545:69;;-1:-1:-1;8634:12:23;;;;8337;;8304:352;;;-1:-1:-1;6815:1872:23;;;;-1:-1:-1;6815:1872:23;;-1:-1:-1;;;;;;;6815:1872:23:o;8955:595::-;9073:6;9081;9134:2;9122:9;9113:7;9109:23;9105:32;9102:52;;;9150:1;9147;9140:12;9102:52;9190:9;9177:23;9219:18;9260:2;9252:6;9249:14;9246:34;;;9276:1;9273;9266:12;9246:34;9299:61;9352:7;9343:6;9332:9;9328:22;9299:61;:::i;:::-;9289:71;;9413:2;9402:9;9398:18;9385:32;9369:48;;9442:2;9432:8;9429:16;9426:36;;;9458:1;9455;9448:12;9426:36;;9481:63;9536:7;9525:8;9514:9;9510:24;9481:63;:::i;:::-;9471:73;;;8955:595;;;;;:::o;9555:435::-;9608:3;9646:5;9640:12;9673:6;9668:3;9661:19;9699:4;9728:2;9723:3;9719:12;9712:19;;9765:2;9758:5;9754:14;9786:1;9796:169;9810:6;9807:1;9804:13;9796:169;;;9871:13;;9859:26;;9905:12;;;;9940:15;;;;9832:1;9825:9;9796:169;;;-1:-1:-1;9981:3:23;;9555:435;-1:-1:-1;;;;;9555:435:23:o;9995:261::-;10174:2;10163:9;10156:21;10137:4;10194:56;10246:2;10235:9;10231:18;10223:6;10194:56;:::i;10261:321::-;10330:6;10383:2;10371:9;10362:7;10358:23;10354:32;10351:52;;;10399:1;10396;10389:12;10351:52;10439:9;10426:23;10472:18;10464:6;10461:30;10458:50;;;10504:1;10501;10494:12;10458:50;10527:49;10568:7;10559:6;10548:9;10544:22;10527:49;:::i;10587:730::-;10714:6;10722;10730;10783:2;10771:9;10762:7;10758:23;10754:32;10751:52;;;10799:1;10796;10789:12;10751:52;10838:9;10825:23;10857:31;10882:5;10857:31;:::i;:::-;10907:5;-1:-1:-1;10963:2:23;10948:18;;10935:32;10986:18;11016:14;;;11013:34;;;11043:1;11040;11033:12;11013:34;11066:61;11119:7;11110:6;11099:9;11095:22;11066:61;:::i;:::-;11056:71;;11180:2;11169:9;11165:18;11152:32;11136:48;;11209:2;11199:8;11196:16;11193:36;;;11225:1;11222;11215:12;11193:36;;11248:63;11303:7;11292:8;11281:9;11277:24;11248:63;:::i;:::-;11238:73;;;10587:730;;;;;:::o;11322:247::-;11381:6;11434:2;11422:9;11413:7;11409:23;11405:32;11402:52;;;11450:1;11447;11440:12;11402:52;11489:9;11476:23;11508:31;11533:5;11508:31;:::i;11574:642::-;11739:2;11791:21;;;11861:13;;11764:18;;;11883:22;;;11710:4;;11739:2;11962:15;;;;11936:2;11921:18;;;11710:4;12005:185;12019:6;12016:1;12013:13;12005:185;;;12094:13;;12087:21;12080:29;12068:42;;12165:15;;;;12130:12;;;;12041:1;12034:9;12005:185;;;-1:-1:-1;12207:3:23;;11574:642;-1:-1:-1;;;;;;11574:642:23:o;12221:681::-;12392:2;12444:21;;;12514:13;;12417:18;;;12536:22;;;12363:4;;12392:2;12615:15;;;;12589:2;12574:18;;;12363:4;12658:218;12672:6;12669:1;12666:13;12658:218;;;12737:13;;12752:42;12733:62;12721:75;;12851:15;;;;12816:12;;;;12694:1;12687:9;12658:218;;12907:523;12993:6;13001;13009;13062:2;13050:9;13041:7;13037:23;13033:32;13030:52;;;13078:1;13075;13068:12;13030:52;13117:9;13104:23;13136:31;13161:5;13136:31;:::i;:::-;13186:5;-1:-1:-1;13238:2:23;13223:18;;13210:32;;-1:-1:-1;13293:2:23;13278:18;;13265:32;13320:18;13309:30;;13306:50;;;13352:1;13349;13342:12;13306:50;13375:49;13416:7;13407:6;13396:9;13392:22;13375:49;:::i;13435:316::-;13512:6;13520;13528;13581:2;13569:9;13560:7;13556:23;13552:32;13549:52;;;13597:1;13594;13587:12;13549:52;-1:-1:-1;;13620:23:23;;;13690:2;13675:18;;13662:32;;-1:-1:-1;13741:2:23;13726:18;;;13713:32;;13435:316;-1:-1:-1;13435:316:23:o;13756:315::-;13821:6;13829;13882:2;13870:9;13861:7;13857:23;13853:32;13850:52;;;13898:1;13895;13888:12;13850:52;13937:9;13924:23;13956:31;13981:5;13956:31;:::i;:::-;14006:5;-1:-1:-1;14030:35:23;14061:2;14046:18;;14030:35;:::i;:::-;14020:45;;13756:315;;;;;:::o;14076:388::-;14144:6;14152;14205:2;14193:9;14184:7;14180:23;14176:32;14173:52;;;14221:1;14218;14211:12;14173:52;14260:9;14247:23;14279:31;14304:5;14279:31;:::i;:::-;14329:5;-1:-1:-1;14386:2:23;14371:18;;14358:32;14399:33;14358:32;14399:33;:::i;:::-;14451:7;14441:17;;;14076:388;;;;;:::o;14469:734::-;14573:6;14581;14589;14597;14605;14658:3;14646:9;14637:7;14633:23;14629:33;14626:53;;;14675:1;14672;14665:12;14626:53;14714:9;14701:23;14733:31;14758:5;14733:31;:::i;:::-;14783:5;-1:-1:-1;14840:2:23;14825:18;;14812:32;14853:33;14812:32;14853:33;:::i;:::-;14905:7;-1:-1:-1;14959:2:23;14944:18;;14931:32;;-1:-1:-1;15010:2:23;14995:18;;14982:32;;-1:-1:-1;15065:3:23;15050:19;;15037:33;15093:18;15082:30;;15079:50;;;15125:1;15122;15115:12;15079:50;15148:49;15189:7;15180:6;15169:9;15165:22;15148:49;:::i;15208:383::-;15285:6;15293;15301;15354:2;15342:9;15333:7;15329:23;15325:32;15322:52;;;15370:1;15367;15360:12;15322:52;15409:9;15396:23;15428:31;15453:5;15428:31;:::i;:::-;15478:5;15530:2;15515:18;;15502:32;;-1:-1:-1;15581:2:23;15566:18;;;15553:32;;15208:383;-1:-1:-1;;;15208:383:23:o;15596:248::-;15661:6;15669;15722:2;15710:9;15701:7;15697:23;15693:32;15690:52;;;15738:1;15735;15728:12;15690:52;15774:9;15761:23;15751:33;;15803:35;15834:2;15823:9;15819:18;15803:35;:::i;15849:457::-;15936:6;15944;15952;16005:2;15993:9;15984:7;15980:23;15976:32;15973:52;;;16021:1;16018;16011:12;15973:52;16057:9;16044:23;16034:33;;16114:2;16103:9;16099:18;16086:32;16076:42;;16169:2;16158:9;16154:18;16141:32;16196:18;16188:6;16185:30;16182:50;;;16228:1;16225;16218:12;16723:437;16802:1;16798:12;;;;16845;;;16866:61;;16920:4;16912:6;16908:17;16898:27;;16866:61;16973:2;16965:6;16962:14;16942:18;16939:38;16936:218;;;17010:77;17007:1;17000:88;17111:4;17108:1;17101:15;17139:4;17136:1;17129:15;17291:185;17333:3;17371:5;17365:12;17386:52;17431:6;17426:3;17419:4;17412:5;17408:16;17386:52;:::i;:::-;17454:16;;;;;17291:185;-1:-1:-1;;17291:185:23:o;17481:1289::-;17657:3;17686:1;17719:6;17713:13;17749:3;17771:1;17799:9;17795:2;17791:18;17781:28;;17859:2;17848:9;17844:18;17881;17871:61;;17925:4;17917:6;17913:17;17903:27;;17871:61;17951:2;17999;17991:6;17988:14;17968:18;17965:38;17962:222;;;18038:77;18033:3;18026:90;18139:4;18136:1;18129:15;18169:4;18164:3;18157:17;17962:222;18200:18;18227:162;;;;18403:1;18398:320;;;;18193:525;;18227:162;18275:66;18264:9;18260:82;18255:3;18248:95;18372:6;18367:3;18363:16;18356:23;;18227:162;;18398:320;17238:1;17231:14;;;17275:4;17262:18;;18493:1;18507:165;18521:6;18518:1;18515:13;18507:165;;;18599:14;;18586:11;;;18579:35;18642:16;;;;18536:10;;18507:165;;;18511:3;;18701:6;18696:3;18692:16;18685:23;;18193:525;;;;;;;18734:30;18760:3;18752:6;18734:30;:::i;:::-;18727:37;17481:1289;-1:-1:-1;;;;;17481:1289:23:o;18775:184::-;18827:77;18824:1;18817:88;18924:4;18921:1;18914:15;18948:4;18945:1;18938:15;18964:128;19004:3;19035:1;19031:6;19028:1;19025:13;19022:39;;;19041:18;;:::i;:::-;-1:-1:-1;19077:9:23;;18964:128::o;19097:195::-;19136:3;19167:66;19160:5;19157:77;19154:103;;;19237:18;;:::i;:::-;-1:-1:-1;19284:1:23;19273:13;;19097:195::o;21393:184::-;21445:77;21442:1;21435:88;21542:4;21539:1;21532:15;21566:4;21563:1;21556:15;22746:125;22786:4;22814:1;22811;22808:8;22805:34;;;22819:18;;:::i;:::-;-1:-1:-1;22856:9:23;;22746:125::o;23913:228::-;23953:7;24079:1;24011:66;24007:74;24004:1;24001:81;23996:1;23989:9;23982:17;23978:105;23975:131;;;24086:18;;:::i;:::-;-1:-1:-1;24126:9:23;;23913:228::o;24489:280::-;24588:6;24641:2;24629:9;24620:7;24616:23;24612:32;24609:52;;;24657:1;24654;24647:12;24609:52;24689:9;24683:16;24708:31;24733:5;24708:31;:::i;26294:446::-;26527:6;26516:9;26509:25;26570:6;26565:2;26554:9;26550:18;26543:34;26613:6;26608:2;26597:9;26593:18;26586:34;26656:3;26651:2;26640:9;26636:18;26629:31;26490:4;26677:57;26729:3;26718:9;26714:19;26706:6;26677:57;:::i;:::-;26669:65;26294:446;-1:-1:-1;;;;;;26294:446:23:o;26745:274::-;26785:1;26811;26801:189;;26846:77;26843:1;26836:88;26947:4;26944:1;26937:15;26975:4;26972:1;26965:15;26801:189;-1:-1:-1;27004:9:23;;26745:274::o;27024:204::-;27062:3;27098:4;27095:1;27091:12;27130:4;27127:1;27123:12;27165:3;27159:4;27155:14;27150:3;27147:23;27144:49;;;27173:18;;:::i;:::-;27209:13;;27024:204;-1:-1:-1;;;27024:204:23:o;28459:465::-;28716:2;28705:9;28698:21;28679:4;28742:56;28794:2;28783:9;28779:18;28771:6;28742:56;:::i;:::-;28846:9;28838:6;28834:22;28829:2;28818:9;28814:18;28807:50;28874:44;28911:6;28903;28874:44;:::i;29592:861::-;29914:4;29943:42;30024:2;30016:6;30012:15;30001:9;29994:34;30076:2;30068:6;30064:15;30059:2;30048:9;30044:18;30037:43;;30116:3;30111:2;30100:9;30096:18;30089:31;30143:57;30195:3;30184:9;30180:19;30172:6;30143:57;:::i;:::-;30248:9;30240:6;30236:22;30231:2;30220:9;30216:18;30209:50;30282:44;30319:6;30311;30282:44;:::i;:::-;30268:58;;30375:9;30367:6;30363:22;30357:3;30346:9;30342:19;30335:51;30403:44;30440:6;30432;30403:44;:::i;:::-;30395:52;29592:861;-1:-1:-1;;;;;;;;29592:861:23:o;30458:249::-;30527:6;30580:2;30568:9;30559:7;30555:23;30551:32;30548:52;;;30596:1;30593;30586:12;30548:52;30628:9;30622:16;30647:30;30671:5;30647:30;:::i;30712:179::-;30747:3;30789:1;30771:16;30768:23;30765:120;;;30835:1;30832;30829;30814:23;-1:-1:-1;30872:1:23;30866:8;30861:3;30857:18;30765:120;30712:179;:::o;30896:731::-;30935:3;30977:4;30959:16;30956:26;30953:39;;;30896:731;:::o;30953:39::-;31019:2;31013:9;31041:66;31162:2;31144:16;31140:25;31137:1;31131:4;31116:50;31195:4;31189:11;31219:16;31254:18;31325:2;31318:4;31310:6;31306:17;31303:25;31298:2;31290:6;31287:14;31284:45;31281:58;;;31332:5;;;;;30896:731;:::o;31281:58::-;31369:6;31363:4;31359:17;31348:28;;31405:3;31399:10;31432:2;31424:6;31421:14;31418:27;;;31438:5;;;;;;30896:731;:::o;31418:27::-;31522:2;31503:16;31497:4;31493:27;31489:36;31482:4;31473:6;31468:3;31464:16;31460:27;31457:69;31454:82;;;31529:5;;;;;;30896:731;:::o;31454:82::-;31545:57;31596:4;31587:6;31579;31575:19;31571:30;31565:4;31545:57;:::i;:::-;-1:-1:-1;31618:3:23;;30896:731;-1:-1:-1;;;;;30896:731:23:o;32462:595::-;32684:4;32713:42;32794:2;32786:6;32782:15;32771:9;32764:34;32846:2;32838:6;32834:15;32829:2;32818:9;32814:18;32807:43;;32886:6;32881:2;32870:9;32866:18;32859:34;32929:6;32924:2;32913:9;32909:18;32902:34;32973:3;32967;32956:9;32952:19;32945:32;32994:57;33046:3;33035:9;33031:19;33023:6;32994:57;:::i;:::-;32986:65;32462:595;-1:-1:-1;;;;;;;32462:595:23:o;34273:184::-;34325:77;34322:1;34315:88;34422:4;34419:1;34412:15;34446:4;34443:1;34436:15

Swarm Source

ipfs://6045803d74f9576bb8ac4fe6434bb9a221a55ec859d83abe9cbbf1a8b7766460
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.