ETH Price: $3,408.71 (+1.68%)

Token

Hammies (HG)
 

Overview

Max Total Supply

5,985 HG

Holders

1,010

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
aiqiyi.eth
Balance
1 HG
0x0813e1b0a5b1d0d67ceac68696591f5aecc613c7
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:
Hammies

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 11 of 21: Hammies.sol
// ___  ___  ________  _____ ______   _____ ______   ___  _______           ________  ________  _____ ______   _______      
//|\  \|\  \|\   __  \|\   _ \  _   \|\   _ \  _   \|\  \|\  ___ \         |\   ____\|\   __  \|\   _ \  _   \|\  ___ \     
//\ \  \\\  \ \  \|\  \ \  \\\__\ \  \ \  \\\__\ \  \ \  \ \   __/|        \ \  \___|\ \  \|\  \ \  \\\__\ \  \ \   __/|    
// \ \   __  \ \   __  \ \  \\|__| \  \ \  \\|__| \  \ \  \ \  \_|/__       \ \  \  __\ \   __  \ \  \\|__| \  \ \  \_|/__  
//  \ \  \ \  \ \  \ \  \ \  \    \ \  \ \  \    \ \  \ \  \ \  \_|\ \       \ \  \|\  \ \  \ \  \ \  \    \ \  \ \  \_|\ \ 
//   \ \__\ \__\ \__\ \__\ \__\    \ \__\ \__\    \ \__\ \__\ \_______\       \ \_______\ \__\ \__\ \__\    \ \__\ \_______\
//    \|__|\|__|\|__|\|__|\|__|     \|__|\|__|     \|__|\|__|\|_______|        \|_______|\|__|\|__|\|__|     \|__|\|_______|                                                                                                                                                                                                                           

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./ERC721Enumerable.sol";
import "./Ownable.sol";
import "./SafeMath.sol";
import "./Counters.sol";
import "./Strings.sol";
import "./Fluff.sol";
import "./Galaxy.sol";

contract Hammies is ERC721Enumerable, Ownable {
    using SafeMath for uint256;
    using Counters for Counters.Counter;
    using Strings for uint256;
    
    Counters.Counter private _tokenIdTracker;

    Fluff fluff;
    
    uint256 public maxFreeSupply = 888;
    uint256 public constant maxPublicSupply = 4888;
    uint256 public constant maxTotalSupply = 8888;
    uint256 public constant mintPrice = 0.06 ether;
    uint256 public constant maxPerTx = 10;
    uint256 public constant maxFreePerWallet = 10;

    address public constant dev1Address = 0xcd2367Fcfbd8bf8eF87C98fC53Cc2EA27437f6EE;
    address public constant dev2Address = 0x2E824997ACE675F5BdB0d56121Aa04B2599BDa8B;

    bool mintActive = false;
    bool public fluffMinting = false;
    
    mapping(address => uint256) public freeMintsClaimed; //Track free mints claimed per wallet
    
    string public baseTokenURI;

    constructor() ERC721("Hammies", "HG") {}
    
    //-----------------------------------------------------------------------------//
    //------------------------------Mint Logic-------------------------------------//
    //-----------------------------------------------------------------------------//
    
    //Resume/pause Public Sale
    function toggleMint() public onlyOwner {
        mintActive = !mintActive;
    }

    //Public Mint
    function mint(uint256 _count) public payable {
        uint256 total = _totalSupply();
        require(mintActive, "Sale has not begun");
        require(total + _count <= maxPublicSupply, "No hammies left");
        require(_count <= maxPerTx, "10 max per tx");
        require(msg.value >= price(_count), "Not enough eth sent");

        for (uint256 i = 0; i < _count; i++) {
            _mintHammie(msg.sender);
        }
    }
    
    //Free Mint for first 888
    function freeMint(uint256 _count) public {
        uint256 total = _totalSupply();
        require(mintActive, "Public Sale is not active");
        require(total + _count <= maxFreeSupply, "No more free hammies");
        require(_count + freeMintsClaimed[msg.sender] <= maxFreePerWallet, "Only 10 free mints per wallet");
        require(_count <= maxPerTx, "10 max per tx");

        for (uint256 i = 0; i < _count; i++) {
            freeMintsClaimed[msg.sender]++;
            _mintHammie(msg.sender);
        }
    }
    
    //Public Mint until 4888
    function mintHammieForFluff() public {
        uint256 total = _totalSupply();
        require(total < maxTotalSupply, "No Hammies left");
        require(fluffMinting, "Minting with $fluff has not begun");
        fluff.burn(msg.sender, getFluffCost(total));
        _mintHammie(msg.sender);
    }
    
    function getFluffCost(uint256 totalSupply) internal pure returns (uint256 cost){
        if (totalSupply < 5888)
            return 100;
        else if (totalSupply < 6887)
            return 200;
        else if (totalSupply < 7887)
            return 400;
        else if (totalSupply < 8887)
            return 800;
    }
    
    //Mint Hammie
    function _mintHammie(address _to) private {
        uint id = _tokenIdTracker.current();
        _tokenIdTracker.increment();
        _safeMint(_to, id);
    }

    //Function to get price of minting a hammie
    function price(uint256 _count) public pure returns (uint256) {
        return mintPrice.mul(_count);
    }
    
    //-----------------------------------------------------------------------------//
    //---------------------------Admin & Internal Logic----------------------------//
    //-----------------------------------------------------------------------------//

    //Set address for $Fluff
    function setFluffAddress(address fluffAddr) external onlyOwner {
        fluff = Fluff(fluffAddr);
    }
    
    //Internal URI function
    function _baseURI() internal view virtual override returns (string memory) {
        return baseTokenURI;
    }

    //Start/Stop minting hammies for $fluff
    function toggleFluffMinting() public onlyOwner {
        fluffMinting = !fluffMinting;
    }
    
    //Set URI for metadata
    function setBaseURI(string memory baseURI) public onlyOwner {
        baseTokenURI = baseURI;
    }
    
    //Withdraw from contract
    function withdrawAll() public onlyOwner {
        uint256 balance = address(this).balance;
        uint256 dev1Share = balance.mul(50).div(100);
        uint256 dev2Share = balance.mul(50).div(100);

        require(balance > 0);
        _withdraw(dev1Address, dev1Share);
        _withdraw(dev2Address, dev2Share);
    }

    //Internal withdraw
    function _withdraw(address _address, uint256 _amount) private {
        (bool success, ) = _address.call{value: _amount}("");
        require(success, "Transfer failed.");
    }
    
    //Return total supply of hammies
    function _totalSupply() public view returns (uint) {
        return _tokenIdTracker.current();
    }
}

File 1 of 21: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 2 of 21: Context.sol
// SPDX-License-Identifier: MIT

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 21: Counters.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 4 of 21: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 5 of 21: ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount
    ) 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, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 6 of 21: ERC721.sol
// SPDX-License-Identifier: MIT

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 overriden 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 {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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 || getApproved(tokenId) == spender || isApprovedForAll(owner, 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);
    }

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

    /**
     * @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 of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(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 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 {}
}

File 7 of 21: ERC721Burnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./Context.sol";

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

File 8 of 21: ERC721Enumerable.sol
// SPDX-License-Identifier: MIT

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 21: Fluff.sol
// ________ ___       ___  ___  ________ ________ 
//|\  _____\\  \     |\  \|\  \|\  _____\\  _____\
//\ \  \__/\ \  \    \ \  \\\  \ \  \__/\ \  \__/ 
// \ \   __\\ \  \    \ \  \\\  \ \   __\\ \   __\
//  \ \  \_| \ \  \____\ \  \\\  \ \  \_| \ \  \_|
//   \ \__\   \ \_______\ \_______\ \__\   \ \__\ 
//    \|__|    \|_______|\|_______|\|__|    \|__| 
                                                
                                                
                                                
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ERC20.sol";
import "./Ownable.sol";

contract Fluff is ERC20, Ownable {
    address public hammieAddress;
    address public galaxyAddress;
    
    mapping(address => bool) public allowedAddresses;

    constructor() ERC20("Fluff", "FLF") {}
    
    function setHammieAddress(address hammieAddr) external onlyOwner {
        hammieAddress = hammieAddr;
    }
    
    function setGalaxyAddress(address galaxyAddr) external onlyOwner {
        galaxyAddress = galaxyAddr;
    }
    
    function burn(address user, uint256 amount) external {
        require(msg.sender == galaxyAddress || msg.sender == hammieAddress, "Address not authorized");
        _burn(user, amount);
    }
    
    function mint(address to, uint256 value) external {
        require(msg.sender == galaxyAddress || msg.sender == hammieAddress, "Address not authorized");
        _mint(to, value);
    }
}

File 10 of 21: Galaxy.sol
// ________  ________  ___       ________     ___    ___ ___    ___ 
//|\   ____\|\   __  \|\  \     |\   __  \   |\  \  /  /|\  \  /  /|
//\ \  \___|\ \  \|\  \ \  \    \ \  \|\  \  \ \  \/  / | \  \/  / /
// \ \  \  __\ \   __  \ \  \    \ \   __  \  \ \    / / \ \    / / 
//  \ \  \|\  \ \  \ \  \ \  \____\ \  \ \  \  /     \/   \/  /  /  
//   \ \_______\ \__\ \__\ \_______\ \__\ \__\/  /\   \ __/  / /    
//    \|_______|\|__|\|__|\|_______|\|__|\|__/__/ /\ __\\___/ /     
//                                           |__|/ \|__\|___|/      
                                                                  
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Ownable.sol";
import "./SafeMath.sol";
import "./IERC721Receiver.sol";
import "./Hammies.sol";
import "./Fluff.sol";

contract Galaxy is Ownable, IERC721Receiver {
    using SafeMath for uint256;
    
    //Establish interface for Hammies
    Hammies hammies;
    
    //Establish interface for $Fluff
    Fluff fluff;

    event HammieStolen(address previousOwner, address newOwner, uint256 tokenId);
    event HammieStaked(address owner, uint256 tokenId, uint256 status);
    event HammieClaimed(address owner, uint256 tokenId);
    
    //Maps tokenId to owner
    mapping(uint256 => address) public ownerById;
    /*Maps Status to tokenId
      Status is as follows:
        0 - Unstaked
        1 - Adventurer
        2 - Pirate
        3 - Salvager
    */
    mapping(uint256 => uint256) public statusById;
    //Maps tokenId to time staked
    mapping(uint256 => uint256) public timeStaked;
    //Amount of $Fluff stolen by Pirate while staked
    mapping(uint256 => uint256) public fluffStolen;
    
    //Daily $Fluff earned by adventurers
    uint256 public adventuringFluffRate = 100 ether;
    //Total number of adventurers staked
    uint256 public totalAdventurersStaked = 0;
    //Percent of $Fluff earned by adventurers that is kept
    uint256 public adventurerShare = 50;
    
    //Percent of $Fluff earned by adventurers that is stolen by pirates
    uint256 public pirateShare = 50;
    //5% chance a pirate gets lost each time it is unstaked
    uint256 public chancePirateGetsLost = 5;
    
    //Store tokenIds of all pirates staked
    uint256[] public piratesStaked;
    //Store tokenIds of all salvagers staked
    uint256[] public salvagersStaked;
    
    //1 day lock on staking
    uint256 public minStakeTime = 1 days;
    
    bool public staking = false;
    
    constructor(){}
    
    //-----------------------------------------------------------------------------//
    //------------------------------Staking----------------------------------------//
    //-----------------------------------------------------------------------------//
    
    /*sends any number of Hammies to the galaxy
        ids -> list of hammie ids to stake
        Status == 1 -> Adventurer
        Status == 2 -> Pirate
        Status == 3 -> Salvager
    */
    function sendManyToGalaxy(uint256[] calldata ids, uint256 status) external {
        for(uint256 i = 0; i < ids.length; i++){
            require(hammies.ownerOf(ids[i]) == msg.sender, "Not your Hammie");
            require(staking, "Staking is paused");

            statusById[ids[i]] = status;
            ownerById[ids[i]] = msg.sender;
            timeStaked[ids[i]] = block.timestamp;

            emit HammieStaked(msg.sender, ids[i], status);
            hammies.transferFrom(msg.sender, address(this), ids[i]);

            if (status == 1)
                totalAdventurersStaked++;
            else if (status == 2){
                piratesStaked.push(ids[i]);
            }
            else if (status == 3){
                salvagersStaked.push(ids[i]);
            }
        }
    }
    
    function unstakeManyHammies(uint256[] calldata ids) external {
        for(uint256 i = 0; i < ids.length; i++){
            require(ownerById[ids[i]] == msg.sender, "Not your Hammie");
            require(hammies.ownerOf(ids[i]) == address(this), "Hammie must be staked in order to claim");
            require(staking, "Staking is paused");
            require(block.timestamp - timeStaked[ids[i]]>= minStakeTime, "1 day stake lock");

            _claim(msg.sender, ids[i]);

            if (statusById[ids[i]] == 1){       
                totalAdventurersStaked--;
            }
            else if (statusById[ids[i]] == 2){
                for (uint256 j = 0; j < piratesStaked.length; j++){
                    if (piratesStaked[j] == ids[i]){
                        piratesStaked[j] = piratesStaked[piratesStaked.length-1];
                        piratesStaked.pop();
                    }
                }
                
            }
            else if (statusById[ids[i]] == 3){
                for (uint256 j = 0; j < salvagersStaked.length; j++){
                    if (salvagersStaked[j] == ids[i]){
                        salvagersStaked[j] = salvagersStaked[salvagersStaked.length-1];
                        salvagersStaked.pop();
                    }
                } 
            }

            emit HammieClaimed(address(this), ids[i]);
            hammies.safeTransferFrom(address(this), ownerById[ids[i]], ids[i]);
            statusById[ids[i]] = 0;
        }
    }

    function claimManyHammies(uint256[] calldata ids) external {
        for(uint256 i = 0; i < ids.length; i++){
            require(ownerById[ids[i]] == msg.sender, "Not your hammie");
            require(hammies.ownerOf(ids[i]) == address(this), "Hammie must be staked in order to claim");
            require(staking, "Staking is paused");
            
            _claim(msg.sender, ids[i]);
            emit HammieClaimed(address(this), ids[i]);
        }
    }
    
    function _claim(address owner, uint256 tokenId) internal {
        if (statusById[tokenId] == 1){
            if(piratesStaked.length > 0){
                fluff.mint(owner, getPendingFluff(tokenId).mul(adventurerShare).div(100));
                distributeAmongstPirates(getPendingFluff(tokenId).mul(pirateShare).div(100));
            }
            else {
                fluff.mint(owner, getPendingFluff(tokenId));
            }            
        }
        else if (statusById[tokenId] == 2){
            uint256 roll = randomIntInRange(tokenId, 100);
            if(roll > chancePirateGetsLost || salvagersStaked.length == 0){
                fluff.mint(owner, fluffStolen[tokenId]);
                fluffStolen[tokenId] = 0;
            } else{
                getNewOwnerForPirate(roll, tokenId);
            }
        }
        timeStaked[tokenId] = block.timestamp;
    }
    
    //Passive earning of $Fluff, 100 $Fluff per day
    function getPendingFluff(uint256 id) internal view returns(uint256) {
        return (block.timestamp - timeStaked[id]) * 100 ether / 1 days;
    }
    
    //Distribute stolen $Fluff accross all staked pirates
    function distributeAmongstPirates(uint256 amount) internal {
        for(uint256 i = 0; i < piratesStaked.length; i++){
            fluffStolen[piratesStaked[i]] += amount.div(piratesStaked.length);
        }
    }
    
    //Returns a pseudo-random integer between 0 - max
    function randomIntInRange(uint256 seed, uint256 max) internal view returns (uint256) {
        return uint256(keccak256(abi.encodePacked(
            tx.origin,
            blockhash(block.number - 1),
            block.timestamp,
            seed
        ))) % max;
    }
    
    
    //Return new owner of lost pirate from current salvagers
    function getNewOwnerForPirate(uint256 seed, uint256 tokenId) internal{
        uint256 roll = randomIntInRange(seed, salvagersStaked.length);
        emit HammieStolen(ownerById[tokenId], ownerById[salvagersStaked[roll]], tokenId);
        ownerById[tokenId] = ownerById[salvagersStaked[roll]];
        fluff.mint(ownerById[tokenId], fluffStolen[tokenId]);
        fluffStolen[tokenId] = 0;
    }
      
    function getTotalSalvagersStaked() public view returns (uint256) {
        return salvagersStaked.length;
    }

    function getTotalPiratesStaked() public view returns (uint256) {
        return piratesStaked.length;
    }

    //Set address for Hammies
    function setHammieAddress(address hammieAddr) external onlyOwner {
        hammies = Hammies(hammieAddr);
    }
    
    //Set address for $Fluff
    function setFluffAddress(address fluffAddr) external onlyOwner {
        fluff = Fluff(fluffAddr);
    }
    
    //Start/Stop staking
    function toggleStaking() public onlyOwner {
        staking = !staking;
    }

    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external pure override returns (bytes4) {
      return IERC721Receiver.onERC721Received.selector;
    }
}

File 12 of 21: IERC165.sol
// SPDX-License-Identifier: MIT

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 21: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 14 of 21: IERC20Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 15 of 21: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 16 of 21: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 17 of 21: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

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 18 of 21: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 19 of 21: Ownable.sol
// SPDX-License-Identifier: MIT

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() {
        _setOwner(_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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 20 of 21: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 21 of 21: Strings.sol
// SPDX-License-Identifier: MIT

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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dev1Address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dev2Address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fluffMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"freeMintsClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"maxFreePerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFreeSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPublicSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintHammieForFluff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fluffAddr","type":"address"}],"name":"setFluffAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleFluffMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052610378600d556000600e60006101000a81548160ff0219169083151502179055506000600e60016101000a81548160ff0219169083151502179055503480156200004d57600080fd5b506040518060400160405280600781526020017f48616d6d696573000000000000000000000000000000000000000000000000008152506040518060400160405280600281526020017f48470000000000000000000000000000000000000000000000000000000000008152508160009080519060200190620000d2929190620001e2565b508060019080519060200190620000eb929190620001e2565b5050506200010e620001026200011460201b60201c565b6200011c60201b60201c565b620002f7565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001f09062000292565b90600052602060002090601f01602090048101928262000214576000855562000260565b82601f106200022f57805160ff191683800117855562000260565b8280016001018555821562000260579182015b828111156200025f57825182559160200191906001019062000242565b5b5090506200026f919062000273565b5090565b5b808211156200028e57600081600090555060010162000274565b5090565b60006002820490506001821680620002ab57607f821691505b60208210811415620002c257620002c1620002c8565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b614a2f80620003076000396000f3fe60806040526004361061023b5760003560e01c80636817c76c1161012e578063a7027357116100ab578063d547cfb71161006f578063d547cfb714610840578063e985e9c51461086b578063f2fde38b146108a8578063f968adbe146108d1578063fff5982b146108fc5761023b565b8063a70273571461076f578063b7d32a7e1461079a578063b88d4fde146107c3578063c87b56dd146107ec578063d3dd5fe0146108295761023b565b80638da5cb5b116100f25780638da5cb5b146106bd57806395d89b41146106e8578063990b21ec14610713578063a0712d681461072a578063a22cb465146107465761023b565b80636817c76c146105fe57806370a0823114610629578063715018a6146106665780637c928fe91461067d578063853828b6146106a65761023b565b806326a74d8e116101bc578063475133341161018057806347513334146105195780634f6ccce71461054457806355f804b3146105815780635d3bb979146105aa5780636352211e146105c15761023b565b806326a74d8e146104325780632ab4d0521461045d5780632f745c59146104885780633eaaf86b146104c557806342842e0e146104f05761023b565b80630dad00d8116102035780630dad00d81461034b57806318160ddd1461037657806320c09e24146103a157806323b872dd146103cc57806326a49e37146103f55761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a85780630865704c146102e5578063095ea7b314610322575b600080fd5b34801561024c57600080fd5b50610267600480360381019061026291906133f0565b610927565b6040516102749190613a50565b60405180910390f35b34801561028957600080fd5b506102926109a1565b60405161029f9190613a6b565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613493565b610a33565b6040516102dc91906139c0565b60405180910390f35b3480156102f157600080fd5b5061030c6004803603810190610307919061322d565b610ab8565b6040516103199190613e0d565b60405180910390f35b34801561032e57600080fd5b50610349600480360381019061034491906133b0565b610ad0565b005b34801561035757600080fd5b50610360610be8565b60405161036d9190613a50565b60405180910390f35b34801561038257600080fd5b5061038b610bfb565b6040516103989190613e0d565b60405180910390f35b3480156103ad57600080fd5b506103b6610c08565b6040516103c391906139c0565b60405180910390f35b3480156103d857600080fd5b506103f360048036038101906103ee919061329a565b610c20565b005b34801561040157600080fd5b5061041c60048036038101906104179190613493565b610c80565b6040516104299190613e0d565b60405180910390f35b34801561043e57600080fd5b50610447610ca3565b6040516104549190613e0d565b60405180910390f35b34801561046957600080fd5b50610472610ca9565b60405161047f9190613e0d565b60405180910390f35b34801561049457600080fd5b506104af60048036038101906104aa91906133b0565b610caf565b6040516104bc9190613e0d565b60405180910390f35b3480156104d157600080fd5b506104da610d54565b6040516104e79190613e0d565b60405180910390f35b3480156104fc57600080fd5b506105176004803603810190610512919061329a565b610d65565b005b34801561052557600080fd5b5061052e610d85565b60405161053b9190613e0d565b60405180910390f35b34801561055057600080fd5b5061056b60048036038101906105669190613493565b610d8b565b6040516105789190613e0d565b60405180910390f35b34801561058d57600080fd5b506105a860048036038101906105a3919061344a565b610dfc565b005b3480156105b657600080fd5b506105bf610e92565b005b3480156105cd57600080fd5b506105e860048036038101906105e39190613493565b610fd4565b6040516105f591906139c0565b60405180910390f35b34801561060a57600080fd5b50610613611086565b6040516106209190613e0d565b60405180910390f35b34801561063557600080fd5b50610650600480360381019061064b919061322d565b611091565b60405161065d9190613e0d565b60405180910390f35b34801561067257600080fd5b5061067b611149565b005b34801561068957600080fd5b506106a4600480360381019061069f9190613493565b6111d1565b005b3480156106b257600080fd5b506106bb6113cf565b005b3480156106c957600080fd5b506106d26114f4565b6040516106df91906139c0565b60405180910390f35b3480156106f457600080fd5b506106fd61151e565b60405161070a9190613a6b565b60405180910390f35b34801561071f57600080fd5b506107286115b0565b005b610744600480360381019061073f9190613493565b611658565b005b34801561075257600080fd5b5061076d60048036038101906107689190613370565b6117be565b005b34801561077b57600080fd5b5061078461193f565b6040516107919190613e0d565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc919061322d565b611944565b005b3480156107cf57600080fd5b506107ea60048036038101906107e591906132ed565b611a04565b005b3480156107f857600080fd5b50610813600480360381019061080e9190613493565b611a66565b6040516108209190613a6b565b60405180910390f35b34801561083557600080fd5b5061083e611b0d565b005b34801561084c57600080fd5b50610855611bb5565b6040516108629190613a6b565b60405180910390f35b34801561087757600080fd5b50610892600480360381019061088d919061325a565b611c43565b60405161089f9190613a50565b60405180910390f35b3480156108b457600080fd5b506108cf60048036038101906108ca919061322d565b611cd7565b005b3480156108dd57600080fd5b506108e6611dcf565b6040516108f39190613e0d565b60405180910390f35b34801561090857600080fd5b50610911611dd4565b60405161091e91906139c0565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061099a575061099982611dec565b5b9050919050565b6060600080546109b0906140c8565b80601f01602080910402602001604051908101604052809291908181526020018280546109dc906140c8565b8015610a295780601f106109fe57610100808354040283529160200191610a29565b820191906000526020600020905b815481529060010190602001808311610a0c57829003601f168201915b5050505050905090565b6000610a3e82611ece565b610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490613c8d565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600f6020528060005260406000206000915090505481565b6000610adb82610fd4565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390613d4d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b6b611f3a565b73ffffffffffffffffffffffffffffffffffffffff161480610b9a5750610b9981610b94611f3a565b611c43565b5b610bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd090613bed565b60405180910390fd5b610be38383611f42565b505050565b600e60019054906101000a900460ff1681565b6000600880549050905090565b732e824997ace675f5bdb0d56121aa04b2599bda8b81565b610c31610c2b611f3a565b82611ffb565b610c70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6790613dcd565b60405180910390fd5b610c7b8383836120d9565b505050565b6000610c9c8266d529ae9e86000061233590919063ffffffff16565b9050919050565b61131881565b6122b881565b6000610cba83611091565b8210610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf290613a8d565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610d60600b61234b565b905090565b610d8083838360405180602001604052806000815250611a04565b505050565b600d5481565b6000610d95610bfb565b8210610dd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dcd90613ded565b60405180910390fd5b60088281548110610dea57610de9614261565b5b90600052602060002001549050919050565b610e04611f3a565b73ffffffffffffffffffffffffffffffffffffffff16610e226114f4565b73ffffffffffffffffffffffffffffffffffffffff1614610e78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6f90613cad565b60405180910390fd5b8060109080519060200190610e8e929190613041565b5050565b6000610e9c610d54565b90506122b88110610ee2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed990613aed565b60405180910390fd5b600e60019054906101000a900460ff16610f31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2890613d8d565b60405180910390fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac33610f7984612359565b6040518363ffffffff1660e01b8152600401610f96929190613a27565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd1336123af565b50565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561107d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107490613c2d565b60405180910390fd5b80915050919050565b66d529ae9e86000081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f990613c0d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611151611f3a565b73ffffffffffffffffffffffffffffffffffffffff1661116f6114f4565b73ffffffffffffffffffffffffffffffffffffffff16146111c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bc90613cad565b60405180910390fd5b6111cf60006123d5565b565b60006111db610d54565b9050600e60009054906101000a900460ff1661122c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122390613b2d565b60405180910390fd5b600d54828261123b9190613efd565b111561127c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127390613d0d565b60405180910390fd5b600a600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054836112c99190613efd565b111561130a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130190613c6d565b60405180910390fd5b600a82111561134e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134590613d6d565b60405180910390fd5b60005b828110156113ca57600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906113a99061412b565b91905055506113b7336123af565b80806113c29061412b565b915050611351565b505050565b6113d7611f3a565b73ffffffffffffffffffffffffffffffffffffffff166113f56114f4565b73ffffffffffffffffffffffffffffffffffffffff161461144b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144290613cad565b60405180910390fd5b60004790506000611479606461146b60328561233590919063ffffffff16565b61249b90919063ffffffff16565b905060006114a4606461149660328661233590919063ffffffff16565b61249b90919063ffffffff16565b9050600083116114b357600080fd5b6114d173cd2367fcfbd8bf8ef87c98fc53cc2ea27437f6ee836124b1565b6114ef732e824997ace675f5bdb0d56121aa04b2599bda8b826124b1565b505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461152d906140c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611559906140c8565b80156115a65780601f1061157b576101008083540402835291602001916115a6565b820191906000526020600020905b81548152906001019060200180831161158957829003601f168201915b5050505050905090565b6115b8611f3a565b73ffffffffffffffffffffffffffffffffffffffff166115d66114f4565b73ffffffffffffffffffffffffffffffffffffffff161461162c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162390613cad565b60405180910390fd5b600e60019054906101000a900460ff1615600e60016101000a81548160ff021916908315150217905550565b6000611662610d54565b9050600e60009054906101000a900460ff166116b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116aa90613b4d565b60405180910390fd5b61131882826116c29190613efd565b1115611703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fa90613bad565b60405180910390fd5b600a821115611747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173e90613d6d565b60405180910390fd5b61175082610c80565b341015611792576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178990613ced565b60405180910390fd5b60005b828110156117b9576117a6336123af565b80806117b19061412b565b915050611795565b505050565b6117c6611f3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611834576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182b90613b8d565b60405180910390fd5b8060056000611841611f3a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166118ee611f3a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516119339190613a50565b60405180910390a35050565b600a81565b61194c611f3a565b73ffffffffffffffffffffffffffffffffffffffff1661196a6114f4565b73ffffffffffffffffffffffffffffffffffffffff16146119c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b790613cad565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611a15611a0f611f3a565b83611ffb565b611a54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4b90613dcd565b60405180910390fd5b611a6084848484612562565b50505050565b6060611a7182611ece565b611ab0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa790613d2d565b60405180910390fd5b6000611aba6125be565b90506000815111611ada5760405180602001604052806000815250611b05565b80611ae484612650565b604051602001611af5929190613987565b6040516020818303038152906040525b915050919050565b611b15611f3a565b73ffffffffffffffffffffffffffffffffffffffff16611b336114f4565b73ffffffffffffffffffffffffffffffffffffffff1614611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8090613cad565b60405180910390fd5b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b60108054611bc2906140c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611bee906140c8565b8015611c3b5780601f10611c1057610100808354040283529160200191611c3b565b820191906000526020600020905b815481529060010190602001808311611c1e57829003601f168201915b505050505081565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611cdf611f3a565b73ffffffffffffffffffffffffffffffffffffffff16611cfd6114f4565b73ffffffffffffffffffffffffffffffffffffffff1614611d53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4a90613cad565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611dc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dba90613acd565b60405180910390fd5b611dcc816123d5565b50565b600a81565b73cd2367fcfbd8bf8ef87c98fc53cc2ea27437f6ee81565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611eb757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ec75750611ec6826127b1565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611fb583610fd4565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061200682611ece565b612045576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203c90613bcd565b60405180910390fd5b600061205083610fd4565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806120bf57508373ffffffffffffffffffffffffffffffffffffffff166120a784610a33565b73ffffffffffffffffffffffffffffffffffffffff16145b806120d057506120cf8185611c43565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166120f982610fd4565b73ffffffffffffffffffffffffffffffffffffffff161461214f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214690613ccd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156121bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121b690613b6d565b60405180910390fd5b6121ca83838361281b565b6121d5600082611f42565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546122259190613fde565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461227c9190613efd565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600081836123439190613f84565b905092915050565b600081600001549050919050565b600061170082101561236e57606490506123aa565b611ae78210156123815760c890506123aa565b611ecf8210156123955761019090506123aa565b6122b78210156123a95761032090506123aa565b5b919050565b60006123bb600b61234b565b90506123c7600b61292f565b6123d18282612945565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081836124a99190613f53565b905092915050565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516124d7906139ab565b60006040518083038185875af1925050503d8060008114612514576040519150601f19603f3d011682016040523d82523d6000602084013e612519565b606091505b505090508061255d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255490613dad565b60405180910390fd5b505050565b61256d8484846120d9565b61257984848484612963565b6125b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125af90613aad565b60405180910390fd5b50505050565b6060601080546125cd906140c8565b80601f01602080910402602001604051908101604052809291908181526020018280546125f9906140c8565b80156126465780601f1061261b57610100808354040283529160200191612646565b820191906000526020600020905b81548152906001019060200180831161262957829003601f168201915b5050505050905090565b60606000821415612698576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506127ac565b600082905060005b600082146126ca5780806126b39061412b565b915050600a826126c39190613f53565b91506126a0565b60008167ffffffffffffffff8111156126e6576126e5614290565b5b6040519080825280601f01601f1916602001820160405280156127185781602001600182028036833780820191505090505b5090505b600085146127a5576001826127319190613fde565b9150600a856127409190614174565b603061274c9190613efd565b60f81b81838151811061276257612761614261565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561279e9190613f53565b945061271c565b8093505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612826838383612afa565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156128695761286481612aff565b6128a8565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146128a7576128a68382612b48565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156128eb576128e681612cb5565b61292a565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612929576129288282612d86565b5b5b505050565b6001816000016000828254019250508190555050565b61295f828260405180602001604052806000815250612e05565b5050565b60006129848473ffffffffffffffffffffffffffffffffffffffff16612e60565b15612aed578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026129ad611f3a565b8786866040518563ffffffff1660e01b81526004016129cf94939291906139db565b602060405180830381600087803b1580156129e957600080fd5b505af1925050508015612a1a57506040513d601f19601f82011682018060405250810190612a17919061341d565b60015b612a9d573d8060008114612a4a576040519150601f19603f3d011682016040523d82523d6000602084013e612a4f565b606091505b50600081511415612a95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a8c90613aad565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612af2565b600190505b949350505050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b5584611091565b612b5f9190613fde565b9050600060076000848152602001908152602001600020549050818114612c44576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050612cc99190613fde565b9050600060096000848152602001908152602001600020549050600060088381548110612cf957612cf8614261565b5b906000526020600020015490508060088381548110612d1b57612d1a614261565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480612d6a57612d69614232565b5b6001900381819060005260206000200160009055905550505050565b6000612d9183611091565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b612e0f8383612e73565b612e1c6000848484612963565b612e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5290613aad565b60405180910390fd5b505050565b600080823b905060008111915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ee3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eda90613c4d565b60405180910390fd5b612eec81611ece565b15612f2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f2390613b0d565b60405180910390fd5b612f386000838361281b565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612f889190613efd565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b82805461304d906140c8565b90600052602060002090601f01602090048101928261306f57600085556130b6565b82601f1061308857805160ff19168380011785556130b6565b828001600101855582156130b6579182015b828111156130b557825182559160200191906001019061309a565b5b5090506130c391906130c7565b5090565b5b808211156130e05760008160009055506001016130c8565b5090565b60006130f76130f284613e4d565b613e28565b905082815260208101848484011115613113576131126142c4565b5b61311e848285614086565b509392505050565b600061313961313484613e7e565b613e28565b905082815260208101848484011115613155576131546142c4565b5b613160848285614086565b509392505050565b6000813590506131778161499d565b92915050565b60008135905061318c816149b4565b92915050565b6000813590506131a1816149cb565b92915050565b6000815190506131b6816149cb565b92915050565b600082601f8301126131d1576131d06142bf565b5b81356131e18482602086016130e4565b91505092915050565b600082601f8301126131ff576131fe6142bf565b5b813561320f848260208601613126565b91505092915050565b600081359050613227816149e2565b92915050565b600060208284031215613243576132426142ce565b5b600061325184828501613168565b91505092915050565b60008060408385031215613271576132706142ce565b5b600061327f85828601613168565b925050602061329085828601613168565b9150509250929050565b6000806000606084860312156132b3576132b26142ce565b5b60006132c186828701613168565b93505060206132d286828701613168565b92505060406132e386828701613218565b9150509250925092565b60008060008060808587031215613307576133066142ce565b5b600061331587828801613168565b945050602061332687828801613168565b935050604061333787828801613218565b925050606085013567ffffffffffffffff811115613358576133576142c9565b5b613364878288016131bc565b91505092959194509250565b60008060408385031215613387576133866142ce565b5b600061339585828601613168565b92505060206133a68582860161317d565b9150509250929050565b600080604083850312156133c7576133c66142ce565b5b60006133d585828601613168565b92505060206133e685828601613218565b9150509250929050565b600060208284031215613406576134056142ce565b5b600061341484828501613192565b91505092915050565b600060208284031215613433576134326142ce565b5b6000613441848285016131a7565b91505092915050565b6000602082840312156134605761345f6142ce565b5b600082013567ffffffffffffffff81111561347e5761347d6142c9565b5b61348a848285016131ea565b91505092915050565b6000602082840312156134a9576134a86142ce565b5b60006134b784828501613218565b91505092915050565b6134c981614012565b82525050565b6134d881614024565b82525050565b60006134e982613eaf565b6134f38185613ec5565b9350613503818560208601614095565b61350c816142d3565b840191505092915050565b600061352282613eba565b61352c8185613ee1565b935061353c818560208601614095565b613545816142d3565b840191505092915050565b600061355b82613eba565b6135658185613ef2565b9350613575818560208601614095565b80840191505092915050565b600061358e602b83613ee1565b9150613599826142e4565b604082019050919050565b60006135b1603283613ee1565b91506135bc82614333565b604082019050919050565b60006135d4602683613ee1565b91506135df82614382565b604082019050919050565b60006135f7600f83613ee1565b9150613602826143d1565b602082019050919050565b600061361a601c83613ee1565b9150613625826143fa565b602082019050919050565b600061363d601983613ee1565b915061364882614423565b602082019050919050565b6000613660601283613ee1565b915061366b8261444c565b602082019050919050565b6000613683602483613ee1565b915061368e82614475565b604082019050919050565b60006136a6601983613ee1565b91506136b1826144c4565b602082019050919050565b60006136c9600f83613ee1565b91506136d4826144ed565b602082019050919050565b60006136ec602c83613ee1565b91506136f782614516565b604082019050919050565b600061370f603883613ee1565b915061371a82614565565b604082019050919050565b6000613732602a83613ee1565b915061373d826145b4565b604082019050919050565b6000613755602983613ee1565b915061376082614603565b604082019050919050565b6000613778602083613ee1565b915061378382614652565b602082019050919050565b600061379b601d83613ee1565b91506137a68261467b565b602082019050919050565b60006137be602c83613ee1565b91506137c9826146a4565b604082019050919050565b60006137e1602083613ee1565b91506137ec826146f3565b602082019050919050565b6000613804602983613ee1565b915061380f8261471c565b604082019050919050565b6000613827601383613ee1565b91506138328261476b565b602082019050919050565b600061384a601483613ee1565b915061385582614794565b602082019050919050565b600061386d602f83613ee1565b9150613878826147bd565b604082019050919050565b6000613890602183613ee1565b915061389b8261480c565b604082019050919050565b60006138b3600d83613ee1565b91506138be8261485b565b602082019050919050565b60006138d6600083613ed6565b91506138e182614884565b600082019050919050565b60006138f9602183613ee1565b915061390482614887565b604082019050919050565b600061391c601083613ee1565b9150613927826148d6565b602082019050919050565b600061393f603183613ee1565b915061394a826148ff565b604082019050919050565b6000613962602c83613ee1565b915061396d8261494e565b604082019050919050565b6139818161407c565b82525050565b60006139938285613550565b915061399f8284613550565b91508190509392505050565b60006139b6826138c9565b9150819050919050565b60006020820190506139d560008301846134c0565b92915050565b60006080820190506139f060008301876134c0565b6139fd60208301866134c0565b613a0a6040830185613978565b8181036060830152613a1c81846134de565b905095945050505050565b6000604082019050613a3c60008301856134c0565b613a496020830184613978565b9392505050565b6000602082019050613a6560008301846134cf565b92915050565b60006020820190508181036000830152613a858184613517565b905092915050565b60006020820190508181036000830152613aa681613581565b9050919050565b60006020820190508181036000830152613ac6816135a4565b9050919050565b60006020820190508181036000830152613ae6816135c7565b9050919050565b60006020820190508181036000830152613b06816135ea565b9050919050565b60006020820190508181036000830152613b268161360d565b9050919050565b60006020820190508181036000830152613b4681613630565b9050919050565b60006020820190508181036000830152613b6681613653565b9050919050565b60006020820190508181036000830152613b8681613676565b9050919050565b60006020820190508181036000830152613ba681613699565b9050919050565b60006020820190508181036000830152613bc6816136bc565b9050919050565b60006020820190508181036000830152613be6816136df565b9050919050565b60006020820190508181036000830152613c0681613702565b9050919050565b60006020820190508181036000830152613c2681613725565b9050919050565b60006020820190508181036000830152613c4681613748565b9050919050565b60006020820190508181036000830152613c668161376b565b9050919050565b60006020820190508181036000830152613c868161378e565b9050919050565b60006020820190508181036000830152613ca6816137b1565b9050919050565b60006020820190508181036000830152613cc6816137d4565b9050919050565b60006020820190508181036000830152613ce6816137f7565b9050919050565b60006020820190508181036000830152613d068161381a565b9050919050565b60006020820190508181036000830152613d268161383d565b9050919050565b60006020820190508181036000830152613d4681613860565b9050919050565b60006020820190508181036000830152613d6681613883565b9050919050565b60006020820190508181036000830152613d86816138a6565b9050919050565b60006020820190508181036000830152613da6816138ec565b9050919050565b60006020820190508181036000830152613dc68161390f565b9050919050565b60006020820190508181036000830152613de681613932565b9050919050565b60006020820190508181036000830152613e0681613955565b9050919050565b6000602082019050613e226000830184613978565b92915050565b6000613e32613e43565b9050613e3e82826140fa565b919050565b6000604051905090565b600067ffffffffffffffff821115613e6857613e67614290565b5b613e71826142d3565b9050602081019050919050565b600067ffffffffffffffff821115613e9957613e98614290565b5b613ea2826142d3565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613f088261407c565b9150613f138361407c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613f4857613f476141a5565b5b828201905092915050565b6000613f5e8261407c565b9150613f698361407c565b925082613f7957613f786141d4565b5b828204905092915050565b6000613f8f8261407c565b9150613f9a8361407c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613fd357613fd26141a5565b5b828202905092915050565b6000613fe98261407c565b9150613ff48361407c565b925082821015614007576140066141a5565b5b828203905092915050565b600061401d8261405c565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156140b3578082015181840152602081019050614098565b838111156140c2576000848401525b50505050565b600060028204905060018216806140e057607f821691505b602082108114156140f4576140f3614203565b5b50919050565b614103826142d3565b810181811067ffffffffffffffff8211171561412257614121614290565b5b80604052505050565b60006141368261407c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614169576141686141a5565b5b600182019050919050565b600061417f8261407c565b915061418a8361407c565b92508261419a576141996141d4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4e6f2048616d6d696573206c6566740000000000000000000000000000000000600082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f5075626c69632053616c65206973206e6f742061637469766500000000000000600082015250565b7f53616c6520686173206e6f7420626567756e0000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4e6f2068616d6d696573206c6566740000000000000000000000000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4f6e6c792031302066726565206d696e7473207065722077616c6c6574000000600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4e6f7420656e6f756768206574682073656e7400000000000000000000000000600082015250565b7f4e6f206d6f726520667265652068616d6d696573000000000000000000000000600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f3130206d61782070657220747800000000000000000000000000000000000000600082015250565b50565b7f4d696e74696e6720776974682024666c75666620686173206e6f74206265677560008201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6149a681614012565b81146149b157600080fd5b50565b6149bd81614024565b81146149c857600080fd5b50565b6149d481614030565b81146149df57600080fd5b50565b6149eb8161407c565b81146149f657600080fd5b5056fea2646970667358221220e3bee46e0faa0d074a9726513c204bda7fa07b4589ac15c7ffb71c22d5047f6c64736f6c63430008070033

Deployed Bytecode

0x60806040526004361061023b5760003560e01c80636817c76c1161012e578063a7027357116100ab578063d547cfb71161006f578063d547cfb714610840578063e985e9c51461086b578063f2fde38b146108a8578063f968adbe146108d1578063fff5982b146108fc5761023b565b8063a70273571461076f578063b7d32a7e1461079a578063b88d4fde146107c3578063c87b56dd146107ec578063d3dd5fe0146108295761023b565b80638da5cb5b116100f25780638da5cb5b146106bd57806395d89b41146106e8578063990b21ec14610713578063a0712d681461072a578063a22cb465146107465761023b565b80636817c76c146105fe57806370a0823114610629578063715018a6146106665780637c928fe91461067d578063853828b6146106a65761023b565b806326a74d8e116101bc578063475133341161018057806347513334146105195780634f6ccce71461054457806355f804b3146105815780635d3bb979146105aa5780636352211e146105c15761023b565b806326a74d8e146104325780632ab4d0521461045d5780632f745c59146104885780633eaaf86b146104c557806342842e0e146104f05761023b565b80630dad00d8116102035780630dad00d81461034b57806318160ddd1461037657806320c09e24146103a157806323b872dd146103cc57806326a49e37146103f55761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a85780630865704c146102e5578063095ea7b314610322575b600080fd5b34801561024c57600080fd5b50610267600480360381019061026291906133f0565b610927565b6040516102749190613a50565b60405180910390f35b34801561028957600080fd5b506102926109a1565b60405161029f9190613a6b565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613493565b610a33565b6040516102dc91906139c0565b60405180910390f35b3480156102f157600080fd5b5061030c6004803603810190610307919061322d565b610ab8565b6040516103199190613e0d565b60405180910390f35b34801561032e57600080fd5b50610349600480360381019061034491906133b0565b610ad0565b005b34801561035757600080fd5b50610360610be8565b60405161036d9190613a50565b60405180910390f35b34801561038257600080fd5b5061038b610bfb565b6040516103989190613e0d565b60405180910390f35b3480156103ad57600080fd5b506103b6610c08565b6040516103c391906139c0565b60405180910390f35b3480156103d857600080fd5b506103f360048036038101906103ee919061329a565b610c20565b005b34801561040157600080fd5b5061041c60048036038101906104179190613493565b610c80565b6040516104299190613e0d565b60405180910390f35b34801561043e57600080fd5b50610447610ca3565b6040516104549190613e0d565b60405180910390f35b34801561046957600080fd5b50610472610ca9565b60405161047f9190613e0d565b60405180910390f35b34801561049457600080fd5b506104af60048036038101906104aa91906133b0565b610caf565b6040516104bc9190613e0d565b60405180910390f35b3480156104d157600080fd5b506104da610d54565b6040516104e79190613e0d565b60405180910390f35b3480156104fc57600080fd5b506105176004803603810190610512919061329a565b610d65565b005b34801561052557600080fd5b5061052e610d85565b60405161053b9190613e0d565b60405180910390f35b34801561055057600080fd5b5061056b60048036038101906105669190613493565b610d8b565b6040516105789190613e0d565b60405180910390f35b34801561058d57600080fd5b506105a860048036038101906105a3919061344a565b610dfc565b005b3480156105b657600080fd5b506105bf610e92565b005b3480156105cd57600080fd5b506105e860048036038101906105e39190613493565b610fd4565b6040516105f591906139c0565b60405180910390f35b34801561060a57600080fd5b50610613611086565b6040516106209190613e0d565b60405180910390f35b34801561063557600080fd5b50610650600480360381019061064b919061322d565b611091565b60405161065d9190613e0d565b60405180910390f35b34801561067257600080fd5b5061067b611149565b005b34801561068957600080fd5b506106a4600480360381019061069f9190613493565b6111d1565b005b3480156106b257600080fd5b506106bb6113cf565b005b3480156106c957600080fd5b506106d26114f4565b6040516106df91906139c0565b60405180910390f35b3480156106f457600080fd5b506106fd61151e565b60405161070a9190613a6b565b60405180910390f35b34801561071f57600080fd5b506107286115b0565b005b610744600480360381019061073f9190613493565b611658565b005b34801561075257600080fd5b5061076d60048036038101906107689190613370565b6117be565b005b34801561077b57600080fd5b5061078461193f565b6040516107919190613e0d565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc919061322d565b611944565b005b3480156107cf57600080fd5b506107ea60048036038101906107e591906132ed565b611a04565b005b3480156107f857600080fd5b50610813600480360381019061080e9190613493565b611a66565b6040516108209190613a6b565b60405180910390f35b34801561083557600080fd5b5061083e611b0d565b005b34801561084c57600080fd5b50610855611bb5565b6040516108629190613a6b565b60405180910390f35b34801561087757600080fd5b50610892600480360381019061088d919061325a565b611c43565b60405161089f9190613a50565b60405180910390f35b3480156108b457600080fd5b506108cf60048036038101906108ca919061322d565b611cd7565b005b3480156108dd57600080fd5b506108e6611dcf565b6040516108f39190613e0d565b60405180910390f35b34801561090857600080fd5b50610911611dd4565b60405161091e91906139c0565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061099a575061099982611dec565b5b9050919050565b6060600080546109b0906140c8565b80601f01602080910402602001604051908101604052809291908181526020018280546109dc906140c8565b8015610a295780601f106109fe57610100808354040283529160200191610a29565b820191906000526020600020905b815481529060010190602001808311610a0c57829003601f168201915b5050505050905090565b6000610a3e82611ece565b610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490613c8d565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600f6020528060005260406000206000915090505481565b6000610adb82610fd4565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390613d4d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b6b611f3a565b73ffffffffffffffffffffffffffffffffffffffff161480610b9a5750610b9981610b94611f3a565b611c43565b5b610bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd090613bed565b60405180910390fd5b610be38383611f42565b505050565b600e60019054906101000a900460ff1681565b6000600880549050905090565b732e824997ace675f5bdb0d56121aa04b2599bda8b81565b610c31610c2b611f3a565b82611ffb565b610c70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6790613dcd565b60405180910390fd5b610c7b8383836120d9565b505050565b6000610c9c8266d529ae9e86000061233590919063ffffffff16565b9050919050565b61131881565b6122b881565b6000610cba83611091565b8210610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf290613a8d565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610d60600b61234b565b905090565b610d8083838360405180602001604052806000815250611a04565b505050565b600d5481565b6000610d95610bfb565b8210610dd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dcd90613ded565b60405180910390fd5b60088281548110610dea57610de9614261565b5b90600052602060002001549050919050565b610e04611f3a565b73ffffffffffffffffffffffffffffffffffffffff16610e226114f4565b73ffffffffffffffffffffffffffffffffffffffff1614610e78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6f90613cad565b60405180910390fd5b8060109080519060200190610e8e929190613041565b5050565b6000610e9c610d54565b90506122b88110610ee2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed990613aed565b60405180910390fd5b600e60019054906101000a900460ff16610f31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2890613d8d565b60405180910390fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac33610f7984612359565b6040518363ffffffff1660e01b8152600401610f96929190613a27565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd1336123af565b50565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561107d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107490613c2d565b60405180910390fd5b80915050919050565b66d529ae9e86000081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f990613c0d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611151611f3a565b73ffffffffffffffffffffffffffffffffffffffff1661116f6114f4565b73ffffffffffffffffffffffffffffffffffffffff16146111c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bc90613cad565b60405180910390fd5b6111cf60006123d5565b565b60006111db610d54565b9050600e60009054906101000a900460ff1661122c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122390613b2d565b60405180910390fd5b600d54828261123b9190613efd565b111561127c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127390613d0d565b60405180910390fd5b600a600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054836112c99190613efd565b111561130a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130190613c6d565b60405180910390fd5b600a82111561134e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134590613d6d565b60405180910390fd5b60005b828110156113ca57600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906113a99061412b565b91905055506113b7336123af565b80806113c29061412b565b915050611351565b505050565b6113d7611f3a565b73ffffffffffffffffffffffffffffffffffffffff166113f56114f4565b73ffffffffffffffffffffffffffffffffffffffff161461144b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144290613cad565b60405180910390fd5b60004790506000611479606461146b60328561233590919063ffffffff16565b61249b90919063ffffffff16565b905060006114a4606461149660328661233590919063ffffffff16565b61249b90919063ffffffff16565b9050600083116114b357600080fd5b6114d173cd2367fcfbd8bf8ef87c98fc53cc2ea27437f6ee836124b1565b6114ef732e824997ace675f5bdb0d56121aa04b2599bda8b826124b1565b505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461152d906140c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611559906140c8565b80156115a65780601f1061157b576101008083540402835291602001916115a6565b820191906000526020600020905b81548152906001019060200180831161158957829003601f168201915b5050505050905090565b6115b8611f3a565b73ffffffffffffffffffffffffffffffffffffffff166115d66114f4565b73ffffffffffffffffffffffffffffffffffffffff161461162c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162390613cad565b60405180910390fd5b600e60019054906101000a900460ff1615600e60016101000a81548160ff021916908315150217905550565b6000611662610d54565b9050600e60009054906101000a900460ff166116b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116aa90613b4d565b60405180910390fd5b61131882826116c29190613efd565b1115611703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fa90613bad565b60405180910390fd5b600a821115611747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173e90613d6d565b60405180910390fd5b61175082610c80565b341015611792576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178990613ced565b60405180910390fd5b60005b828110156117b9576117a6336123af565b80806117b19061412b565b915050611795565b505050565b6117c6611f3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611834576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182b90613b8d565b60405180910390fd5b8060056000611841611f3a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166118ee611f3a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516119339190613a50565b60405180910390a35050565b600a81565b61194c611f3a565b73ffffffffffffffffffffffffffffffffffffffff1661196a6114f4565b73ffffffffffffffffffffffffffffffffffffffff16146119c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b790613cad565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611a15611a0f611f3a565b83611ffb565b611a54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4b90613dcd565b60405180910390fd5b611a6084848484612562565b50505050565b6060611a7182611ece565b611ab0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa790613d2d565b60405180910390fd5b6000611aba6125be565b90506000815111611ada5760405180602001604052806000815250611b05565b80611ae484612650565b604051602001611af5929190613987565b6040516020818303038152906040525b915050919050565b611b15611f3a565b73ffffffffffffffffffffffffffffffffffffffff16611b336114f4565b73ffffffffffffffffffffffffffffffffffffffff1614611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8090613cad565b60405180910390fd5b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b60108054611bc2906140c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611bee906140c8565b8015611c3b5780601f10611c1057610100808354040283529160200191611c3b565b820191906000526020600020905b815481529060010190602001808311611c1e57829003601f168201915b505050505081565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611cdf611f3a565b73ffffffffffffffffffffffffffffffffffffffff16611cfd6114f4565b73ffffffffffffffffffffffffffffffffffffffff1614611d53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4a90613cad565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611dc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dba90613acd565b60405180910390fd5b611dcc816123d5565b50565b600a81565b73cd2367fcfbd8bf8ef87c98fc53cc2ea27437f6ee81565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611eb757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ec75750611ec6826127b1565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611fb583610fd4565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061200682611ece565b612045576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203c90613bcd565b60405180910390fd5b600061205083610fd4565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806120bf57508373ffffffffffffffffffffffffffffffffffffffff166120a784610a33565b73ffffffffffffffffffffffffffffffffffffffff16145b806120d057506120cf8185611c43565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166120f982610fd4565b73ffffffffffffffffffffffffffffffffffffffff161461214f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214690613ccd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156121bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121b690613b6d565b60405180910390fd5b6121ca83838361281b565b6121d5600082611f42565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546122259190613fde565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461227c9190613efd565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600081836123439190613f84565b905092915050565b600081600001549050919050565b600061170082101561236e57606490506123aa565b611ae78210156123815760c890506123aa565b611ecf8210156123955761019090506123aa565b6122b78210156123a95761032090506123aa565b5b919050565b60006123bb600b61234b565b90506123c7600b61292f565b6123d18282612945565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081836124a99190613f53565b905092915050565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516124d7906139ab565b60006040518083038185875af1925050503d8060008114612514576040519150601f19603f3d011682016040523d82523d6000602084013e612519565b606091505b505090508061255d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255490613dad565b60405180910390fd5b505050565b61256d8484846120d9565b61257984848484612963565b6125b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125af90613aad565b60405180910390fd5b50505050565b6060601080546125cd906140c8565b80601f01602080910402602001604051908101604052809291908181526020018280546125f9906140c8565b80156126465780601f1061261b57610100808354040283529160200191612646565b820191906000526020600020905b81548152906001019060200180831161262957829003601f168201915b5050505050905090565b60606000821415612698576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506127ac565b600082905060005b600082146126ca5780806126b39061412b565b915050600a826126c39190613f53565b91506126a0565b60008167ffffffffffffffff8111156126e6576126e5614290565b5b6040519080825280601f01601f1916602001820160405280156127185781602001600182028036833780820191505090505b5090505b600085146127a5576001826127319190613fde565b9150600a856127409190614174565b603061274c9190613efd565b60f81b81838151811061276257612761614261565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561279e9190613f53565b945061271c565b8093505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612826838383612afa565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156128695761286481612aff565b6128a8565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146128a7576128a68382612b48565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156128eb576128e681612cb5565b61292a565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612929576129288282612d86565b5b5b505050565b6001816000016000828254019250508190555050565b61295f828260405180602001604052806000815250612e05565b5050565b60006129848473ffffffffffffffffffffffffffffffffffffffff16612e60565b15612aed578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026129ad611f3a565b8786866040518563ffffffff1660e01b81526004016129cf94939291906139db565b602060405180830381600087803b1580156129e957600080fd5b505af1925050508015612a1a57506040513d601f19601f82011682018060405250810190612a17919061341d565b60015b612a9d573d8060008114612a4a576040519150601f19603f3d011682016040523d82523d6000602084013e612a4f565b606091505b50600081511415612a95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a8c90613aad565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612af2565b600190505b949350505050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b5584611091565b612b5f9190613fde565b9050600060076000848152602001908152602001600020549050818114612c44576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050612cc99190613fde565b9050600060096000848152602001908152602001600020549050600060088381548110612cf957612cf8614261565b5b906000526020600020015490508060088381548110612d1b57612d1a614261565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480612d6a57612d69614232565b5b6001900381819060005260206000200160009055905550505050565b6000612d9183611091565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b612e0f8383612e73565b612e1c6000848484612963565b612e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5290613aad565b60405180910390fd5b505050565b600080823b905060008111915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ee3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eda90613c4d565b60405180910390fd5b612eec81611ece565b15612f2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f2390613b0d565b60405180910390fd5b612f386000838361281b565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612f889190613efd565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b82805461304d906140c8565b90600052602060002090601f01602090048101928261306f57600085556130b6565b82601f1061308857805160ff19168380011785556130b6565b828001600101855582156130b6579182015b828111156130b557825182559160200191906001019061309a565b5b5090506130c391906130c7565b5090565b5b808211156130e05760008160009055506001016130c8565b5090565b60006130f76130f284613e4d565b613e28565b905082815260208101848484011115613113576131126142c4565b5b61311e848285614086565b509392505050565b600061313961313484613e7e565b613e28565b905082815260208101848484011115613155576131546142c4565b5b613160848285614086565b509392505050565b6000813590506131778161499d565b92915050565b60008135905061318c816149b4565b92915050565b6000813590506131a1816149cb565b92915050565b6000815190506131b6816149cb565b92915050565b600082601f8301126131d1576131d06142bf565b5b81356131e18482602086016130e4565b91505092915050565b600082601f8301126131ff576131fe6142bf565b5b813561320f848260208601613126565b91505092915050565b600081359050613227816149e2565b92915050565b600060208284031215613243576132426142ce565b5b600061325184828501613168565b91505092915050565b60008060408385031215613271576132706142ce565b5b600061327f85828601613168565b925050602061329085828601613168565b9150509250929050565b6000806000606084860312156132b3576132b26142ce565b5b60006132c186828701613168565b93505060206132d286828701613168565b92505060406132e386828701613218565b9150509250925092565b60008060008060808587031215613307576133066142ce565b5b600061331587828801613168565b945050602061332687828801613168565b935050604061333787828801613218565b925050606085013567ffffffffffffffff811115613358576133576142c9565b5b613364878288016131bc565b91505092959194509250565b60008060408385031215613387576133866142ce565b5b600061339585828601613168565b92505060206133a68582860161317d565b9150509250929050565b600080604083850312156133c7576133c66142ce565b5b60006133d585828601613168565b92505060206133e685828601613218565b9150509250929050565b600060208284031215613406576134056142ce565b5b600061341484828501613192565b91505092915050565b600060208284031215613433576134326142ce565b5b6000613441848285016131a7565b91505092915050565b6000602082840312156134605761345f6142ce565b5b600082013567ffffffffffffffff81111561347e5761347d6142c9565b5b61348a848285016131ea565b91505092915050565b6000602082840312156134a9576134a86142ce565b5b60006134b784828501613218565b91505092915050565b6134c981614012565b82525050565b6134d881614024565b82525050565b60006134e982613eaf565b6134f38185613ec5565b9350613503818560208601614095565b61350c816142d3565b840191505092915050565b600061352282613eba565b61352c8185613ee1565b935061353c818560208601614095565b613545816142d3565b840191505092915050565b600061355b82613eba565b6135658185613ef2565b9350613575818560208601614095565b80840191505092915050565b600061358e602b83613ee1565b9150613599826142e4565b604082019050919050565b60006135b1603283613ee1565b91506135bc82614333565b604082019050919050565b60006135d4602683613ee1565b91506135df82614382565b604082019050919050565b60006135f7600f83613ee1565b9150613602826143d1565b602082019050919050565b600061361a601c83613ee1565b9150613625826143fa565b602082019050919050565b600061363d601983613ee1565b915061364882614423565b602082019050919050565b6000613660601283613ee1565b915061366b8261444c565b602082019050919050565b6000613683602483613ee1565b915061368e82614475565b604082019050919050565b60006136a6601983613ee1565b91506136b1826144c4565b602082019050919050565b60006136c9600f83613ee1565b91506136d4826144ed565b602082019050919050565b60006136ec602c83613ee1565b91506136f782614516565b604082019050919050565b600061370f603883613ee1565b915061371a82614565565b604082019050919050565b6000613732602a83613ee1565b915061373d826145b4565b604082019050919050565b6000613755602983613ee1565b915061376082614603565b604082019050919050565b6000613778602083613ee1565b915061378382614652565b602082019050919050565b600061379b601d83613ee1565b91506137a68261467b565b602082019050919050565b60006137be602c83613ee1565b91506137c9826146a4565b604082019050919050565b60006137e1602083613ee1565b91506137ec826146f3565b602082019050919050565b6000613804602983613ee1565b915061380f8261471c565b604082019050919050565b6000613827601383613ee1565b91506138328261476b565b602082019050919050565b600061384a601483613ee1565b915061385582614794565b602082019050919050565b600061386d602f83613ee1565b9150613878826147bd565b604082019050919050565b6000613890602183613ee1565b915061389b8261480c565b604082019050919050565b60006138b3600d83613ee1565b91506138be8261485b565b602082019050919050565b60006138d6600083613ed6565b91506138e182614884565b600082019050919050565b60006138f9602183613ee1565b915061390482614887565b604082019050919050565b600061391c601083613ee1565b9150613927826148d6565b602082019050919050565b600061393f603183613ee1565b915061394a826148ff565b604082019050919050565b6000613962602c83613ee1565b915061396d8261494e565b604082019050919050565b6139818161407c565b82525050565b60006139938285613550565b915061399f8284613550565b91508190509392505050565b60006139b6826138c9565b9150819050919050565b60006020820190506139d560008301846134c0565b92915050565b60006080820190506139f060008301876134c0565b6139fd60208301866134c0565b613a0a6040830185613978565b8181036060830152613a1c81846134de565b905095945050505050565b6000604082019050613a3c60008301856134c0565b613a496020830184613978565b9392505050565b6000602082019050613a6560008301846134cf565b92915050565b60006020820190508181036000830152613a858184613517565b905092915050565b60006020820190508181036000830152613aa681613581565b9050919050565b60006020820190508181036000830152613ac6816135a4565b9050919050565b60006020820190508181036000830152613ae6816135c7565b9050919050565b60006020820190508181036000830152613b06816135ea565b9050919050565b60006020820190508181036000830152613b268161360d565b9050919050565b60006020820190508181036000830152613b4681613630565b9050919050565b60006020820190508181036000830152613b6681613653565b9050919050565b60006020820190508181036000830152613b8681613676565b9050919050565b60006020820190508181036000830152613ba681613699565b9050919050565b60006020820190508181036000830152613bc6816136bc565b9050919050565b60006020820190508181036000830152613be6816136df565b9050919050565b60006020820190508181036000830152613c0681613702565b9050919050565b60006020820190508181036000830152613c2681613725565b9050919050565b60006020820190508181036000830152613c4681613748565b9050919050565b60006020820190508181036000830152613c668161376b565b9050919050565b60006020820190508181036000830152613c868161378e565b9050919050565b60006020820190508181036000830152613ca6816137b1565b9050919050565b60006020820190508181036000830152613cc6816137d4565b9050919050565b60006020820190508181036000830152613ce6816137f7565b9050919050565b60006020820190508181036000830152613d068161381a565b9050919050565b60006020820190508181036000830152613d268161383d565b9050919050565b60006020820190508181036000830152613d4681613860565b9050919050565b60006020820190508181036000830152613d6681613883565b9050919050565b60006020820190508181036000830152613d86816138a6565b9050919050565b60006020820190508181036000830152613da6816138ec565b9050919050565b60006020820190508181036000830152613dc68161390f565b9050919050565b60006020820190508181036000830152613de681613932565b9050919050565b60006020820190508181036000830152613e0681613955565b9050919050565b6000602082019050613e226000830184613978565b92915050565b6000613e32613e43565b9050613e3e82826140fa565b919050565b6000604051905090565b600067ffffffffffffffff821115613e6857613e67614290565b5b613e71826142d3565b9050602081019050919050565b600067ffffffffffffffff821115613e9957613e98614290565b5b613ea2826142d3565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613f088261407c565b9150613f138361407c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613f4857613f476141a5565b5b828201905092915050565b6000613f5e8261407c565b9150613f698361407c565b925082613f7957613f786141d4565b5b828204905092915050565b6000613f8f8261407c565b9150613f9a8361407c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613fd357613fd26141a5565b5b828202905092915050565b6000613fe98261407c565b9150613ff48361407c565b925082821015614007576140066141a5565b5b828203905092915050565b600061401d8261405c565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156140b3578082015181840152602081019050614098565b838111156140c2576000848401525b50505050565b600060028204905060018216806140e057607f821691505b602082108114156140f4576140f3614203565b5b50919050565b614103826142d3565b810181811067ffffffffffffffff8211171561412257614121614290565b5b80604052505050565b60006141368261407c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614169576141686141a5565b5b600182019050919050565b600061417f8261407c565b915061418a8361407c565b92508261419a576141996141d4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4e6f2048616d6d696573206c6566740000000000000000000000000000000000600082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f5075626c69632053616c65206973206e6f742061637469766500000000000000600082015250565b7f53616c6520686173206e6f7420626567756e0000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4e6f2068616d6d696573206c6566740000000000000000000000000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4f6e6c792031302066726565206d696e7473207065722077616c6c6574000000600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4e6f7420656e6f756768206574682073656e7400000000000000000000000000600082015250565b7f4e6f206d6f726520667265652068616d6d696573000000000000000000000000600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f3130206d61782070657220747800000000000000000000000000000000000000600082015250565b50565b7f4d696e74696e6720776974682024666c75666620686173206e6f74206265677560008201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6149a681614012565b81146149b157600080fd5b50565b6149bd81614024565b81146149c857600080fd5b50565b6149d481614030565b81146149df57600080fd5b50565b6149eb8161407c565b81146149f657600080fd5b5056fea2646970667358221220e3bee46e0faa0d074a9726513c204bda7fa07b4589ac15c7ffb71c22d5047f6c64736f6c63430008070033

Deployed Bytecode Sourcemap

1354:4903:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;909:222:7;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2349:98:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3860:217;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2119:51:10;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3398:401:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2076:32:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1534:111:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1960:80:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4724:330:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4606:106:10;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1624:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1676:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1210:253:7;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6155:100:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5120:179:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1584:34:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1717:230:7;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5442:99:10;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3732:298;;;;;;;;;;;;;:::i;:::-;;2052:235:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1727:46:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1790:205:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1598:92:18;;;;;;;;;;;;;:::i;:::-;;3171:522:10;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5580:321;;;;;;;;;;;;;:::i;:::-;;966:85:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2511:102:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5313:92:10;;;;;;;;;;;;;:::i;:::-;;2700:431;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4144:290:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1822:45:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5010:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5365:320:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2679:329;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2596:80:10;;;;;;;;;;;;;:::i;:::-;;2219:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4500:162:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1839:189:18;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1779:37:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1874:80;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;909:222:7;1011:4;1049:35;1034:50;;;:11;:50;;;;:90;;;;1088:36;1112:11;1088:23;:36::i;:::-;1034:90;1027:97;;909:222;;;:::o;2349:98:5:-;2403:13;2435:5;2428:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2349:98;:::o;3860:217::-;3936:7;3963:16;3971:7;3963;:16::i;:::-;3955:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;4046:15;:24;4062:7;4046:24;;;;;;;;;;;;;;;;;;;;;4039:31;;3860:217;;;:::o;2119:51:10:-;;;;;;;;;;;;;;;;;:::o;3398:401:5:-;3478:13;3494:23;3509:7;3494:14;:23::i;:::-;3478:39;;3541:5;3535:11;;:2;:11;;;;3527:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;3632:5;3616:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;3641:37;3658:5;3665:12;:10;:12::i;:::-;3641:16;:37::i;:::-;3616:62;3595:165;;;;;;;;;;;;:::i;:::-;;;;;;;;;3771:21;3780:2;3784:7;3771:8;:21::i;:::-;3468:331;3398:401;;:::o;2076:32:10:-;;;;;;;;;;;;;:::o;1534:111:7:-;1595:7;1621:10;:17;;;;1614:24;;1534:111;:::o;1960:80:10:-;1998:42;1960:80;:::o;4724:330:5:-;4913:41;4932:12;:10;:12::i;:::-;4946:7;4913:18;:41::i;:::-;4905:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;5019:28;5029:4;5035:2;5039:7;5019:9;:28::i;:::-;4724:330;;;:::o;4606:106:10:-;4658:7;4684:21;4698:6;1763:10;4684:13;;:21;;;;:::i;:::-;4677:28;;4606:106;;;:::o;1624:46::-;1666:4;1624:46;:::o;1676:45::-;1717:4;1676:45;:::o;1210:253:7:-;1307:7;1342:23;1359:5;1342:16;:23::i;:::-;1334:5;:31;1326:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;1430:12;:19;1443:5;1430:19;;;;;;;;;;;;;;;:26;1450:5;1430:26;;;;;;;;;;;;1423:33;;1210:253;;;;:::o;6155:100:10:-;6200:4;6223:25;:15;:23;:25::i;:::-;6216:32;;6155:100;:::o;5120:179:5:-;5253:39;5270:4;5276:2;5280:7;5253:39;;;;;;;;;;;;:16;:39::i;:::-;5120:179;;;:::o;1584:34:10:-;;;;:::o;1717:230:7:-;1792:7;1827:30;:28;:30::i;:::-;1819:5;:38;1811:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;1923:10;1934:5;1923:17;;;;;;;;:::i;:::-;;;;;;;;;;1916:24;;1717:230;;;:::o;5442:99:10:-;1189:12:18;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5527:7:10::1;5512:12;:22;;;;;;;;;;;;:::i;:::-;;5442:99:::0;:::o;3732:298::-;3779:13;3795:14;:12;:14::i;:::-;3779:30;;1717:4;3827:5;:22;3819:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;3887:12;;;;;;;;;;;3879:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;3947:5;;;;;;;;;;;:10;;;3958;3970:19;3983:5;3970:12;:19::i;:::-;3947:43;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4000:23;4012:10;4000:11;:23::i;:::-;3769:261;3732:298::o;2052:235:5:-;2124:7;2143:13;2159:7;:16;2167:7;2159:16;;;;;;;;;;;;;;;;;;;;;2143:32;;2210:1;2193:19;;:5;:19;;;;2185:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2275:5;2268:12;;;2052:235;;;:::o;1727:46:10:-;1763:10;1727:46;:::o;1790:205:5:-;1862:7;1906:1;1889:19;;:5;:19;;;;1881:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;1972:9;:16;1982:5;1972:16;;;;;;;;;;;;;;;;1965:23;;1790:205;;;:::o;1598:92:18:-;1189:12;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1662:21:::1;1680:1;1662:9;:21::i;:::-;1598:92::o:0;3171:522:10:-;3222:13;3238:14;:12;:14::i;:::-;3222:30;;3270:10;;;;;;;;;;;3262:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;3346:13;;3336:6;3328:5;:14;;;;:::i;:::-;:31;;3320:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;1865:2;3411:16;:28;3428:10;3411:28;;;;;;;;;;;;;;;;3402:6;:37;;;;:::i;:::-;:57;;3394:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;1814:2;3511:6;:18;;3503:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;3563:9;3558:129;3582:6;3578:1;:10;3558:129;;;3609:16;:28;3626:10;3609:28;;;;;;;;;;;;;;;;:30;;;;;;;;;:::i;:::-;;;;;;3653:23;3665:10;3653:11;:23::i;:::-;3590:3;;;;;:::i;:::-;;;;3558:129;;;;3212:481;3171:522;:::o;5580:321::-;1189:12:18;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5630:15:10::1;5648:21;5630:39;;5679:17;5699:24;5719:3;5699:15;5711:2;5699:7;:11;;:15;;;;:::i;:::-;:19;;:24;;;;:::i;:::-;5679:44;;5733:17;5753:24;5773:3;5753:15;5765:2;5753:7;:11;;:15;;;;:::i;:::-;:19;;:24;;;;:::i;:::-;5733:44;;5806:1;5796:7;:11;5788:20;;;::::0;::::1;;5818:33;1912:42;5841:9;5818;:33::i;:::-;5861;1998:42;5884:9;5861;:33::i;:::-;5620:281;;;5580:321::o:0;966:85:18:-;1012:7;1038:6;;;;;;;;;;;1031:13;;966:85;:::o;2511:102:5:-;2567:13;2599:7;2592:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2511:102;:::o;5313:92:10:-;1189:12:18;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5386:12:10::1;;;;;;;;;;;5385:13;5370:12;;:28;;;;;;;;;;;;;;;;;;5313:92::o:0;2700:431::-;2755:13;2771:14;:12;:14::i;:::-;2755:30;;2803:10;;;;;;;;;;;2795:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;1666:4;2862:6;2854:5;:14;;;;:::i;:::-;:33;;2846:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;1814:2;2925:6;:18;;2917:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;2992:13;2998:6;2992:5;:13::i;:::-;2979:9;:26;;2971:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;3045:9;3040:85;3064:6;3060:1;:10;3040:85;;;3091:23;3103:10;3091:11;:23::i;:::-;3072:3;;;;;:::i;:::-;;;;3040:85;;;;2745:386;2700:431;:::o;4144:290:5:-;4258:12;:10;:12::i;:::-;4246:24;;:8;:24;;;;4238:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;4356:8;4311:18;:32;4330:12;:10;:12::i;:::-;4311:32;;;;;;;;;;;;;;;:42;4344:8;4311:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;4408:8;4379:48;;4394:12;:10;:12::i;:::-;4379:48;;;4418:8;4379:48;;;;;;:::i;:::-;;;;;;;;4144:290;;:::o;1822:45:10:-;1865:2;1822:45;:::o;5010:104::-;1189:12:18;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5097:9:10::1;5083:5;;:24;;;;;;;;;;;;;;;;;;5010:104:::0;:::o;5365:320:5:-;5534:41;5553:12;:10;:12::i;:::-;5567:7;5534:18;:41::i;:::-;5526:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;5639:39;5653:4;5659:2;5663:7;5672:5;5639:13;:39::i;:::-;5365:320;;;;:::o;2679:329::-;2752:13;2785:16;2793:7;2785;:16::i;:::-;2777:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;2864:21;2888:10;:8;:10::i;:::-;2864:34;;2939:1;2921:7;2915:21;:25;:86;;;;;;;;;;;;;;;;;2967:7;2976:18;:7;:16;:18::i;:::-;2950:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2915:86;2908:93;;;2679:329;;;:::o;2596:80:10:-;1189:12:18;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2659:10:10::1;;;;;;;;;;;2658:11;2645:10;;:24;;;;;;;;;;;;;;;;;;2596:80::o:0;2219:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4500:162:5:-;4597:4;4620:18;:25;4639:5;4620:25;;;;;;;;;;;;;;;:35;4646:8;4620:35;;;;;;;;;;;;;;;;;;;;;;;;;4613:42;;4500:162;;;;:::o;1839:189:18:-;1189:12;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1947:1:::1;1927:22;;:8;:22;;;;1919:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2002:19;2012:8;2002:9;:19::i;:::-;1839:189:::0;:::o;1779:37:10:-;1814:2;1779:37;:::o;1874:80::-;1912:42;1874:80;:::o;1431:300:5:-;1533:4;1583:25;1568:40;;;:11;:40;;;;:104;;;;1639:33;1624:48;;;:11;:48;;;;1568:104;:156;;;;1688:36;1712:11;1688:23;:36::i;:::-;1568:156;1549:175;;1431:300;;;:::o;7157:125::-;7222:4;7273:1;7245:30;;:7;:16;7253:7;7245:16;;;;;;;;;;;;;;;;;;;;;:30;;;;7238:37;;7157:125;;;:::o;587:96:1:-;640:7;666:10;659:17;;587:96;:::o;11008:171:5:-;11109:2;11082:15;:24;11098:7;11082:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;11164:7;11160:2;11126:46;;11135:23;11150:7;11135:14;:23::i;:::-;11126:46;;;;;;;;;;;;11008:171;;:::o;7440:344::-;7533:4;7557:16;7565:7;7557;:16::i;:::-;7549:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;7632:13;7648:23;7663:7;7648:14;:23::i;:::-;7632:39;;7700:5;7689:16;;:7;:16;;;:51;;;;7733:7;7709:31;;:20;7721:7;7709:11;:20::i;:::-;:31;;;7689:51;:87;;;;7744:32;7761:5;7768:7;7744:16;:32::i;:::-;7689:87;7681:96;;;7440:344;;;;:::o;10337:560::-;10491:4;10464:31;;:23;10479:7;10464:14;:23::i;:::-;:31;;;10456:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;10573:1;10559:16;;:2;:16;;;;10551:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;10627:39;10648:4;10654:2;10658:7;10627:20;:39::i;:::-;10728:29;10745:1;10749:7;10728:8;:29::i;:::-;10787:1;10768:9;:15;10778:4;10768:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;10815:1;10798:9;:13;10808:2;10798:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;10845:2;10826:7;:16;10834:7;10826:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;10882:7;10878:2;10863:27;;10872:4;10863:27;;;;;;;;;;;;10337:560;;;:::o;3382:96:19:-;3440:7;3470:1;3466;:5;;;;:::i;:::-;3459:12;;3382:96;;;;:::o;773:112:2:-;838:7;864;:14;;;857:21;;773:112;;;:::o;4040:325:10:-;4106:12;4147:4;4133:11;:18;4129:229;;;4172:3;4165:10;;;;4129:229;4208:4;4194:11;:18;4190:168;;;4233:3;4226:10;;;;4190:168;4269:4;4255:11;:18;4251:107;;;4294:3;4287:10;;;;4251:107;4330:4;4316:11;:18;4312:46;;;4355:3;4348:10;;;;4312:46;4040:325;;;;:::o;4393:159::-;4445:7;4455:25;:15;:23;:25::i;:::-;4445:35;;4490:27;:15;:25;:27::i;:::-;4527:18;4537:3;4542:2;4527:9;:18::i;:::-;4435:117;4393:159;:::o;2034:169:18:-;2089:16;2108:6;;;;;;;;;;;2089:25;;2133:8;2124:6;;:17;;;;;;;;;;;;;;;;;;2187:8;2156:40;;2177:8;2156:40;;;;;;;;;;;;2079:124;2034:169;:::o;3767:96:19:-;3825:7;3855:1;3851;:5;;;;:::i;:::-;3844:12;;3767:96;;;;:::o;5931:177:10:-;6004:12;6022:8;:13;;6043:7;6022:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6003:52;;;6073:7;6065:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;5993:115;5931:177;;:::o;6547:307:5:-;6698:28;6708:4;6714:2;6718:7;6698:9;:28::i;:::-;6744:48;6767:4;6773:2;6777:7;6786:5;6744:22;:48::i;:::-;6736:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;6547:307;;;;:::o;5152:111:10:-;5212:13;5244:12;5237:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5152:111;:::o;275:703:20:-;331:13;557:1;548:5;:10;544:51;;;574:10;;;;;;;;;;;;;;;;;;;;;544:51;604:12;619:5;604:20;;634:14;658:75;673:1;665:4;:9;658:75;;690:8;;;;;:::i;:::-;;;;720:2;712:10;;;;;:::i;:::-;;;658:75;;;742:19;774:6;764:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;742:39;;791:150;807:1;798:5;:10;791:150;;834:1;824:11;;;;;:::i;:::-;;;900:2;892:5;:10;;;;:::i;:::-;879:2;:24;;;;:::i;:::-;866:39;;849:6;856;849:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;928:2;919:11;;;;;:::i;:::-;;;791:150;;;964:6;950:21;;;;;275:703;;;;:::o;763:155:3:-;848:4;886:25;871:40;;;:11;:40;;;;864:47;;763:155;;;:::o;2543:572:7:-;2682:45;2709:4;2715:2;2719:7;2682:26;:45::i;:::-;2758:1;2742:18;;:4;:18;;;2738:183;;;2776:40;2808:7;2776:31;:40::i;:::-;2738:183;;;2845:2;2837:10;;:4;:10;;;2833:88;;2863:47;2896:4;2902:7;2863:32;:47::i;:::-;2833:88;2738:183;2948:1;2934:16;;:2;:16;;;2930:179;;;2966:45;3003:7;2966:36;:45::i;:::-;2930:179;;;3038:4;3032:10;;:2;:10;;;3028:81;;3058:40;3086:2;3090:7;3058:27;:40::i;:::-;3028:81;2930:179;2543:572;;;:::o;891:123:2:-;996:1;978:7;:14;;;:19;;;;;;;;;;;891:123;:::o;8114:108:5:-;8189:26;8199:2;8203:7;8189:26;;;;;;;;;;;;:9;:26::i;:::-;8114:108;;:::o;11732:778::-;11882:4;11902:15;:2;:13;;;:15::i;:::-;11898:606;;;11953:2;11937:36;;;11974:12;:10;:12::i;:::-;11988:4;11994:7;12003:5;11937:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;11933:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12193:1;12176:6;:13;:18;12172:266;;;12218:60;;;;;;;;;;:::i;:::-;;;;;;;;12172:266;12390:6;12384:13;12375:6;12371:2;12367:15;12360:38;11933:519;12069:41;;;12059:51;;;:6;:51;;;;12052:58;;;;;11898:606;12489:4;12482:11;;11732:778;;;;;;;:::o;13066:122::-;;;;:::o;3821:161:7:-;3924:10;:17;;;;3897:15;:24;3913:7;3897:24;;;;;;;;;;;:44;;;;3951:10;3967:7;3951:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3821:161;:::o;4599:970::-;4861:22;4911:1;4886:22;4903:4;4886:16;:22::i;:::-;:26;;;;:::i;:::-;4861:51;;4922:18;4943:17;:26;4961:7;4943:26;;;;;;;;;;;;4922:47;;5087:14;5073:10;:28;5069:323;;5117:19;5139:12;:18;5152:4;5139:18;;;;;;;;;;;;;;;:34;5158:14;5139:34;;;;;;;;;;;;5117:56;;5221:11;5188:12;:18;5201:4;5188:18;;;;;;;;;;;;;;;:30;5207:10;5188:30;;;;;;;;;;;:44;;;;5337:10;5304:17;:30;5322:11;5304:30;;;;;;;;;;;:43;;;;5103:289;5069:323;5485:17;:26;5503:7;5485:26;;;;;;;;;;;5478:33;;;5528:12;:18;5541:4;5528:18;;;;;;;;;;;;;;;:34;5547:14;5528:34;;;;;;;;;;;5521:41;;;4680:889;;4599:970;;:::o;5857:1061::-;6106:22;6151:1;6131:10;:17;;;;:21;;;;:::i;:::-;6106:46;;6162:18;6183:15;:24;6199:7;6183:24;;;;;;;;;;;;6162:45;;6529:19;6551:10;6562:14;6551:26;;;;;;;;:::i;:::-;;;;;;;;;;6529:48;;6613:11;6588:10;6599;6588:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;6723:10;6692:15;:28;6708:11;6692:28;;;;;;;;;;;:41;;;;6861:15;:24;6877:7;6861:24;;;;;;;;;;;6854:31;;;6895:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5928:990;;;5857:1061;:::o;3409:217::-;3493:14;3510:20;3527:2;3510:16;:20::i;:::-;3493:37;;3567:7;3540:12;:16;3553:2;3540:16;;;;;;;;;;;;;;;:24;3557:6;3540:24;;;;;;;;;;;:34;;;;3613:6;3584:17;:26;3602:7;3584:26;;;;;;;;;;;:35;;;;3483:143;3409:217;;:::o;8443:311:5:-;8568:18;8574:2;8578:7;8568:5;:18::i;:::-;8617:54;8648:1;8652:2;8656:7;8665:5;8617:22;:54::i;:::-;8596:151;;;;;;;;;;;;:::i;:::-;;;;;;;;;8443:311;;;:::o;718:377:0:-;778:4;981:12;1046:7;1034:20;1026:28;;1087:1;1080:4;:8;1073:15;;;718:377;;;:::o;9076:372:5:-;9169:1;9155:16;;:2;:16;;;;9147:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;9227:16;9235:7;9227;:16::i;:::-;9226:17;9218:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;9287:45;9316:1;9320:2;9324:7;9287:20;:45::i;:::-;9360:1;9343:9;:13;9353:2;9343:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;9390:2;9371:7;:16;9379:7;9371:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;9433:7;9429:2;9408:33;;9425:1;9408:33;;;;;;;;;;;;9076:372;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:21:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;986:133::-;1029:5;1067:6;1054:20;1045:29;;1083:30;1107:5;1083:30;:::i;:::-;986:133;;;;:::o;1125:137::-;1170:5;1208:6;1195:20;1186:29;;1224:32;1250:5;1224:32;:::i;:::-;1125:137;;;;:::o;1268:141::-;1324:5;1355:6;1349:13;1340:22;;1371:32;1397:5;1371:32;:::i;:::-;1268:141;;;;:::o;1428:338::-;1483:5;1532:3;1525:4;1517:6;1513:17;1509:27;1499:122;;1540:79;;:::i;:::-;1499:122;1657:6;1644:20;1682:78;1756:3;1748:6;1741:4;1733:6;1729:17;1682:78;:::i;:::-;1673:87;;1489:277;1428:338;;;;:::o;1786:340::-;1842:5;1891:3;1884:4;1876:6;1872:17;1868:27;1858:122;;1899:79;;:::i;:::-;1858:122;2016:6;2003:20;2041:79;2116:3;2108:6;2101:4;2093:6;2089:17;2041:79;:::i;:::-;2032:88;;1848:278;1786:340;;;;:::o;2132:139::-;2178:5;2216:6;2203:20;2194:29;;2232:33;2259:5;2232:33;:::i;:::-;2132:139;;;;:::o;2277:329::-;2336:6;2385:2;2373:9;2364:7;2360:23;2356:32;2353:119;;;2391:79;;:::i;:::-;2353:119;2511:1;2536:53;2581:7;2572:6;2561:9;2557:22;2536:53;:::i;:::-;2526:63;;2482:117;2277:329;;;;:::o;2612:474::-;2680:6;2688;2737:2;2725:9;2716:7;2712:23;2708:32;2705:119;;;2743:79;;:::i;:::-;2705:119;2863:1;2888:53;2933:7;2924:6;2913:9;2909:22;2888:53;:::i;:::-;2878:63;;2834:117;2990:2;3016:53;3061:7;3052:6;3041:9;3037:22;3016:53;:::i;:::-;3006:63;;2961:118;2612:474;;;;;:::o;3092:619::-;3169:6;3177;3185;3234:2;3222:9;3213:7;3209:23;3205:32;3202:119;;;3240:79;;:::i;:::-;3202:119;3360:1;3385:53;3430:7;3421:6;3410:9;3406:22;3385:53;:::i;:::-;3375:63;;3331:117;3487:2;3513:53;3558:7;3549:6;3538:9;3534:22;3513:53;:::i;:::-;3503:63;;3458:118;3615:2;3641:53;3686:7;3677:6;3666:9;3662:22;3641:53;:::i;:::-;3631:63;;3586:118;3092:619;;;;;:::o;3717:943::-;3812:6;3820;3828;3836;3885:3;3873:9;3864:7;3860:23;3856:33;3853:120;;;3892:79;;:::i;:::-;3853:120;4012:1;4037:53;4082:7;4073:6;4062:9;4058:22;4037:53;:::i;:::-;4027:63;;3983:117;4139:2;4165:53;4210:7;4201:6;4190:9;4186:22;4165:53;:::i;:::-;4155:63;;4110:118;4267:2;4293:53;4338:7;4329:6;4318:9;4314:22;4293:53;:::i;:::-;4283:63;;4238:118;4423:2;4412:9;4408:18;4395:32;4454:18;4446:6;4443:30;4440:117;;;4476:79;;:::i;:::-;4440:117;4581:62;4635:7;4626:6;4615:9;4611:22;4581:62;:::i;:::-;4571:72;;4366:287;3717:943;;;;;;;:::o;4666:468::-;4731:6;4739;4788:2;4776:9;4767:7;4763:23;4759:32;4756:119;;;4794:79;;:::i;:::-;4756:119;4914:1;4939:53;4984:7;4975:6;4964:9;4960:22;4939:53;:::i;:::-;4929:63;;4885:117;5041:2;5067:50;5109:7;5100:6;5089:9;5085:22;5067:50;:::i;:::-;5057:60;;5012:115;4666:468;;;;;:::o;5140:474::-;5208:6;5216;5265:2;5253:9;5244:7;5240:23;5236:32;5233:119;;;5271:79;;:::i;:::-;5233:119;5391:1;5416:53;5461:7;5452:6;5441:9;5437:22;5416:53;:::i;:::-;5406:63;;5362:117;5518:2;5544:53;5589:7;5580:6;5569:9;5565:22;5544:53;:::i;:::-;5534:63;;5489:118;5140:474;;;;;:::o;5620:327::-;5678:6;5727:2;5715:9;5706:7;5702:23;5698:32;5695:119;;;5733:79;;:::i;:::-;5695:119;5853:1;5878:52;5922:7;5913:6;5902:9;5898:22;5878:52;:::i;:::-;5868:62;;5824:116;5620:327;;;;:::o;5953:349::-;6022:6;6071:2;6059:9;6050:7;6046:23;6042:32;6039:119;;;6077:79;;:::i;:::-;6039:119;6197:1;6222:63;6277:7;6268:6;6257:9;6253:22;6222:63;:::i;:::-;6212:73;;6168:127;5953:349;;;;:::o;6308:509::-;6377:6;6426:2;6414:9;6405:7;6401:23;6397:32;6394:119;;;6432:79;;:::i;:::-;6394:119;6580:1;6569:9;6565:17;6552:31;6610:18;6602:6;6599:30;6596:117;;;6632:79;;:::i;:::-;6596:117;6737:63;6792:7;6783:6;6772:9;6768:22;6737:63;:::i;:::-;6727:73;;6523:287;6308:509;;;;:::o;6823:329::-;6882:6;6931:2;6919:9;6910:7;6906:23;6902:32;6899:119;;;6937:79;;:::i;:::-;6899:119;7057:1;7082:53;7127:7;7118:6;7107:9;7103:22;7082:53;:::i;:::-;7072:63;;7028:117;6823:329;;;;:::o;7158:118::-;7245:24;7263:5;7245:24;:::i;:::-;7240:3;7233:37;7158:118;;:::o;7282:109::-;7363:21;7378:5;7363:21;:::i;:::-;7358:3;7351:34;7282:109;;:::o;7397:360::-;7483:3;7511:38;7543:5;7511:38;:::i;:::-;7565:70;7628:6;7623:3;7565:70;:::i;:::-;7558:77;;7644:52;7689:6;7684:3;7677:4;7670:5;7666:16;7644:52;:::i;:::-;7721:29;7743:6;7721:29;:::i;:::-;7716:3;7712:39;7705:46;;7487:270;7397:360;;;;:::o;7763:364::-;7851:3;7879:39;7912:5;7879:39;:::i;:::-;7934:71;7998:6;7993:3;7934:71;:::i;:::-;7927:78;;8014:52;8059:6;8054:3;8047:4;8040:5;8036:16;8014:52;:::i;:::-;8091:29;8113:6;8091:29;:::i;:::-;8086:3;8082:39;8075:46;;7855:272;7763:364;;;;:::o;8133:377::-;8239:3;8267:39;8300:5;8267:39;:::i;:::-;8322:89;8404:6;8399:3;8322:89;:::i;:::-;8315:96;;8420:52;8465:6;8460:3;8453:4;8446:5;8442:16;8420:52;:::i;:::-;8497:6;8492:3;8488:16;8481:23;;8243:267;8133:377;;;;:::o;8516:366::-;8658:3;8679:67;8743:2;8738:3;8679:67;:::i;:::-;8672:74;;8755:93;8844:3;8755:93;:::i;:::-;8873:2;8868:3;8864:12;8857:19;;8516:366;;;:::o;8888:::-;9030:3;9051:67;9115:2;9110:3;9051:67;:::i;:::-;9044:74;;9127:93;9216:3;9127:93;:::i;:::-;9245:2;9240:3;9236:12;9229:19;;8888:366;;;:::o;9260:::-;9402:3;9423:67;9487:2;9482:3;9423:67;:::i;:::-;9416:74;;9499:93;9588:3;9499:93;:::i;:::-;9617:2;9612:3;9608:12;9601:19;;9260:366;;;:::o;9632:::-;9774:3;9795:67;9859:2;9854:3;9795:67;:::i;:::-;9788:74;;9871:93;9960:3;9871:93;:::i;:::-;9989:2;9984:3;9980:12;9973:19;;9632:366;;;:::o;10004:::-;10146:3;10167:67;10231:2;10226:3;10167:67;:::i;:::-;10160:74;;10243:93;10332:3;10243:93;:::i;:::-;10361:2;10356:3;10352:12;10345:19;;10004:366;;;:::o;10376:::-;10518:3;10539:67;10603:2;10598:3;10539:67;:::i;:::-;10532:74;;10615:93;10704:3;10615:93;:::i;:::-;10733:2;10728:3;10724:12;10717:19;;10376:366;;;:::o;10748:::-;10890:3;10911:67;10975:2;10970:3;10911:67;:::i;:::-;10904:74;;10987:93;11076:3;10987:93;:::i;:::-;11105:2;11100:3;11096:12;11089:19;;10748:366;;;:::o;11120:::-;11262:3;11283:67;11347:2;11342:3;11283:67;:::i;:::-;11276:74;;11359:93;11448:3;11359:93;:::i;:::-;11477:2;11472:3;11468:12;11461:19;;11120:366;;;:::o;11492:::-;11634:3;11655:67;11719:2;11714:3;11655:67;:::i;:::-;11648:74;;11731:93;11820:3;11731:93;:::i;:::-;11849:2;11844:3;11840:12;11833:19;;11492:366;;;:::o;11864:::-;12006:3;12027:67;12091:2;12086:3;12027:67;:::i;:::-;12020:74;;12103:93;12192:3;12103:93;:::i;:::-;12221:2;12216:3;12212:12;12205:19;;11864:366;;;:::o;12236:::-;12378:3;12399:67;12463:2;12458:3;12399:67;:::i;:::-;12392:74;;12475:93;12564:3;12475:93;:::i;:::-;12593:2;12588:3;12584:12;12577:19;;12236:366;;;:::o;12608:::-;12750:3;12771:67;12835:2;12830:3;12771:67;:::i;:::-;12764:74;;12847:93;12936:3;12847:93;:::i;:::-;12965:2;12960:3;12956:12;12949:19;;12608:366;;;:::o;12980:::-;13122:3;13143:67;13207:2;13202:3;13143:67;:::i;:::-;13136:74;;13219:93;13308:3;13219:93;:::i;:::-;13337:2;13332:3;13328:12;13321:19;;12980:366;;;:::o;13352:::-;13494:3;13515:67;13579:2;13574:3;13515:67;:::i;:::-;13508:74;;13591:93;13680:3;13591:93;:::i;:::-;13709:2;13704:3;13700:12;13693:19;;13352:366;;;:::o;13724:::-;13866:3;13887:67;13951:2;13946:3;13887:67;:::i;:::-;13880:74;;13963:93;14052:3;13963:93;:::i;:::-;14081:2;14076:3;14072:12;14065:19;;13724:366;;;:::o;14096:::-;14238:3;14259:67;14323:2;14318:3;14259:67;:::i;:::-;14252:74;;14335:93;14424:3;14335:93;:::i;:::-;14453:2;14448:3;14444:12;14437:19;;14096:366;;;:::o;14468:::-;14610:3;14631:67;14695:2;14690:3;14631:67;:::i;:::-;14624:74;;14707:93;14796:3;14707:93;:::i;:::-;14825:2;14820:3;14816:12;14809:19;;14468:366;;;:::o;14840:::-;14982:3;15003:67;15067:2;15062:3;15003:67;:::i;:::-;14996:74;;15079:93;15168:3;15079:93;:::i;:::-;15197:2;15192:3;15188:12;15181:19;;14840:366;;;:::o;15212:::-;15354:3;15375:67;15439:2;15434:3;15375:67;:::i;:::-;15368:74;;15451:93;15540:3;15451:93;:::i;:::-;15569:2;15564:3;15560:12;15553:19;;15212:366;;;:::o;15584:::-;15726:3;15747:67;15811:2;15806:3;15747:67;:::i;:::-;15740:74;;15823:93;15912:3;15823:93;:::i;:::-;15941:2;15936:3;15932:12;15925:19;;15584:366;;;:::o;15956:::-;16098:3;16119:67;16183:2;16178:3;16119:67;:::i;:::-;16112:74;;16195:93;16284:3;16195:93;:::i;:::-;16313:2;16308:3;16304:12;16297:19;;15956:366;;;:::o;16328:::-;16470:3;16491:67;16555:2;16550:3;16491:67;:::i;:::-;16484:74;;16567:93;16656:3;16567:93;:::i;:::-;16685:2;16680:3;16676:12;16669:19;;16328:366;;;:::o;16700:::-;16842:3;16863:67;16927:2;16922:3;16863:67;:::i;:::-;16856:74;;16939:93;17028:3;16939:93;:::i;:::-;17057:2;17052:3;17048:12;17041:19;;16700:366;;;:::o;17072:::-;17214:3;17235:67;17299:2;17294:3;17235:67;:::i;:::-;17228:74;;17311:93;17400:3;17311:93;:::i;:::-;17429:2;17424:3;17420:12;17413:19;;17072:366;;;:::o;17444:398::-;17603:3;17624:83;17705:1;17700:3;17624:83;:::i;:::-;17617:90;;17716:93;17805:3;17716:93;:::i;:::-;17834:1;17829:3;17825:11;17818:18;;17444:398;;;:::o;17848:366::-;17990:3;18011:67;18075:2;18070:3;18011:67;:::i;:::-;18004:74;;18087:93;18176:3;18087:93;:::i;:::-;18205:2;18200:3;18196:12;18189:19;;17848:366;;;:::o;18220:::-;18362:3;18383:67;18447:2;18442:3;18383:67;:::i;:::-;18376:74;;18459:93;18548:3;18459:93;:::i;:::-;18577:2;18572:3;18568:12;18561:19;;18220:366;;;:::o;18592:::-;18734:3;18755:67;18819:2;18814:3;18755:67;:::i;:::-;18748:74;;18831:93;18920:3;18831:93;:::i;:::-;18949:2;18944:3;18940:12;18933:19;;18592:366;;;:::o;18964:::-;19106:3;19127:67;19191:2;19186:3;19127:67;:::i;:::-;19120:74;;19203:93;19292:3;19203:93;:::i;:::-;19321:2;19316:3;19312:12;19305:19;;18964:366;;;:::o;19336:118::-;19423:24;19441:5;19423:24;:::i;:::-;19418:3;19411:37;19336:118;;:::o;19460:435::-;19640:3;19662:95;19753:3;19744:6;19662:95;:::i;:::-;19655:102;;19774:95;19865:3;19856:6;19774:95;:::i;:::-;19767:102;;19886:3;19879:10;;19460:435;;;;;:::o;19901:379::-;20085:3;20107:147;20250:3;20107:147;:::i;:::-;20100:154;;20271:3;20264:10;;19901:379;;;:::o;20286:222::-;20379:4;20417:2;20406:9;20402:18;20394:26;;20430:71;20498:1;20487:9;20483:17;20474:6;20430:71;:::i;:::-;20286:222;;;;:::o;20514:640::-;20709:4;20747:3;20736:9;20732:19;20724:27;;20761:71;20829:1;20818:9;20814:17;20805:6;20761:71;:::i;:::-;20842:72;20910:2;20899:9;20895:18;20886:6;20842:72;:::i;:::-;20924;20992:2;20981:9;20977:18;20968:6;20924:72;:::i;:::-;21043:9;21037:4;21033:20;21028:2;21017:9;21013:18;21006:48;21071:76;21142:4;21133:6;21071:76;:::i;:::-;21063:84;;20514:640;;;;;;;:::o;21160:332::-;21281:4;21319:2;21308:9;21304:18;21296:26;;21332:71;21400:1;21389:9;21385:17;21376:6;21332:71;:::i;:::-;21413:72;21481:2;21470:9;21466:18;21457:6;21413:72;:::i;:::-;21160:332;;;;;:::o;21498:210::-;21585:4;21623:2;21612:9;21608:18;21600:26;;21636:65;21698:1;21687:9;21683:17;21674:6;21636:65;:::i;:::-;21498:210;;;;:::o;21714:313::-;21827:4;21865:2;21854:9;21850:18;21842:26;;21914:9;21908:4;21904:20;21900:1;21889:9;21885:17;21878:47;21942:78;22015:4;22006:6;21942:78;:::i;:::-;21934:86;;21714:313;;;;:::o;22033:419::-;22199:4;22237:2;22226:9;22222:18;22214:26;;22286:9;22280:4;22276:20;22272:1;22261:9;22257:17;22250:47;22314:131;22440:4;22314:131;:::i;:::-;22306:139;;22033:419;;;:::o;22458:::-;22624:4;22662:2;22651:9;22647:18;22639:26;;22711:9;22705:4;22701:20;22697:1;22686:9;22682:17;22675:47;22739:131;22865:4;22739:131;:::i;:::-;22731:139;;22458:419;;;:::o;22883:::-;23049:4;23087:2;23076:9;23072:18;23064:26;;23136:9;23130:4;23126:20;23122:1;23111:9;23107:17;23100:47;23164:131;23290:4;23164:131;:::i;:::-;23156:139;;22883:419;;;:::o;23308:::-;23474:4;23512:2;23501:9;23497:18;23489:26;;23561:9;23555:4;23551:20;23547:1;23536:9;23532:17;23525:47;23589:131;23715:4;23589:131;:::i;:::-;23581:139;;23308:419;;;:::o;23733:::-;23899:4;23937:2;23926:9;23922:18;23914:26;;23986:9;23980:4;23976:20;23972:1;23961:9;23957:17;23950:47;24014:131;24140:4;24014:131;:::i;:::-;24006:139;;23733:419;;;:::o;24158:::-;24324:4;24362:2;24351:9;24347:18;24339:26;;24411:9;24405:4;24401:20;24397:1;24386:9;24382:17;24375:47;24439:131;24565:4;24439:131;:::i;:::-;24431:139;;24158:419;;;:::o;24583:::-;24749:4;24787:2;24776:9;24772:18;24764:26;;24836:9;24830:4;24826:20;24822:1;24811:9;24807:17;24800:47;24864:131;24990:4;24864:131;:::i;:::-;24856:139;;24583:419;;;:::o;25008:::-;25174:4;25212:2;25201:9;25197:18;25189:26;;25261:9;25255:4;25251:20;25247:1;25236:9;25232:17;25225:47;25289:131;25415:4;25289:131;:::i;:::-;25281:139;;25008:419;;;:::o;25433:::-;25599:4;25637:2;25626:9;25622:18;25614:26;;25686:9;25680:4;25676:20;25672:1;25661:9;25657:17;25650:47;25714:131;25840:4;25714:131;:::i;:::-;25706:139;;25433:419;;;:::o;25858:::-;26024:4;26062:2;26051:9;26047:18;26039:26;;26111:9;26105:4;26101:20;26097:1;26086:9;26082:17;26075:47;26139:131;26265:4;26139:131;:::i;:::-;26131:139;;25858:419;;;:::o;26283:::-;26449:4;26487:2;26476:9;26472:18;26464:26;;26536:9;26530:4;26526:20;26522:1;26511:9;26507:17;26500:47;26564:131;26690:4;26564:131;:::i;:::-;26556:139;;26283:419;;;:::o;26708:::-;26874:4;26912:2;26901:9;26897:18;26889:26;;26961:9;26955:4;26951:20;26947:1;26936:9;26932:17;26925:47;26989:131;27115:4;26989:131;:::i;:::-;26981:139;;26708:419;;;:::o;27133:::-;27299:4;27337:2;27326:9;27322:18;27314:26;;27386:9;27380:4;27376:20;27372:1;27361:9;27357:17;27350:47;27414:131;27540:4;27414:131;:::i;:::-;27406:139;;27133:419;;;:::o;27558:::-;27724:4;27762:2;27751:9;27747:18;27739:26;;27811:9;27805:4;27801:20;27797:1;27786:9;27782:17;27775:47;27839:131;27965:4;27839:131;:::i;:::-;27831:139;;27558:419;;;:::o;27983:::-;28149:4;28187:2;28176:9;28172:18;28164:26;;28236:9;28230:4;28226:20;28222:1;28211:9;28207:17;28200:47;28264:131;28390:4;28264:131;:::i;:::-;28256:139;;27983:419;;;:::o;28408:::-;28574:4;28612:2;28601:9;28597:18;28589:26;;28661:9;28655:4;28651:20;28647:1;28636:9;28632:17;28625:47;28689:131;28815:4;28689:131;:::i;:::-;28681:139;;28408:419;;;:::o;28833:::-;28999:4;29037:2;29026:9;29022:18;29014:26;;29086:9;29080:4;29076:20;29072:1;29061:9;29057:17;29050:47;29114:131;29240:4;29114:131;:::i;:::-;29106:139;;28833:419;;;:::o;29258:::-;29424:4;29462:2;29451:9;29447:18;29439:26;;29511:9;29505:4;29501:20;29497:1;29486:9;29482:17;29475:47;29539:131;29665:4;29539:131;:::i;:::-;29531:139;;29258:419;;;:::o;29683:::-;29849:4;29887:2;29876:9;29872:18;29864:26;;29936:9;29930:4;29926:20;29922:1;29911:9;29907:17;29900:47;29964:131;30090:4;29964:131;:::i;:::-;29956:139;;29683:419;;;:::o;30108:::-;30274:4;30312:2;30301:9;30297:18;30289:26;;30361:9;30355:4;30351:20;30347:1;30336:9;30332:17;30325:47;30389:131;30515:4;30389:131;:::i;:::-;30381:139;;30108:419;;;:::o;30533:::-;30699:4;30737:2;30726:9;30722:18;30714:26;;30786:9;30780:4;30776:20;30772:1;30761:9;30757:17;30750:47;30814:131;30940:4;30814:131;:::i;:::-;30806:139;;30533:419;;;:::o;30958:::-;31124:4;31162:2;31151:9;31147:18;31139:26;;31211:9;31205:4;31201:20;31197:1;31186:9;31182:17;31175:47;31239:131;31365:4;31239:131;:::i;:::-;31231:139;;30958:419;;;:::o;31383:::-;31549:4;31587:2;31576:9;31572:18;31564:26;;31636:9;31630:4;31626:20;31622:1;31611:9;31607:17;31600:47;31664:131;31790:4;31664:131;:::i;:::-;31656:139;;31383:419;;;:::o;31808:::-;31974:4;32012:2;32001:9;31997:18;31989:26;;32061:9;32055:4;32051:20;32047:1;32036:9;32032:17;32025:47;32089:131;32215:4;32089:131;:::i;:::-;32081:139;;31808:419;;;:::o;32233:::-;32399:4;32437:2;32426:9;32422:18;32414:26;;32486:9;32480:4;32476:20;32472:1;32461:9;32457:17;32450:47;32514:131;32640:4;32514:131;:::i;:::-;32506:139;;32233:419;;;:::o;32658:::-;32824:4;32862:2;32851:9;32847:18;32839:26;;32911:9;32905:4;32901:20;32897:1;32886:9;32882:17;32875:47;32939:131;33065:4;32939:131;:::i;:::-;32931:139;;32658:419;;;:::o;33083:::-;33249:4;33287:2;33276:9;33272:18;33264:26;;33336:9;33330:4;33326:20;33322:1;33311:9;33307:17;33300:47;33364:131;33490:4;33364:131;:::i;:::-;33356:139;;33083:419;;;:::o;33508:::-;33674:4;33712:2;33701:9;33697:18;33689:26;;33761:9;33755:4;33751:20;33747:1;33736:9;33732:17;33725:47;33789:131;33915:4;33789:131;:::i;:::-;33781:139;;33508:419;;;:::o;33933:222::-;34026:4;34064:2;34053:9;34049:18;34041:26;;34077:71;34145:1;34134:9;34130:17;34121:6;34077:71;:::i;:::-;33933:222;;;;:::o;34161:129::-;34195:6;34222:20;;:::i;:::-;34212:30;;34251:33;34279:4;34271:6;34251:33;:::i;:::-;34161:129;;;:::o;34296:75::-;34329:6;34362:2;34356:9;34346:19;;34296:75;:::o;34377:307::-;34438:4;34528:18;34520:6;34517:30;34514:56;;;34550:18;;:::i;:::-;34514:56;34588:29;34610:6;34588:29;:::i;:::-;34580:37;;34672:4;34666;34662:15;34654:23;;34377:307;;;:::o;34690:308::-;34752:4;34842:18;34834:6;34831:30;34828:56;;;34864:18;;:::i;:::-;34828:56;34902:29;34924:6;34902:29;:::i;:::-;34894:37;;34986:4;34980;34976:15;34968:23;;34690:308;;;:::o;35004:98::-;35055:6;35089:5;35083:12;35073:22;;35004:98;;;:::o;35108:99::-;35160:6;35194:5;35188:12;35178:22;;35108:99;;;:::o;35213:168::-;35296:11;35330:6;35325:3;35318:19;35370:4;35365:3;35361:14;35346:29;;35213:168;;;;:::o;35387:147::-;35488:11;35525:3;35510:18;;35387:147;;;;:::o;35540:169::-;35624:11;35658:6;35653:3;35646:19;35698:4;35693:3;35689:14;35674:29;;35540:169;;;;:::o;35715:148::-;35817:11;35854:3;35839:18;;35715:148;;;;:::o;35869:305::-;35909:3;35928:20;35946:1;35928:20;:::i;:::-;35923:25;;35962:20;35980:1;35962:20;:::i;:::-;35957:25;;36116:1;36048:66;36044:74;36041:1;36038:81;36035:107;;;36122:18;;:::i;:::-;36035:107;36166:1;36163;36159:9;36152:16;;35869:305;;;;:::o;36180:185::-;36220:1;36237:20;36255:1;36237:20;:::i;:::-;36232:25;;36271:20;36289:1;36271:20;:::i;:::-;36266:25;;36310:1;36300:35;;36315:18;;:::i;:::-;36300:35;36357:1;36354;36350:9;36345:14;;36180:185;;;;:::o;36371:348::-;36411:7;36434:20;36452:1;36434:20;:::i;:::-;36429:25;;36468:20;36486:1;36468:20;:::i;:::-;36463:25;;36656:1;36588:66;36584:74;36581:1;36578:81;36573:1;36566:9;36559:17;36555:105;36552:131;;;36663:18;;:::i;:::-;36552:131;36711:1;36708;36704:9;36693:20;;36371:348;;;;:::o;36725:191::-;36765:4;36785:20;36803:1;36785:20;:::i;:::-;36780:25;;36819:20;36837:1;36819:20;:::i;:::-;36814:25;;36858:1;36855;36852:8;36849:34;;;36863:18;;:::i;:::-;36849:34;36908:1;36905;36901:9;36893:17;;36725:191;;;;:::o;36922:96::-;36959:7;36988:24;37006:5;36988:24;:::i;:::-;36977:35;;36922:96;;;:::o;37024:90::-;37058:7;37101:5;37094:13;37087:21;37076:32;;37024:90;;;:::o;37120:149::-;37156:7;37196:66;37189:5;37185:78;37174:89;;37120:149;;;:::o;37275:126::-;37312:7;37352:42;37345:5;37341:54;37330:65;;37275:126;;;:::o;37407:77::-;37444:7;37473:5;37462:16;;37407:77;;;:::o;37490:154::-;37574:6;37569:3;37564;37551:30;37636:1;37627:6;37622:3;37618:16;37611:27;37490:154;;;:::o;37650:307::-;37718:1;37728:113;37742:6;37739:1;37736:13;37728:113;;;37827:1;37822:3;37818:11;37812:18;37808:1;37803:3;37799:11;37792:39;37764:2;37761:1;37757:10;37752:15;;37728:113;;;37859:6;37856:1;37853:13;37850:101;;;37939:1;37930:6;37925:3;37921:16;37914:27;37850:101;37699:258;37650:307;;;:::o;37963:320::-;38007:6;38044:1;38038:4;38034:12;38024:22;;38091:1;38085:4;38081:12;38112:18;38102:81;;38168:4;38160:6;38156:17;38146:27;;38102:81;38230:2;38222:6;38219:14;38199:18;38196:38;38193:84;;;38249:18;;:::i;:::-;38193:84;38014:269;37963:320;;;:::o;38289:281::-;38372:27;38394:4;38372:27;:::i;:::-;38364:6;38360:40;38502:6;38490:10;38487:22;38466:18;38454:10;38451:34;38448:62;38445:88;;;38513:18;;:::i;:::-;38445:88;38553:10;38549:2;38542:22;38332:238;38289:281;;:::o;38576:233::-;38615:3;38638:24;38656:5;38638:24;:::i;:::-;38629:33;;38684:66;38677:5;38674:77;38671:103;;;38754:18;;:::i;:::-;38671:103;38801:1;38794:5;38790:13;38783:20;;38576:233;;;:::o;38815:176::-;38847:1;38864:20;38882:1;38864:20;:::i;:::-;38859:25;;38898:20;38916:1;38898:20;:::i;:::-;38893:25;;38937:1;38927:35;;38942:18;;:::i;:::-;38927:35;38983:1;38980;38976:9;38971:14;;38815:176;;;;:::o;38997:180::-;39045:77;39042:1;39035:88;39142:4;39139:1;39132:15;39166:4;39163:1;39156:15;39183:180;39231:77;39228:1;39221:88;39328:4;39325:1;39318:15;39352:4;39349:1;39342:15;39369:180;39417:77;39414:1;39407:88;39514:4;39511:1;39504:15;39538:4;39535:1;39528:15;39555:180;39603:77;39600:1;39593:88;39700:4;39697:1;39690:15;39724:4;39721:1;39714:15;39741:180;39789:77;39786:1;39779:88;39886:4;39883:1;39876:15;39910:4;39907:1;39900:15;39927:180;39975:77;39972:1;39965:88;40072:4;40069:1;40062:15;40096:4;40093:1;40086:15;40113:117;40222:1;40219;40212:12;40236:117;40345:1;40342;40335:12;40359:117;40468:1;40465;40458:12;40482:117;40591:1;40588;40581:12;40605:102;40646:6;40697:2;40693:7;40688:2;40681:5;40677:14;40673:28;40663:38;;40605:102;;;:::o;40713:230::-;40853:34;40849:1;40841:6;40837:14;40830:58;40922:13;40917:2;40909:6;40905:15;40898:38;40713:230;:::o;40949:237::-;41089:34;41085:1;41077:6;41073:14;41066:58;41158:20;41153:2;41145:6;41141:15;41134:45;40949:237;:::o;41192:225::-;41332:34;41328:1;41320:6;41316:14;41309:58;41401:8;41396:2;41388:6;41384:15;41377:33;41192:225;:::o;41423:165::-;41563:17;41559:1;41551:6;41547:14;41540:41;41423:165;:::o;41594:178::-;41734:30;41730:1;41722:6;41718:14;41711:54;41594:178;:::o;41778:175::-;41918:27;41914:1;41906:6;41902:14;41895:51;41778:175;:::o;41959:168::-;42099:20;42095:1;42087:6;42083:14;42076:44;41959:168;:::o;42133:223::-;42273:34;42269:1;42261:6;42257:14;42250:58;42342:6;42337:2;42329:6;42325:15;42318:31;42133:223;:::o;42362:175::-;42502:27;42498:1;42490:6;42486:14;42479:51;42362:175;:::o;42543:165::-;42683:17;42679:1;42671:6;42667:14;42660:41;42543:165;:::o;42714:231::-;42854:34;42850:1;42842:6;42838:14;42831:58;42923:14;42918:2;42910:6;42906:15;42899:39;42714:231;:::o;42951:243::-;43091:34;43087:1;43079:6;43075:14;43068:58;43160:26;43155:2;43147:6;43143:15;43136:51;42951:243;:::o;43200:229::-;43340:34;43336:1;43328:6;43324:14;43317:58;43409:12;43404:2;43396:6;43392:15;43385:37;43200:229;:::o;43435:228::-;43575:34;43571:1;43563:6;43559:14;43552:58;43644:11;43639:2;43631:6;43627:15;43620:36;43435:228;:::o;43669:182::-;43809:34;43805:1;43797:6;43793:14;43786:58;43669:182;:::o;43857:179::-;43997:31;43993:1;43985:6;43981:14;43974:55;43857:179;:::o;44042:231::-;44182:34;44178:1;44170:6;44166:14;44159:58;44251:14;44246:2;44238:6;44234:15;44227:39;44042:231;:::o;44279:182::-;44419:34;44415:1;44407:6;44403:14;44396:58;44279:182;:::o;44467:228::-;44607:34;44603:1;44595:6;44591:14;44584:58;44676:11;44671:2;44663:6;44659:15;44652:36;44467:228;:::o;44701:169::-;44841:21;44837:1;44829:6;44825:14;44818:45;44701:169;:::o;44876:170::-;45016:22;45012:1;45004:6;45000:14;44993:46;44876:170;:::o;45052:234::-;45192:34;45188:1;45180:6;45176:14;45169:58;45261:17;45256:2;45248:6;45244:15;45237:42;45052:234;:::o;45292:220::-;45432:34;45428:1;45420:6;45416:14;45409:58;45501:3;45496:2;45488:6;45484:15;45477:28;45292:220;:::o;45518:163::-;45658:15;45654:1;45646:6;45642:14;45635:39;45518:163;:::o;45687:114::-;;:::o;45807:220::-;45947:34;45943:1;45935:6;45931:14;45924:58;46016:3;46011:2;46003:6;45999:15;45992:28;45807:220;:::o;46033:166::-;46173:18;46169:1;46161:6;46157:14;46150:42;46033:166;:::o;46205:236::-;46345:34;46341:1;46333:6;46329:14;46322:58;46414:19;46409:2;46401:6;46397:15;46390:44;46205:236;:::o;46447:231::-;46587:34;46583:1;46575:6;46571:14;46564:58;46656:14;46651:2;46643:6;46639:15;46632:39;46447:231;:::o;46684:122::-;46757:24;46775:5;46757:24;:::i;:::-;46750:5;46747:35;46737:63;;46796:1;46793;46786:12;46737:63;46684:122;:::o;46812:116::-;46882:21;46897:5;46882:21;:::i;:::-;46875:5;46872:32;46862:60;;46918:1;46915;46908:12;46862:60;46812:116;:::o;46934:120::-;47006:23;47023:5;47006:23;:::i;:::-;46999:5;46996:34;46986:62;;47044:1;47041;47034:12;46986:62;46934:120;:::o;47060:122::-;47133:24;47151:5;47133:24;:::i;:::-;47126:5;47123:35;47113:63;;47172:1;47169;47162:12;47113:63;47060:122;:::o

Swarm Source

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