ETH Price: $3,103.61 (+1.15%)
Gas: 13 Gwei

Token

Witches & Demons Game (WNDGAME)
 

Overview

Max Total Supply

91 WNDGAME

Holders

26

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
curtisjcummings.eth
Balance
10 WNDGAME
0x939cc6dbe3fe8564fc2b84a49cbeddb10060bf43
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

15,000 Witches and Demons fight on the blockchain for $NEWT. Choose to play as a Witch or a Demon as you balance your risk and reward!

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
WitchesandDemonsGame

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-04
*/

// oooooo   oooooo     oooo ooooo ooooooooooooo   .oooooo.   ooooo   ooooo oooooooooooo  .oooooo..o                                      
//  `888.    `888.     .8'  `888' 8'   888   `8  d8P'  `Y8b  `888'   `888' `888'     `8 d8P'    `Y8                                      
//   `888.   .8888.   .8'    888       888      888           888     888   888         Y88bo.                                           
//    `888  .8'`888. .8'     888       888      888           888ooooo888   888oooo8     `"Y8888o.                                       
//     `888.8'  `888.8'      888       888      888           888     888   888    "         `"Y88b                                      
//      `888'    `888'       888       888      `88b    ooo   888     888   888       o oo     .d8P                                      
//       `8'      `8'       o888o     o888o      `Y8bood8P'  o888o   o888o o888ooooood8 8""88888P'                                       
//                                                                                                                                       
//                                                                                                                                       
//                                                                                                                                       
//       .o.       ooooo      ooo oooooooooo.        oooooooooo.   oooooooooooo ooo        ooooo   .oooooo.   ooooo      ooo  .oooooo..o 
//      .888.      `888b.     `8' `888'   `Y8b       `888'   `Y8b  `888'     `8 `88.       .888'  d8P'  `Y8b  `888b.     `8' d8P'    `Y8 
//     .8"888.      8 `88b.    8   888      888       888      888  888          888b     d'888  888      888  8 `88b.    8  Y88bo.      
//    .8' `888.     8   `88b.  8   888      888       888      888  888oooo8     8 Y88. .P  888  888      888  8   `88b.  8   `"Y8888o.  
//   .88ooo8888.    8     `88b.8   888      888       888      888  888    "     8  `888'   888  888      888  8     `88b.8       `"Y88b 
//  .8'     `888.   8       `888   888     d88'       888     d88'  888       o  8    Y     888  `88b    d88'  8       `888  oo     .d8P 
// o88o     o8888o o8o        `8  o888bood8P'        o888bood8P'   o888ooooood8 o8o        o888o  `Y8bood8P'  o8o        `8  8""88888P'  
//                                                                                                                                       
//                                                                                                                                       
//                                                                                                                                       
//   .oooooo.          .o.       ooo        ooooo oooooooooooo                                                                           
//  d8P'  `Y8b        .888.      `88.       .888' `888'     `8                                                                           
// 888               .8"888.      888b     d'888   888                                                                                   
// 888              .8' `888.     8 Y88. .P  888   888oooo8                                                                              
// 888     ooooo   .88ooo8888.    8  `888'   888   888    "                                                                              
// `88.    .88'   .8'     `888.   8    Y     888   888       o                                                                           
//  `Y8bood8P'   o88o     o8888o o8o        o888o o888ooooood8  


// Credit all resources to Wizards and Dragons
// SPDX-License-Identifier: MIT
// http://discord.gg/eFnUheap

// Address.sol


pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Context.sol


pragma solidity ^0.8.0;

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

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

// Pausable.sol


pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// Counters.sol


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;
    }
}

// EnumerableSet.sol


pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

// IERC165.sol


pragma solidity ^0.8.0;

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


// ERC165.sol


pragma solidity ^0.8.0;


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

// IERC721.sol


pragma solidity ^0.8.0;


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

// IERC721Metadata.sol


pragma solidity ^0.8.0;


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

// IERC20.sol


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);
}

// ERC721.sol


pragma solidity ^0.8.0;

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

// IERC721Enumerable.sol


pragma solidity ^0.8.0;


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


// IERC721Receiver.sol


pragma solidity ^0.8.0;

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

// ERC721Enumerable.sol


pragma solidity ^0.8.0;


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



// LinkTokenInterface.sol

pragma solidity ^0.8.0;

interface LinkTokenInterface {

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

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

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

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

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

  function increaseApproval(
    address spender,
    uint256 subtractedValue
  ) external;

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

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

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

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

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

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

}

// Ownable.sol


pragma solidity ^0.8.0;


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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _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);
    }
}

// ReentrancyGuard.sol


pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

// VRFRequestIDBase.sol

pragma solidity ^0.8.0;

contract VRFRequestIDBase {

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

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

// VRFConsumerBase.sol

pragma solidity ^0.8.0;


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

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

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

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

  LinkTokenInterface immutable internal LINK;
  address immutable private vrfCoordinator;

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

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

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

// WitchesandDemons.sol
                                                                                                                                      


pragma solidity ^0.8.7;



interface INEWT {
  function burn(address from, uint256 amount) external;
}

interface ITraits {
  function tokenURI(uint256 tokenId) external view returns (string memory);
}

interface IWitchesandDemons {
  struct ManDemon {bool isWitch; uint8[14] traitarray; uint8 alphaIndex;}
  function getPaidTokens() external view returns (uint256);
  function getTokenTraits(uint256 tokenId) external view returns (ManDemon memory);
}

interface ICoven {
  function addManyToCovenSideAndFishing(address account, uint16[] calldata tokenIds) external;
  function randomDemonOwner(uint256 seed) external view returns (address);
}

contract WitchesandDemonsGame is IWitchesandDemons, ERC721Enumerable, Ownable, Pausable, VRFConsumerBase {
  using Counters for Counters.Counter;
  using EnumerableSet for EnumerableSet.UintSet; 


  // mint variables                    
  uint256 public immutable MAX_TOKENS;                                   // max number of tokens that can be minted - 50000 in production
  uint256 public PAID_TOKENS;                                            // number of tokens that can be claimed for free - 20% of MAX_TOKENS
  uint16 public minted;                                                  // number of tokens have been minted so far
  uint256 public constant MINT_PRICE = .025 ether;                    // mint price
      

  
  string public baseURI;

  // mappings
  mapping(address => uint256) public whitelists;
  mapping(uint256 => ManDemon) public tokenTraits;                       // mapping from tokenId to a struct containing the token's traits
  mapping(uint256 => uint256) public existingCombinations;              // mapping from hashed(tokenTrait) to the tokenId it's associated with, Why? used to ensure there are no duplicates
  mapping(address => uint256[]) public _mints;



  // Pobabilities & Aliases
  // 0 - 8 are associated with witches, 9 - 13 are associated with Demons
  uint8[][18] public rarities;
  uint8[][18] public aliases;


  ICoven public coven;                                                       // STAKING - reference to the Barn for choosing random Demon thieves
  INEWT public NEWT;                                                       // TOKEN - reference to $NEWT for burning on mint
  ITraits public traits;                                                    // TRAITS - reference to Traits
  

  //Chainlink Setup:
  bytes32 internal keyHash;
  uint256 public fee;
  uint256 internal randomResult;
  uint256 internal randomNumber;
  address public linkToken;
  uint256 public vrfcooldown = 10000;
  Counters.Counter public vrfReqd;




  constructor(address _NEWT, uint256 _maxTokens, address _vrfCoordinator, address _link) 
      ERC721("Witches & Demons Game", 'WNDGAME') 
      VRFConsumerBase(_vrfCoordinator, _link)  

  { 


    keyHash = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445;
    fee = 2 * 10 ** 18; // 0.1 LINK (Varies by network)
    linkToken = _link;
    
  


    // Initate Interfaces
    NEWT = INEWT(_NEWT);

    
    MAX_TOKENS = _maxTokens;
    PAID_TOKENS = _maxTokens / 5;

    // string[13] _traitTypes = ['Hat','Eyes','Body','Pants','Skintone','Mouth','Feet','Fishing Pole','Fish','Fur','Eyes','Clothes','Mouth','Alpha'];

    aliases[9] = [0,1,2,3,4];
    aliases[10] = [9,8,7,6,5,4,3,2,1,0];
    aliases[11] = [10,9,8,7,6,5,4,3,2,1,0];
    aliases[12] = [5,4,3,2,1,0];
    aliases[13] = [3,2,1,0];
    

  }


  /** 
   * mint a token - 90% Demons, 10% Witch
   * The first 20% are free to claim, the remaining cost $NEWT
   */
      
    
  // Calculates Mint Cost using $NEWT
  function mintCost(uint256 tokenId) public view returns (uint256) {
    if (tokenId <= PAID_TOKENS) return 0;                           // the first 1/6 are paid in ETH, Hence 0 $NEWT
    if (tokenId <= MAX_TOKENS * 2 / 6) return 16000 ether;          // the next 1/6 are 16000 $NEWT
    if (tokenId <= MAX_TOKENS * 3 / 6) return 24000 ether;          // the next 1/6 are 24000 $NEWT
    if (tokenId <= MAX_TOKENS * 4 / 6) return 32000 ether;          // the next 1/6 are 32000 $NEWT
    if (tokenId <= MAX_TOKENS * 5 / 6) return 40000 ether;          // the next 1/6 are 40000 $NEWT
    return 48000 ether;                                             // the final 1/6 are 48000 $NEWT
  }

  // Main Mint Functions

        function mint(uint8 amount) public payable whenNotPaused {
        require(amount > 0, "Amount must be more than 0");
        require(amount <= 20, "Amount must be 20 or less");
        require(msg.value == MINT_PRICE * amount, "Ether value sent is not correct");
        require(
            minted + amount <= 2500,
            "Sold out!"
        );

        for (uint256 i = 0; i < amount; i++) {
            _safeMint(msg.sender, ++minted);
        }
    }

    function MintFree(uint8 amount) public payable whenNotPaused {
        require(amount > 0, "Amount must be more than 0");
        require(amount <= 5, "Amount must be 5 or less");
        require(
            minted + amount <= 250,
            "Sold out!"
        );

        for (uint256 i = 0; i < amount; i++) {
            _safeMint(msg.sender, ++minted);
        }
    }



  function mintWITH$NEWT(uint256 amount, bool stake) external payable whenNotPaused {

    address msgSender = _msgSender();

    require(tx.origin == msgSender, "Only EOA");
    require(minted + amount <= MAX_TOKENS, "All tokens minted");
    require(amount > 0 && amount <= 10, "Invalid mint amount");
    
    if (minted < PAID_TOKENS) {


      uint256 mintCostEther = MINT_PRICE * amount;
      if (whitelists[msgSender] == 1) {
          mintCostEther = ( amount - 1) * MINT_PRICE;
          whitelists[msgSender] = 0;
      }
    
      require(minted + amount <= PAID_TOKENS, "All tokens on-sale already sold");
      require(mintCostEther == msg.value, "Invalid payment amount");


    } else {

      require(msg.value == 0);

    }

    uint256 totalNEWTCost = 0;                                                          // $NEWT Cost to mint. 0 is Gen0
    uint16[] memory tokenIds = stake ? new uint16[](amount) : new uint16[](0);          
    uint256 seed;

    for (uint i = 0; i < amount; i++) {
      minted++;
      seed = random(minted);                                                             // NOTES: SUS
      address recipient = selectRecipient(seed);                                         // Selects who the NFT is going to. Gen0 always will be minter. 
      if (!stake || recipient != msgSender) {                                            // recipient != _msgSender() -- IF I BAN CONTRACT, SHIT MIGHT BE GOOOOOFY
        _safeMint(recipient, minted);
      } else {
        _safeMint(address(coven), minted);
        tokenIds[i] = minted;
      }
      totalNEWTCost += mintCost(minted);
    }
    
    if (totalNEWTCost > 0) NEWT.burn(msgSender, totalNEWTCost);
    if (stake) coven.addManyToCovenSideAndFishing(msgSender, tokenIds);
  }





  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  ) public virtual override {
    // Hardcode the Coven's approval so that users don't have to waste gas approving
    if (_msgSender() != address(coven))
      require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
    _transfer(from, to, tokenId);
  }






  // Selects Trait using A.J. Walker's Alias algorithm for O(1) rarity table lookup
  function selectTrait(uint16 seed, uint8 traitType) internal view returns (uint8) {

    uint8 trait = uint8(seed) % uint8(rarities[traitType].length);           
    if (seed >> 8 < rarities[traitType][trait]) return trait;                 
    return aliases[traitType][trait];

  }


  // selects the species and all of its traits based on the seed value
  function selectTraits(uint256 seed) internal view returns (ManDemon memory t) {    
    t.isWitch = (seed & 0xFFFF) % 10 != 0;
    uint8 shift = t.isWitch ? 0 : 9;                                          // 0 if its a Witch, 9 if its Demon

    seed >>= 16;
    if (t.isWitch) {

      // / 0 - 8 are associated with witches, 


      t.traitarray[0] = selectTrait(uint16(seed & 0xFFFF), 0 + shift);
      seed >>= 16;
      t.traitarray[1] = selectTrait(uint16(seed & 0xFFFF), 1 + shift);
      seed >>= 16;
      t.traitarray[2] = selectTrait(uint16(seed & 0xFFFF), 2 + shift);
      seed >>= 16;
      t.traitarray[3] = selectTrait(uint16(seed & 0xFFFF), 3 + shift);
      seed >>= 16;
      t.traitarray[4] = selectTrait(uint16(seed & 0xFFFF), 4 + shift);
      seed >>= 16;
      t.traitarray[5] = selectTrait(uint16(seed & 0xFFFF), 5 + shift);
      seed >>= 16;
      t.traitarray[6] = selectTrait(uint16(seed & 0xFFFF), 6 + shift);
      seed >>= 16;
      t.traitarray[7] = selectTrait(uint16(seed & 0xFFFF), 7 + shift);
      seed >>= 16;
      t.traitarray[8] = selectTrait(uint16(seed & 0xFFFF), 8 + shift);

      t.alphaIndex = 0;




    } else {
      // 9 - 13 are associated with Demons

      t.traitarray[9] = selectTrait(uint16(seed & 0xFFFF), 0 + shift);
      seed >>= 16;
      t.traitarray[10] = selectTrait(uint16(seed & 0xFFFF), 1 + shift);
      seed >>= 16;
      t.traitarray[11] = selectTrait(uint16(seed & 0xFFFF), 2 + shift);
      seed >>= 16;
      t.traitarray[12] = selectTrait(uint16(seed & 0xFFFF), 3 + shift);
      seed >>= 16;
      t.traitarray[13] = selectTrait(uint16(seed & 0xFFFF), 4 + shift);

      t.alphaIndex = t.traitarray[13];
      
      
    }

  }


 
  // Select who the NFT goes to --- The first 20% (ETH purchases) go to the minter & the remaining 80% have a 10% chance to be given to a random staked Demon
  function selectRecipient(uint256 seed) internal view returns (address) {
    if (minted <= PAID_TOKENS || ((seed >> 245) % 10) != 0) return _msgSender();                 // top 10 bits haven't been used
    address thief = coven.randomDemonOwner(seed >> 144);                                          // 144 bits reserved for trait selection
    if (thief == address(0x0)) return _msgSender();
    return thief;
  }


  /** READ */

  function getTokenTraits(uint256 tokenId) external view override returns (ManDemon memory) {
    return tokenTraits[tokenId];
  }

  function getPaidTokens() external view override returns (uint256) {
    return PAID_TOKENS;
  }


  // called after deployment so that the contract can get random Demon thieves
  function setCoven(address _coven) external onlyOwner {
    coven = ICoven(_coven);
    getRandomChainlink();
  }

  // Set Interfaces
  function setInit(address _coven, address erc20Address, address _traits ) public onlyOwner {
    coven = ICoven(_coven);
    NEWT = INEWT(erc20Address);
    // NEWT = IERC20(_NEWT);
    traits = ITraits(_traits);
    getRandomChainlink();
  }
  
  // Set Base URL
  function setURI(string memory _newBaseURI) external onlyOwner {
		  baseURI = _newBaseURI;
  }

  // withdraw functions
    function withdraw(address payable recipient) public onlyOwner {
        require(address(this).balance > 0, "No contract balance");
        recipient.transfer(address(this).balance);
    }



  // updates the number of tokens for sale
  function setPaidTokens(uint256 _paidTokens) external onlyOwner {
    PAID_TOKENS = _paidTokens;
    // MAX_TOKENS = _maxTokens;
    // PAID_TOKENS = _maxTokens / 5;
  }


  // enables owner to pause / unpause minting
  function setPaused(bool _paused) external onlyOwner {
    if (_paused) _pause();
    else _unpause();
  }


  function addWhitelist(address[] calldata addressArrays) external onlyOwner {

    uint256 addylength = addressArrays.length;

    for (uint256 i; i < addylength; i++ ){

          whitelists[addressArrays[i]] = 1;
    }
  }




  /** RENDER */

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


  function _baseURI() internal view virtual override returns (string memory) {
      return baseURI;
  }


  function getTokenIds(address _owner) public view returns (uint256[] memory _tokensOfOwner) {
        _tokensOfOwner = new uint256[](balanceOf(_owner));
        for (uint256 i;i<balanceOf(_owner);i++){
            _tokensOfOwner[i] = tokenOfOwnerByIndex(_owner, i);
        }
  }


      
  /** RANDOMNESSSS */

  function random(uint256 seed) internal view returns (uint256) {
    return uint256(keccak256(abi.encodePacked(
      tx.origin,
      blockhash(block.number - 1),
      block.timestamp,
      seed,
      randomNumber
    )));
  }

  function changeLinkFee(uint256 _fee) external onlyOwner {
    // fee = 0.1 * 10 ** 18; // 0.1 LINK (Varies by network)
    fee = _fee;
  }

  function initChainLink() external onlyOwner {
      getRandomChainlink();
  }

  function getRandomChainlink() internal returns (bytes32 requestId) {

    if (vrfReqd.current() <= vrfcooldown) {
      vrfReqd.increment();
      return 0x000;
    }

    require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
    vrfReqd.reset();
    return requestRandomness(keyHash, fee);
  }

  function changeVrfCooldown(uint256 _cooldown) external onlyOwner{
      vrfcooldown = _cooldown;
  }

  function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
      bytes32 reqId = requestId;
      randomNumber = randomness;
  }

  function withdrawLINK() external onlyOwner {
    uint256 tokenSupply = IERC20(linkToken).balanceOf(address(this));
    IERC20(linkToken).transfer(msg.sender, tokenSupply);
  }


}

// Strings.sol


pragma solidity ^0.8.0;

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_NEWT","type":"address"},{"internalType":"uint256","name":"_maxTokens","type":"uint256"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"}],"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"amount","type":"uint8"}],"name":"MintFree","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"NEWT","outputs":[{"internalType":"contract INEWT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAID_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_mints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addressArrays","type":"address[]"}],"name":"addWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"aliases","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"changeLinkFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cooldown","type":"uint256"}],"name":"changeVrfCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"coven","outputs":[{"internalType":"contract ICoven","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"existingCombinations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPaidTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getTokenIds","outputs":[{"internalType":"uint256[]","name":"_tokensOfOwner","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenTraits","outputs":[{"components":[{"internalType":"bool","name":"isWitch","type":"bool"},{"internalType":"uint8[14]","name":"traitarray","type":"uint8[14]"},{"internalType":"uint8","name":"alphaIndex","type":"uint8"}],"internalType":"struct IWitchesandDemons.ManDemon","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initChainLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"amount","type":"uint8"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"stake","type":"bool"}],"name":"mintWITH$NEWT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minted","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rarities","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":"newUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_coven","type":"address"}],"name":"setCoven","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_coven","type":"address"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"address","name":"_traits","type":"address"}],"name":"setInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_paidTokens","type":"uint256"}],"name":"setPaidTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenTraits","outputs":[{"internalType":"bool","name":"isWitch","type":"bool"},{"internalType":"uint8","name":"alphaIndex","type":"uint8"}],"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":[],"name":"traits","outputs":[{"internalType":"contract ITraits","name":"","type":"address"}],"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":"vrfReqd","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfcooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelists","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawLINK","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052612710603f553480156200001757600080fd5b50604051620041d5380380620041d58339810160408190526200003a91620004bb565b604080518082018252601581527f5769746368657320262044656d6f6e732047616d650000000000000000000000602080830191825283518085019094526007845266574e4447414d4560c81b90840152815185938593929091620000a29160009162000355565b508051620000b890600190602084019062000355565b505050620000d5620000cf620002ff60201b60201c565b62000303565b600a805460ff60a01b191690556001600160601b0319606092831b811660a052911b166080527faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445603a55671bc16d674ec80000603b55603e80546001600160a01b038381166001600160a01b031992831617909255603880549287169290911691909117905560c08390526200016d6005846200050f565b600c556040805160a08101825260008152600160208201526002918101919091526003606082015260046080820152620001ac90602e906005620003e4565b50604080516101408101825260098152600860208201526007918101919091526006606082015260056080820152600460a0820152600360c0820152600260e0820152600161010082015260006101208201526200020f90602f90600a620003e4565b506040805161016081018252600a8152600960208201526008918101919091526007606082015260066080820152600560a0820152600460c0820152600360e08201526002610100820152600161012082015260006101408201526200027a90603090600b620003e4565b506040805160c08101825260058152600460208201526003918101919091526002606082015260016080820152600060a0820152620002be906031906006620003e4565b5060408051608081018252600381526002602082015260019181019190915260006060820152620002f4906032906004620003e4565b50505050506200056f565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620003639062000532565b90600052602060002090601f016020900481019282620003875760008555620003d2565b82601f10620003a257805160ff1916838001178555620003d2565b82800160010185558215620003d2579182015b82811115620003d2578251825591602001919060010190620003b5565b50620003e092915062000487565b5090565b82805482825590600052602060002090601f01602090048101928215620003d25791602002820160005b838211156200044e57835183826101000a81548160ff021916908360ff16021790555092602001926001016020816000010492830192600103026200040e565b80156200047d5782816101000a81549060ff02191690556001016020816000010492830192600103026200044e565b5050620003e09291505b5b80821115620003e0576000815560010162000488565b80516001600160a01b0381168114620004b657600080fd5b919050565b60008060008060808587031215620004d257600080fd5b620004dd856200049e565b935060208501519250620004f4604086016200049e565b915062000504606086016200049e565b905092959194509250565b6000826200052d57634e487b7160e01b600052601260045260246000fd5b500490565b600181811c908216806200054757607f821691505b602082108114156200056957634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c60a05160601c60c051613bff620005d660003960008181610ae501528181610e9301528181610ee101528181610f2f01528181610f7d0152611694015260008181611bbd0152612cb10152600081816127ec0152612c820152613bff6000f3fe6080604052600436106103815760003560e01c80637142f7e3116101d1578063ae0f301511610102578063de6d589e116100a0578063eccd1a8d1161006f578063eccd1a8d14610a73578063edac985b14610a93578063f2fde38b14610ab3578063f47c84c514610ad357600080fd5b8063de6d589e146109a3578063e05c57bf146109b6578063e1fc334f14610a0a578063e985e9c514610a2a57600080fd5b8063c084f540116100dc578063c084f5401461092a578063c87b56dd14610940578063d004b03614610960578063ddca3f431461098d57600080fd5b8063ae0f3015146108cf578063b88d4fde146108ef578063c002d23d1461090f57600080fd5b806394985ddd1161016f57806399e4d8ef1161014957806399e4d8ef14610857578063a1b8f3741461086d578063a22cb4651461089a578063adc2112f146108ba57600080fd5b806394985ddd146107f557806394e568471461081557806395d89b411461084257600080fd5b80637dd4899d116101ab5780637dd4899d1461077757806383a3af5314610797578063873efeff146107b75780638da5cb5b146107d757600080fd5b80637142f7e31461073a578063715018a61461074d5780637a98a82a1461076257600080fd5b80633431a753116102b657806355f804b3116102545780636352211e116102235780636352211e146106d25780636c0360eb146106f25780636ecd23061461070757806370a082311461071a57600080fd5b806355f804b3146103bb578063568303ca1461067c57806357970e93146106935780635c975abb146106b357600080fd5b806342842e0e1161029057806342842e0e146105ee5780634f02c4201461060e5780634f6ccce71461063c57806351cff8d91461065c57600080fd5b80633431a7531461059957806336838391146105b95780634018b1f8146105d957600080fd5b806318160ddd1161032357806327de8f27116102fd57806327de8f27146105075780632f745c59146105275780632fb641c91461054757806333df4b2c1461056757600080fd5b806318160ddd146104a55780631e7be210146104ba57806323b872dd146104e757600080fd5b8063081812fc1161035f578063081812fc146103ff578063095ea7b314610437578063109b1ee61461045757806316c38b3c1461048557600080fd5b806301ffc9a71461038657806302fe5305146103bb57806306fdde03146103dd575b600080fd5b34801561039257600080fd5b506103a66103a1366004613628565b610b07565b60405190151581526020015b60405180910390f35b3480156103c757600080fd5b506103db6103d6366004613662565b610b32565b005b3480156103e957600080fd5b506103f2610b7c565b6040516103b2919061388b565b34801561040b57600080fd5b5061041f61041a3660046136ab565b610c0e565b6040516001600160a01b0390911681526020016103b2565b34801561044357600080fd5b506103db61045236600461352b565b610ca3565b34801561046357600080fd5b5061047761047236600461352b565b610db9565b6040519081526020016103b2565b34801561049157600080fd5b506103db6104a03660046135cc565b610dea565b3480156104b157600080fd5b50600854610477565b3480156104c657600080fd5b506104776104d536600461337e565b600f6020526000908152604090205481565b3480156104f357600080fd5b506103db61050236600461343c565b610e2d565b34801561051357600080fd5b506104776105223660046136ab565b610e79565b34801561053357600080fd5b5061047761054236600461352b565b610fd5565b34801561055357600080fd5b506103db6105623660046133f1565b61106b565b34801561057357600080fd5b50610587610582366004613606565b6110e0565b60405160ff90911681526020016103b2565b3480156105a557600080fd5b506103db6105b43660046136ab565b611126565b3480156105c557600080fd5b506105876105d4366004613606565b611155565b3480156105e557600080fd5b50600c54610477565b3480156105fa57600080fd5b506103db61060936600461343c565b611165565b34801561061a57600080fd5b50600d546106299061ffff1681565b60405161ffff90911681526020016103b2565b34801561064857600080fd5b506104776106573660046136ab565b611180565b34801561066857600080fd5b506103db61067736600461337e565b611213565b34801561068857600080fd5b506040546104779081565b34801561069f57600080fd5b50603e5461041f906001600160a01b031681565b3480156106bf57600080fd5b50600a54600160a01b900460ff166103a6565b3480156106de57600080fd5b5061041f6106ed3660046136ab565b6112b8565b3480156106fe57600080fd5b506103f261132f565b6103db610715366004613702565b6113bd565b34801561072657600080fd5b5061047761073536600461337e565b6115a3565b6103db6107483660046136dd565b61162a565b34801561075957600080fd5b506103db611aec565b34801561076e57600080fd5b506103db611b22565b34801561078357600080fd5b5060375461041f906001600160a01b031681565b3480156107a357600080fd5b506103db6107b23660046136ab565b611b54565b3480156107c357600080fd5b506103db6107d23660046136ab565b611b83565b3480156107e357600080fd5b50600a546001600160a01b031661041f565b34801561080157600080fd5b506103db610810366004613606565b611bb2565b34801561082157600080fd5b506108356108303660046136ab565b611c30565b6040516103b291906139a0565b34801561084e57600080fd5b506103f2611cc5565b34801561086357600080fd5b50610477603f5481565b34801561087957600080fd5b506104776108883660046136ab565b60116020526000908152604090205481565b3480156108a657600080fd5b506103db6108b53660046134fd565b611cd4565b3480156108c657600080fd5b506103db611d99565b3480156108db57600080fd5b506103db6108ea36600461337e565b611ec4565b3480156108fb57600080fd5b506103db61090a36600461347d565b611f11565b34801561091b57600080fd5b506104776658d15e1762800081565b34801561093657600080fd5b50610477600c5481565b34801561094c57600080fd5b506103f261095b3660046136ab565b611f43565b34801561096c57600080fd5b5061098061097b36600461337e565b61201e565b6040516103b29190613847565b34801561099957600080fd5b50610477603b5481565b6103db6109b1366004613702565b6120bf565b3480156109c257600080fd5b506109f16109d13660046136ab565b6010602052600090815260409020805460029091015460ff918216911682565b60408051921515835260ff9091166020830152016103b2565b348015610a1657600080fd5b5060395461041f906001600160a01b031681565b348015610a3657600080fd5b506103a6610a453660046133b8565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610a7f57600080fd5b5060385461041f906001600160a01b031681565b348015610a9f57600080fd5b506103db610aae366004613557565b612220565b348015610abf57600080fd5b506103db610ace36600461337e565b6122af565b348015610adf57600080fd5b506104777f000000000000000000000000000000000000000000000000000000000000000081565b60006001600160e01b0319821663780e9d6360e01b1480610b2c5750610b2c82612347565b92915050565b600a546001600160a01b03163314610b655760405162461bcd60e51b8152600401610b5c9061391a565b60405180910390fd5b8051610b7890600e906020840190613227565b5050565b606060008054610b8b90613a9c565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb790613a9c565b8015610c045780601f10610bd957610100808354040283529160200191610c04565b820191906000526020600020905b815481529060010190602001808311610be757829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610c875760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b5c565b506000908152600460205260409020546001600160a01b031690565b6000610cae826112b8565b9050806001600160a01b0316836001600160a01b03161415610d1c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b5c565b336001600160a01b0382161480610d385750610d388133610a45565b610daa5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b5c565b610db48383612397565b505050565b60126020528160005260406000208181548110610dd557600080fd5b90600052602060002001600091509150505481565b600a546001600160a01b03163314610e145760405162461bcd60e51b8152600401610b5c9061391a565b8015610e2557610e22612405565b50565b610e22612487565b6037546001600160a01b0316336001600160a01b031614610e6e57610e52338261250b565b610e6e5760405162461bcd60e51b8152600401610b5c9061394f565b610db4838383612602565b6000600c548211610e8c57506000919050565b6006610eb97f00000000000000000000000000000000000000000000000000000000000000006002613a3a565b610ec39190613a26565b8211610eda57506903635c9adc5dea000000919050565b6006610f077f00000000000000000000000000000000000000000000000000000000000000006003613a3a565b610f119190613a26565b8211610f2857506905150ae84a8cdf000000919050565b6006610f557f00000000000000000000000000000000000000000000000000000000000000006004613a3a565b610f5f9190613a26565b8211610f7657506906c6b935b8bbd4000000919050565b6006610fa37f00000000000000000000000000000000000000000000000000000000000000006005613a3a565b610fad9190613a26565b8211610fc45750690878678326eac9000000919050565b50690a2a15d09519be000000919050565b6000610fe0836115a3565b82106110425760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610b5c565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b031633146110955760405162461bcd60e51b8152600401610b5c9061391a565b603780546001600160a01b038086166001600160a01b0319928316179092556038805485841690831617905560398054928416929091169190911790556110da6127ad565b50505050565b601382601281106110f057600080fd5b0181815481106110ff57600080fd5b9060005260206000209060209182820401919006915091509054906101000a900460ff1681565b600a546001600160a01b031633146111505760405162461bcd60e51b8152600401610b5c9061391a565b600c55565b602582601281106110f057600080fd5b610db483838360405180602001604052806000815250611f11565b600061118b60085490565b82106111ee5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610b5c565b6008828154811061120157611201613b64565b90600052602060002001549050919050565b600a546001600160a01b0316331461123d5760405162461bcd60e51b8152600401610b5c9061391a565b600047116112835760405162461bcd60e51b81526020600482015260136024820152724e6f20636f6e74726163742062616c616e636560681b6044820152606401610b5c565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610b78573d6000803e3d6000fd5b6000818152600260205260408120546001600160a01b031680610b2c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610b5c565b600e805461133c90613a9c565b80601f016020809104026020016040519081016040528092919081815260200182805461136890613a9c565b80156113b55780601f1061138a576101008083540402835291602001916113b5565b820191906000526020600020905b81548152906001019060200180831161139857829003601f168201915b505050505081565b600a54600160a01b900460ff16156113e75760405162461bcd60e51b8152600401610b5c906138f0565b60008160ff161161143a5760405162461bcd60e51b815260206004820152601a60248201527f416d6f756e74206d757374206265206d6f7265207468616e20300000000000006044820152606401610b5c565b60148160ff16111561148e5760405162461bcd60e51b815260206004820152601960248201527f416d6f756e74206d757374206265203230206f72206c657373000000000000006044820152606401610b5c565b6114a260ff82166658d15e17628000613a3a565b34146114f05760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610b5c565b600d546109c4906115099060ff84169061ffff166139f1565b61ffff1611156115475760405162461bcd60e51b8152602060048201526009602482015268536f6c64206f75742160b81b6044820152606401610b5c565b60005b8160ff16811015610b7857600d805461159191339160009061156f9061ffff16613ad1565b91906101000a81548161ffff021916908361ffff160217905561ffff166128e8565b8061159b81613af3565b91505061154a565b60006001600160a01b03821661160e5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b5c565b506001600160a01b031660009081526003602052604090205490565b600a54600160a01b900460ff16156116545760405162461bcd60e51b8152600401610b5c906138f0565b3332811461168f5760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b6044820152606401610b5c565b600d547f0000000000000000000000000000000000000000000000000000000000000000906116c390859061ffff16613a0e565b11156117055760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610b5c565b6000831180156117165750600a8311155b6117585760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610b5c565b600c54600d5461ffff16101561188957600061177b846658d15e17628000613a3a565b6001600160a01b0383166000908152600f6020526040902054909150600114156117d8576658d15e176280006117b2600186613a59565b6117bc9190613a3a565b6001600160a01b0383166000908152600f602052604081205590505b600c54600d546117ed90869061ffff16613a0e565b111561183b5760405162461bcd60e51b815260206004820152601f60248201527f416c6c20746f6b656e73206f6e2d73616c6520616c726561647920736f6c64006044820152606401610b5c565b3481146118835760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c185e5b595b9d08185b5bdd5b9d60521b6044820152606401610b5c565b50611894565b341561189457600080fd5b600080836118b0576040805160008152602081019091526118f4565b8467ffffffffffffffff8111156118c9576118c9613b7a565b6040519080825280602002602001820160405280156118f2578160200160208202803683370190505b505b90506000805b86811015611a0b57600d805461ffff1690600061191683613ad1565b82546101009290920a61ffff818102199093169183160217909155600d5461193f925016612902565b9150600061194c8361296a565b905086158061196d5750856001600160a01b0316816001600160a01b031614155b1561198957600d5461198490829061ffff166128e8565b6119db565b603754600d546119a6916001600160a01b03169061ffff166128e8565b600d54845161ffff909116908590849081106119c4576119c4613b64565b602002602001019061ffff16908161ffff16815250505b600d546119eb9061ffff16610e79565b6119f59086613a0e565b9450508080611a0390613af3565b9150506118fa565b508215611a7957603854604051632770a7eb60e21b81526001600160a01b0386811660048301526024820186905290911690639dc29fac90604401600060405180830381600087803b158015611a6057600080fd5b505af1158015611a74573d6000803e3d6000fd5b505050505b8415611ae4576037546040516393866a0b60e01b81526001600160a01b03909116906393866a0b90611ab190879086906004016137bd565b600060405180830381600087803b158015611acb57600080fd5b505af1158015611adf573d6000803e3d6000fd5b505050505b505050505050565b600a546001600160a01b03163314611b165760405162461bcd60e51b8152600401610b5c9061391a565b611b206000612a34565b565b600a546001600160a01b03163314611b4c5760405162461bcd60e51b8152600401610b5c9061391a565b610e226127ad565b600a546001600160a01b03163314611b7e5760405162461bcd60e51b8152600401610b5c9061391a565b603f55565b600a546001600160a01b03163314611bad5760405162461bcd60e51b8152600401610b5c9061391a565b603b55565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611c2a5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610b5c565b603d5550565b611c386132ab565b60008281526010602090815260408083208151606081018352815460ff161515815282516101c08101938490529094919385019290916001850191600e918390855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411611c7a575050509284525050506002919091015460ff1660209091015292915050565b606060018054610b8b90613a9c565b6001600160a01b038216331415611d2d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b5c565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b03163314611dc35760405162461bcd60e51b8152600401610b5c9061391a565b603e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015611e0757600080fd5b505afa158015611e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3f91906136c4565b603e5460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb90604401602060405180830381600087803b158015611e8c57600080fd5b505af1158015611ea0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7891906135e9565b600a546001600160a01b03163314611eee5760405162461bcd60e51b8152600401610b5c9061391a565b603780546001600160a01b0319166001600160a01b038316179055610b786127ad565b611f1b338361250b565b611f375760405162461bcd60e51b8152600401610b5c9061394f565b6110da84848484612a86565b6000818152600260205260409020546060906001600160a01b0316611fc25760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610b5c565b6000611fcc612ab9565b90506000815111611fec5760405180602001604052806000815250612017565b80611ff684612ac8565b604051602001612007929190613751565b6040516020818303038152906040525b9392505050565b6060612029826115a3565b67ffffffffffffffff81111561204157612041613b7a565b60405190808252806020026020018201604052801561206a578160200160208202803683370190505b50905060005b612079836115a3565b8110156120b95761208a8382610fd5565b82828151811061209c5761209c613b64565b6020908102919091010152806120b181613af3565b915050612070565b50919050565b600a54600160a01b900460ff16156120e95760405162461bcd60e51b8152600401610b5c906138f0565b60008160ff161161213c5760405162461bcd60e51b815260206004820152601a60248201527f416d6f756e74206d757374206265206d6f7265207468616e20300000000000006044820152606401610b5c565b60058160ff1611156121905760405162461bcd60e51b815260206004820152601860248201527f416d6f756e74206d7573742062652035206f72206c65737300000000000000006044820152606401610b5c565b600d5460fa906121a89060ff84169061ffff166139f1565b61ffff1611156121e65760405162461bcd60e51b8152602060048201526009602482015268536f6c64206f75742160b81b6044820152606401610b5c565b60005b8160ff16811015610b7857600d805461220e91339160009061156f9061ffff16613ad1565b8061221881613af3565b9150506121e9565b600a546001600160a01b0316331461224a5760405162461bcd60e51b8152600401610b5c9061391a565b8060005b818110156110da576001600f600086868581811061226e5761226e613b64565b9050602002016020810190612283919061337e565b6001600160a01b03168152602081019190915260400160002055806122a781613af3565b91505061224e565b600a546001600160a01b031633146122d95760405162461bcd60e51b8152600401610b5c9061391a565b6001600160a01b03811661233e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b5c565b610e2281612a34565b60006001600160e01b031982166380ac58cd60e01b148061237857506001600160e01b03198216635b5e139f60e01b145b80610b2c57506301ffc9a760e01b6001600160e01b0319831614610b2c565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906123cc826112b8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600160a01b900460ff161561242f5760405162461bcd60e51b8152600401610b5c906138f0565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861246a3390565b6040516001600160a01b03909116815260200160405180910390a1565b600a54600160a01b900460ff166124d75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610b5c565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361246a565b6000818152600260205260408120546001600160a01b03166125845760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b5c565b600061258f836112b8565b9050806001600160a01b0316846001600160a01b031614806125ca5750836001600160a01b03166125bf84610c0e565b6001600160a01b0316145b806125fa57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612615826112b8565b6001600160a01b03161461267d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b5c565b6001600160a01b0382166126df5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b5c565b6126ea838383612bc6565b6126f5600082612397565b6001600160a01b038316600090815260036020526040812080546001929061271e908490613a59565b90915550506001600160a01b038216600090815260036020526040812080546001929061274c908490613a0e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000603f546127bb60405490565b116127d4576127ce604080546001019055565b50600090565b603b546040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561283657600080fd5b505afa15801561284a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286e91906136c4565b10156128d05760405162461bcd60e51b815260206004820152602b60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e74726163742060448201526a1dda5d1a0819985d58d95d60aa1b6064820152608401610b5c565b60006040556128e3603a54603b54612c7e565b905090565b610b78828260405180602001604052806000815250612e09565b600032612910600143613a59565b603d5460405160609390931b6bffffffffffffffffffffffff191660208401529040603483015242605483015260748201849052609482015260b40160408051601f19818403018152919052805160209091012092915050565b600c54600d5460009161ffff9091161115806129935750612990600a60f584901c613b0e565b15155b1561299e5733610b2c565b603754604051633b1f4e8760e11b8152609084901c60048201526000916001600160a01b03169063763e9d0e9060240160206040518083038186803b1580156129e657600080fd5b505afa1580156129fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1e919061339b565b90506001600160a01b038116610b2c5733612017565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612a91848484612602565b612a9d84848484612e3c565b6110da5760405162461bcd60e51b8152600401610b5c9061389e565b6060600e8054610b8b90613a9c565b606081612aec5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612b165780612b0081613af3565b9150612b0f9050600a83613a26565b9150612af0565b60008167ffffffffffffffff811115612b3157612b31613b7a565b6040519080825280601f01601f191660200182016040528015612b5b576020820181803683370190505b5090505b84156125fa57612b70600183613a59565b9150612b7d600a86613b0e565b612b88906030613a0e565b60f81b818381518110612b9d57612b9d613b64565b60200101906001600160f81b031916908160001a905350612bbf600a86613a26565b9450612b5f565b6001600160a01b038316612c2157612c1c81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612c44565b816001600160a01b0316836001600160a01b031614612c4457612c448382612f49565b6001600160a01b038216612c5b57610db481612fe6565b826001600160a01b0316826001600160a01b031614610db457610db48282613095565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001612cee929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612d1b93929190613817565b602060405180830381600087803b158015612d3557600080fd5b505af1158015612d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6d91906135e9565b506000838152600b6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052612dc9906001613a0e565b6000858152600b60205260409020556125fa8482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b612e1383836130d9565b612e206000848484612e3c565b610db45760405162461bcd60e51b8152600401610b5c9061389e565b60006001600160a01b0384163b15612f3e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e80903390899088908890600401613780565b602060405180830381600087803b158015612e9a57600080fd5b505af1925050508015612eca575060408051601f3d908101601f19168201909252612ec791810190613645565b60015b612f24573d808015612ef8576040519150601f19603f3d011682016040523d82523d6000602084013e612efd565b606091505b508051612f1c5760405162461bcd60e51b8152600401610b5c9061389e565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506125fa565b506001949350505050565b60006001612f56846115a3565b612f609190613a59565b600083815260076020526040902054909150808214612fb3576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612ff890600190613a59565b6000838152600960205260408120546008805493945090928490811061302057613020613b64565b90600052602060002001549050806008838154811061304157613041613b64565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061307957613079613b4e565b6001900381819060005260206000200160009055905550505050565b60006130a0836115a3565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b03821661312f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b5c565b6000818152600260205260409020546001600160a01b0316156131945760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b5c565b6131a060008383612bc6565b6001600160a01b03821660009081526003602052604081208054600192906131c9908490613a0e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461323390613a9c565b90600052602060002090601f016020900481019282613255576000855561329b565b82601f1061326e57805160ff191683800117855561329b565b8280016001018555821561329b579182015b8281111561329b578251825591602001919060010190613280565b506132a79291506132d4565b5090565b60405180606001604052806000151581526020016132c76132e9565b8152600060209091015290565b5b808211156132a757600081556001016132d5565b604051806101c00160405280600e906020820280368337509192915050565b600067ffffffffffffffff8084111561332357613323613b7a565b604051601f8501601f19908116603f0116810190828211818310171561334b5761334b613b7a565b8160405280935085815286868601111561336457600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561339057600080fd5b813561201781613b90565b6000602082840312156133ad57600080fd5b815161201781613b90565b600080604083850312156133cb57600080fd5b82356133d681613b90565b915060208301356133e681613b90565b809150509250929050565b60008060006060848603121561340657600080fd5b833561341181613b90565b9250602084013561342181613b90565b9150604084013561343181613b90565b809150509250925092565b60008060006060848603121561345157600080fd5b833561345c81613b90565b9250602084013561346c81613b90565b929592945050506040919091013590565b6000806000806080858703121561349357600080fd5b843561349e81613b90565b935060208501356134ae81613b90565b925060408501359150606085013567ffffffffffffffff8111156134d157600080fd5b8501601f810187136134e257600080fd5b6134f187823560208401613308565b91505092959194509250565b6000806040838503121561351057600080fd5b823561351b81613b90565b915060208301356133e681613ba5565b6000806040838503121561353e57600080fd5b823561354981613b90565b946020939093013593505050565b6000806020838503121561356a57600080fd5b823567ffffffffffffffff8082111561358257600080fd5b818501915085601f83011261359657600080fd5b8135818111156135a557600080fd5b8660208260051b85010111156135ba57600080fd5b60209290920196919550909350505050565b6000602082840312156135de57600080fd5b813561201781613ba5565b6000602082840312156135fb57600080fd5b815161201781613ba5565b6000806040838503121561361957600080fd5b50508035926020909101359150565b60006020828403121561363a57600080fd5b813561201781613bb3565b60006020828403121561365757600080fd5b815161201781613bb3565b60006020828403121561367457600080fd5b813567ffffffffffffffff81111561368b57600080fd5b8201601f8101841361369c57600080fd5b6125fa84823560208401613308565b6000602082840312156136bd57600080fd5b5035919050565b6000602082840312156136d657600080fd5b5051919050565b600080604083850312156136f057600080fd5b8235915060208301356133e681613ba5565b60006020828403121561371457600080fd5b813560ff8116811461201757600080fd5b6000815180845261373d816020860160208601613a70565b601f01601f19169290920160200192915050565b60008351613763818460208801613a70565b835190830190613777818360208801613a70565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906137b390830184613725565b9695505050505050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b8181101561380a57845161ffff16835293830193918301916001016137ea565b5090979650505050505050565b60018060a01b038416815282602082015260606040820152600061383e6060830184613725565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561387f57835183529284019291840191600101613863565b50909695505050505050565b6020815260006120176020830184613725565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b8151151581526020808301516102008301919081840160005b600e8110156139d957825160ff16825291830191908301906001016139b9565b5050505060ff6040840151166101e083015292915050565b600061ffff80831681851680830382111561377757613777613b22565b60008219821115613a2157613a21613b22565b500190565b600082613a3557613a35613b38565b500490565b6000816000190483118215151615613a5457613a54613b22565b500290565b600082821015613a6b57613a6b613b22565b500390565b60005b83811015613a8b578181015183820152602001613a73565b838111156110da5750506000910152565b600181811c90821680613ab057607f821691505b602082108114156120b957634e487b7160e01b600052602260045260246000fd5b600061ffff80831681811415613ae957613ae9613b22565b6001019392505050565b6000600019821415613b0757613b07613b22565b5060010190565b600082613b1d57613b1d613b38565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610e2257600080fd5b8015158114610e2257600080fd5b6001600160e01b031981168114610e2257600080fdfea264697066735822122024b37e212aafe5cf6f1b7f24d74ea141717c5d2e041a131d4e697d559668353b64736f6c6343000807003300000000000000000000000003e25f2d9d34e2e5f9a3659695f8b470ce6c69df0000000000000000000000000000000000000000000000000000000000003a980000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1

Deployed Bytecode

0x6080604052600436106103815760003560e01c80637142f7e3116101d1578063ae0f301511610102578063de6d589e116100a0578063eccd1a8d1161006f578063eccd1a8d14610a73578063edac985b14610a93578063f2fde38b14610ab3578063f47c84c514610ad357600080fd5b8063de6d589e146109a3578063e05c57bf146109b6578063e1fc334f14610a0a578063e985e9c514610a2a57600080fd5b8063c084f540116100dc578063c084f5401461092a578063c87b56dd14610940578063d004b03614610960578063ddca3f431461098d57600080fd5b8063ae0f3015146108cf578063b88d4fde146108ef578063c002d23d1461090f57600080fd5b806394985ddd1161016f57806399e4d8ef1161014957806399e4d8ef14610857578063a1b8f3741461086d578063a22cb4651461089a578063adc2112f146108ba57600080fd5b806394985ddd146107f557806394e568471461081557806395d89b411461084257600080fd5b80637dd4899d116101ab5780637dd4899d1461077757806383a3af5314610797578063873efeff146107b75780638da5cb5b146107d757600080fd5b80637142f7e31461073a578063715018a61461074d5780637a98a82a1461076257600080fd5b80633431a753116102b657806355f804b3116102545780636352211e116102235780636352211e146106d25780636c0360eb146106f25780636ecd23061461070757806370a082311461071a57600080fd5b806355f804b3146103bb578063568303ca1461067c57806357970e93146106935780635c975abb146106b357600080fd5b806342842e0e1161029057806342842e0e146105ee5780634f02c4201461060e5780634f6ccce71461063c57806351cff8d91461065c57600080fd5b80633431a7531461059957806336838391146105b95780634018b1f8146105d957600080fd5b806318160ddd1161032357806327de8f27116102fd57806327de8f27146105075780632f745c59146105275780632fb641c91461054757806333df4b2c1461056757600080fd5b806318160ddd146104a55780631e7be210146104ba57806323b872dd146104e757600080fd5b8063081812fc1161035f578063081812fc146103ff578063095ea7b314610437578063109b1ee61461045757806316c38b3c1461048557600080fd5b806301ffc9a71461038657806302fe5305146103bb57806306fdde03146103dd575b600080fd5b34801561039257600080fd5b506103a66103a1366004613628565b610b07565b60405190151581526020015b60405180910390f35b3480156103c757600080fd5b506103db6103d6366004613662565b610b32565b005b3480156103e957600080fd5b506103f2610b7c565b6040516103b2919061388b565b34801561040b57600080fd5b5061041f61041a3660046136ab565b610c0e565b6040516001600160a01b0390911681526020016103b2565b34801561044357600080fd5b506103db61045236600461352b565b610ca3565b34801561046357600080fd5b5061047761047236600461352b565b610db9565b6040519081526020016103b2565b34801561049157600080fd5b506103db6104a03660046135cc565b610dea565b3480156104b157600080fd5b50600854610477565b3480156104c657600080fd5b506104776104d536600461337e565b600f6020526000908152604090205481565b3480156104f357600080fd5b506103db61050236600461343c565b610e2d565b34801561051357600080fd5b506104776105223660046136ab565b610e79565b34801561053357600080fd5b5061047761054236600461352b565b610fd5565b34801561055357600080fd5b506103db6105623660046133f1565b61106b565b34801561057357600080fd5b50610587610582366004613606565b6110e0565b60405160ff90911681526020016103b2565b3480156105a557600080fd5b506103db6105b43660046136ab565b611126565b3480156105c557600080fd5b506105876105d4366004613606565b611155565b3480156105e557600080fd5b50600c54610477565b3480156105fa57600080fd5b506103db61060936600461343c565b611165565b34801561061a57600080fd5b50600d546106299061ffff1681565b60405161ffff90911681526020016103b2565b34801561064857600080fd5b506104776106573660046136ab565b611180565b34801561066857600080fd5b506103db61067736600461337e565b611213565b34801561068857600080fd5b506040546104779081565b34801561069f57600080fd5b50603e5461041f906001600160a01b031681565b3480156106bf57600080fd5b50600a54600160a01b900460ff166103a6565b3480156106de57600080fd5b5061041f6106ed3660046136ab565b6112b8565b3480156106fe57600080fd5b506103f261132f565b6103db610715366004613702565b6113bd565b34801561072657600080fd5b5061047761073536600461337e565b6115a3565b6103db6107483660046136dd565b61162a565b34801561075957600080fd5b506103db611aec565b34801561076e57600080fd5b506103db611b22565b34801561078357600080fd5b5060375461041f906001600160a01b031681565b3480156107a357600080fd5b506103db6107b23660046136ab565b611b54565b3480156107c357600080fd5b506103db6107d23660046136ab565b611b83565b3480156107e357600080fd5b50600a546001600160a01b031661041f565b34801561080157600080fd5b506103db610810366004613606565b611bb2565b34801561082157600080fd5b506108356108303660046136ab565b611c30565b6040516103b291906139a0565b34801561084e57600080fd5b506103f2611cc5565b34801561086357600080fd5b50610477603f5481565b34801561087957600080fd5b506104776108883660046136ab565b60116020526000908152604090205481565b3480156108a657600080fd5b506103db6108b53660046134fd565b611cd4565b3480156108c657600080fd5b506103db611d99565b3480156108db57600080fd5b506103db6108ea36600461337e565b611ec4565b3480156108fb57600080fd5b506103db61090a36600461347d565b611f11565b34801561091b57600080fd5b506104776658d15e1762800081565b34801561093657600080fd5b50610477600c5481565b34801561094c57600080fd5b506103f261095b3660046136ab565b611f43565b34801561096c57600080fd5b5061098061097b36600461337e565b61201e565b6040516103b29190613847565b34801561099957600080fd5b50610477603b5481565b6103db6109b1366004613702565b6120bf565b3480156109c257600080fd5b506109f16109d13660046136ab565b6010602052600090815260409020805460029091015460ff918216911682565b60408051921515835260ff9091166020830152016103b2565b348015610a1657600080fd5b5060395461041f906001600160a01b031681565b348015610a3657600080fd5b506103a6610a453660046133b8565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610a7f57600080fd5b5060385461041f906001600160a01b031681565b348015610a9f57600080fd5b506103db610aae366004613557565b612220565b348015610abf57600080fd5b506103db610ace36600461337e565b6122af565b348015610adf57600080fd5b506104777f0000000000000000000000000000000000000000000000000000000000003a9881565b60006001600160e01b0319821663780e9d6360e01b1480610b2c5750610b2c82612347565b92915050565b600a546001600160a01b03163314610b655760405162461bcd60e51b8152600401610b5c9061391a565b60405180910390fd5b8051610b7890600e906020840190613227565b5050565b606060008054610b8b90613a9c565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb790613a9c565b8015610c045780601f10610bd957610100808354040283529160200191610c04565b820191906000526020600020905b815481529060010190602001808311610be757829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610c875760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b5c565b506000908152600460205260409020546001600160a01b031690565b6000610cae826112b8565b9050806001600160a01b0316836001600160a01b03161415610d1c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b5c565b336001600160a01b0382161480610d385750610d388133610a45565b610daa5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b5c565b610db48383612397565b505050565b60126020528160005260406000208181548110610dd557600080fd5b90600052602060002001600091509150505481565b600a546001600160a01b03163314610e145760405162461bcd60e51b8152600401610b5c9061391a565b8015610e2557610e22612405565b50565b610e22612487565b6037546001600160a01b0316336001600160a01b031614610e6e57610e52338261250b565b610e6e5760405162461bcd60e51b8152600401610b5c9061394f565b610db4838383612602565b6000600c548211610e8c57506000919050565b6006610eb97f0000000000000000000000000000000000000000000000000000000000003a986002613a3a565b610ec39190613a26565b8211610eda57506903635c9adc5dea000000919050565b6006610f077f0000000000000000000000000000000000000000000000000000000000003a986003613a3a565b610f119190613a26565b8211610f2857506905150ae84a8cdf000000919050565b6006610f557f0000000000000000000000000000000000000000000000000000000000003a986004613a3a565b610f5f9190613a26565b8211610f7657506906c6b935b8bbd4000000919050565b6006610fa37f0000000000000000000000000000000000000000000000000000000000003a986005613a3a565b610fad9190613a26565b8211610fc45750690878678326eac9000000919050565b50690a2a15d09519be000000919050565b6000610fe0836115a3565b82106110425760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610b5c565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b031633146110955760405162461bcd60e51b8152600401610b5c9061391a565b603780546001600160a01b038086166001600160a01b0319928316179092556038805485841690831617905560398054928416929091169190911790556110da6127ad565b50505050565b601382601281106110f057600080fd5b0181815481106110ff57600080fd5b9060005260206000209060209182820401919006915091509054906101000a900460ff1681565b600a546001600160a01b031633146111505760405162461bcd60e51b8152600401610b5c9061391a565b600c55565b602582601281106110f057600080fd5b610db483838360405180602001604052806000815250611f11565b600061118b60085490565b82106111ee5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610b5c565b6008828154811061120157611201613b64565b90600052602060002001549050919050565b600a546001600160a01b0316331461123d5760405162461bcd60e51b8152600401610b5c9061391a565b600047116112835760405162461bcd60e51b81526020600482015260136024820152724e6f20636f6e74726163742062616c616e636560681b6044820152606401610b5c565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610b78573d6000803e3d6000fd5b6000818152600260205260408120546001600160a01b031680610b2c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610b5c565b600e805461133c90613a9c565b80601f016020809104026020016040519081016040528092919081815260200182805461136890613a9c565b80156113b55780601f1061138a576101008083540402835291602001916113b5565b820191906000526020600020905b81548152906001019060200180831161139857829003601f168201915b505050505081565b600a54600160a01b900460ff16156113e75760405162461bcd60e51b8152600401610b5c906138f0565b60008160ff161161143a5760405162461bcd60e51b815260206004820152601a60248201527f416d6f756e74206d757374206265206d6f7265207468616e20300000000000006044820152606401610b5c565b60148160ff16111561148e5760405162461bcd60e51b815260206004820152601960248201527f416d6f756e74206d757374206265203230206f72206c657373000000000000006044820152606401610b5c565b6114a260ff82166658d15e17628000613a3a565b34146114f05760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610b5c565b600d546109c4906115099060ff84169061ffff166139f1565b61ffff1611156115475760405162461bcd60e51b8152602060048201526009602482015268536f6c64206f75742160b81b6044820152606401610b5c565b60005b8160ff16811015610b7857600d805461159191339160009061156f9061ffff16613ad1565b91906101000a81548161ffff021916908361ffff160217905561ffff166128e8565b8061159b81613af3565b91505061154a565b60006001600160a01b03821661160e5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b5c565b506001600160a01b031660009081526003602052604090205490565b600a54600160a01b900460ff16156116545760405162461bcd60e51b8152600401610b5c906138f0565b3332811461168f5760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b6044820152606401610b5c565b600d547f0000000000000000000000000000000000000000000000000000000000003a98906116c390859061ffff16613a0e565b11156117055760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610b5c565b6000831180156117165750600a8311155b6117585760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610b5c565b600c54600d5461ffff16101561188957600061177b846658d15e17628000613a3a565b6001600160a01b0383166000908152600f6020526040902054909150600114156117d8576658d15e176280006117b2600186613a59565b6117bc9190613a3a565b6001600160a01b0383166000908152600f602052604081205590505b600c54600d546117ed90869061ffff16613a0e565b111561183b5760405162461bcd60e51b815260206004820152601f60248201527f416c6c20746f6b656e73206f6e2d73616c6520616c726561647920736f6c64006044820152606401610b5c565b3481146118835760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c185e5b595b9d08185b5bdd5b9d60521b6044820152606401610b5c565b50611894565b341561189457600080fd5b600080836118b0576040805160008152602081019091526118f4565b8467ffffffffffffffff8111156118c9576118c9613b7a565b6040519080825280602002602001820160405280156118f2578160200160208202803683370190505b505b90506000805b86811015611a0b57600d805461ffff1690600061191683613ad1565b82546101009290920a61ffff818102199093169183160217909155600d5461193f925016612902565b9150600061194c8361296a565b905086158061196d5750856001600160a01b0316816001600160a01b031614155b1561198957600d5461198490829061ffff166128e8565b6119db565b603754600d546119a6916001600160a01b03169061ffff166128e8565b600d54845161ffff909116908590849081106119c4576119c4613b64565b602002602001019061ffff16908161ffff16815250505b600d546119eb9061ffff16610e79565b6119f59086613a0e565b9450508080611a0390613af3565b9150506118fa565b508215611a7957603854604051632770a7eb60e21b81526001600160a01b0386811660048301526024820186905290911690639dc29fac90604401600060405180830381600087803b158015611a6057600080fd5b505af1158015611a74573d6000803e3d6000fd5b505050505b8415611ae4576037546040516393866a0b60e01b81526001600160a01b03909116906393866a0b90611ab190879086906004016137bd565b600060405180830381600087803b158015611acb57600080fd5b505af1158015611adf573d6000803e3d6000fd5b505050505b505050505050565b600a546001600160a01b03163314611b165760405162461bcd60e51b8152600401610b5c9061391a565b611b206000612a34565b565b600a546001600160a01b03163314611b4c5760405162461bcd60e51b8152600401610b5c9061391a565b610e226127ad565b600a546001600160a01b03163314611b7e5760405162461bcd60e51b8152600401610b5c9061391a565b603f55565b600a546001600160a01b03163314611bad5760405162461bcd60e51b8152600401610b5c9061391a565b603b55565b336001600160a01b037f0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae01614611c2a5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610b5c565b603d5550565b611c386132ab565b60008281526010602090815260408083208151606081018352815460ff161515815282516101c08101938490529094919385019290916001850191600e918390855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411611c7a575050509284525050506002919091015460ff1660209091015292915050565b606060018054610b8b90613a9c565b6001600160a01b038216331415611d2d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b5c565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b03163314611dc35760405162461bcd60e51b8152600401610b5c9061391a565b603e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015611e0757600080fd5b505afa158015611e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3f91906136c4565b603e5460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb90604401602060405180830381600087803b158015611e8c57600080fd5b505af1158015611ea0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7891906135e9565b600a546001600160a01b03163314611eee5760405162461bcd60e51b8152600401610b5c9061391a565b603780546001600160a01b0319166001600160a01b038316179055610b786127ad565b611f1b338361250b565b611f375760405162461bcd60e51b8152600401610b5c9061394f565b6110da84848484612a86565b6000818152600260205260409020546060906001600160a01b0316611fc25760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610b5c565b6000611fcc612ab9565b90506000815111611fec5760405180602001604052806000815250612017565b80611ff684612ac8565b604051602001612007929190613751565b6040516020818303038152906040525b9392505050565b6060612029826115a3565b67ffffffffffffffff81111561204157612041613b7a565b60405190808252806020026020018201604052801561206a578160200160208202803683370190505b50905060005b612079836115a3565b8110156120b95761208a8382610fd5565b82828151811061209c5761209c613b64565b6020908102919091010152806120b181613af3565b915050612070565b50919050565b600a54600160a01b900460ff16156120e95760405162461bcd60e51b8152600401610b5c906138f0565b60008160ff161161213c5760405162461bcd60e51b815260206004820152601a60248201527f416d6f756e74206d757374206265206d6f7265207468616e20300000000000006044820152606401610b5c565b60058160ff1611156121905760405162461bcd60e51b815260206004820152601860248201527f416d6f756e74206d7573742062652035206f72206c65737300000000000000006044820152606401610b5c565b600d5460fa906121a89060ff84169061ffff166139f1565b61ffff1611156121e65760405162461bcd60e51b8152602060048201526009602482015268536f6c64206f75742160b81b6044820152606401610b5c565b60005b8160ff16811015610b7857600d805461220e91339160009061156f9061ffff16613ad1565b8061221881613af3565b9150506121e9565b600a546001600160a01b0316331461224a5760405162461bcd60e51b8152600401610b5c9061391a565b8060005b818110156110da576001600f600086868581811061226e5761226e613b64565b9050602002016020810190612283919061337e565b6001600160a01b03168152602081019190915260400160002055806122a781613af3565b91505061224e565b600a546001600160a01b031633146122d95760405162461bcd60e51b8152600401610b5c9061391a565b6001600160a01b03811661233e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b5c565b610e2281612a34565b60006001600160e01b031982166380ac58cd60e01b148061237857506001600160e01b03198216635b5e139f60e01b145b80610b2c57506301ffc9a760e01b6001600160e01b0319831614610b2c565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906123cc826112b8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600160a01b900460ff161561242f5760405162461bcd60e51b8152600401610b5c906138f0565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861246a3390565b6040516001600160a01b03909116815260200160405180910390a1565b600a54600160a01b900460ff166124d75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610b5c565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361246a565b6000818152600260205260408120546001600160a01b03166125845760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b5c565b600061258f836112b8565b9050806001600160a01b0316846001600160a01b031614806125ca5750836001600160a01b03166125bf84610c0e565b6001600160a01b0316145b806125fa57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612615826112b8565b6001600160a01b03161461267d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b5c565b6001600160a01b0382166126df5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b5c565b6126ea838383612bc6565b6126f5600082612397565b6001600160a01b038316600090815260036020526040812080546001929061271e908490613a59565b90915550506001600160a01b038216600090815260036020526040812080546001929061274c908490613a0e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000603f546127bb60405490565b116127d4576127ce604080546001019055565b50600090565b603b546040516370a0823160e01b81523060048201527f000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f16001600160a01b0316906370a082319060240160206040518083038186803b15801561283657600080fd5b505afa15801561284a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286e91906136c4565b10156128d05760405162461bcd60e51b815260206004820152602b60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e74726163742060448201526a1dda5d1a0819985d58d95d60aa1b6064820152608401610b5c565b60006040556128e3603a54603b54612c7e565b905090565b610b78828260405180602001604052806000815250612e09565b600032612910600143613a59565b603d5460405160609390931b6bffffffffffffffffffffffff191660208401529040603483015242605483015260748201849052609482015260b40160408051601f19818403018152919052805160209091012092915050565b600c54600d5460009161ffff9091161115806129935750612990600a60f584901c613b0e565b15155b1561299e5733610b2c565b603754604051633b1f4e8760e11b8152609084901c60048201526000916001600160a01b03169063763e9d0e9060240160206040518083038186803b1580156129e657600080fd5b505afa1580156129fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1e919061339b565b90506001600160a01b038116610b2c5733612017565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612a91848484612602565b612a9d84848484612e3c565b6110da5760405162461bcd60e51b8152600401610b5c9061389e565b6060600e8054610b8b90613a9c565b606081612aec5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612b165780612b0081613af3565b9150612b0f9050600a83613a26565b9150612af0565b60008167ffffffffffffffff811115612b3157612b31613b7a565b6040519080825280601f01601f191660200182016040528015612b5b576020820181803683370190505b5090505b84156125fa57612b70600183613a59565b9150612b7d600a86613b0e565b612b88906030613a0e565b60f81b818381518110612b9d57612b9d613b64565b60200101906001600160f81b031916908160001a905350612bbf600a86613a26565b9450612b5f565b6001600160a01b038316612c2157612c1c81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612c44565b816001600160a01b0316836001600160a01b031614612c4457612c448382612f49565b6001600160a01b038216612c5b57610db481612fe6565b826001600160a01b0316826001600160a01b031614610db457610db48282613095565b60007f000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f16001600160a01b0316634000aea07f0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae084866000604051602001612cee929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612d1b93929190613817565b602060405180830381600087803b158015612d3557600080fd5b505af1158015612d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6d91906135e9565b506000838152600b6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052612dc9906001613a0e565b6000858152600b60205260409020556125fa8482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b612e1383836130d9565b612e206000848484612e3c565b610db45760405162461bcd60e51b8152600401610b5c9061389e565b60006001600160a01b0384163b15612f3e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e80903390899088908890600401613780565b602060405180830381600087803b158015612e9a57600080fd5b505af1925050508015612eca575060408051601f3d908101601f19168201909252612ec791810190613645565b60015b612f24573d808015612ef8576040519150601f19603f3d011682016040523d82523d6000602084013e612efd565b606091505b508051612f1c5760405162461bcd60e51b8152600401610b5c9061389e565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506125fa565b506001949350505050565b60006001612f56846115a3565b612f609190613a59565b600083815260076020526040902054909150808214612fb3576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612ff890600190613a59565b6000838152600960205260408120546008805493945090928490811061302057613020613b64565b90600052602060002001549050806008838154811061304157613041613b64565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061307957613079613b4e565b6001900381819060005260206000200160009055905550505050565b60006130a0836115a3565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b03821661312f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b5c565b6000818152600260205260409020546001600160a01b0316156131945760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b5c565b6131a060008383612bc6565b6001600160a01b03821660009081526003602052604081208054600192906131c9908490613a0e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461323390613a9c565b90600052602060002090601f016020900481019282613255576000855561329b565b82601f1061326e57805160ff191683800117855561329b565b8280016001018555821561329b579182015b8281111561329b578251825591602001919060010190613280565b506132a79291506132d4565b5090565b60405180606001604052806000151581526020016132c76132e9565b8152600060209091015290565b5b808211156132a757600081556001016132d5565b604051806101c00160405280600e906020820280368337509192915050565b600067ffffffffffffffff8084111561332357613323613b7a565b604051601f8501601f19908116603f0116810190828211818310171561334b5761334b613b7a565b8160405280935085815286868601111561336457600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561339057600080fd5b813561201781613b90565b6000602082840312156133ad57600080fd5b815161201781613b90565b600080604083850312156133cb57600080fd5b82356133d681613b90565b915060208301356133e681613b90565b809150509250929050565b60008060006060848603121561340657600080fd5b833561341181613b90565b9250602084013561342181613b90565b9150604084013561343181613b90565b809150509250925092565b60008060006060848603121561345157600080fd5b833561345c81613b90565b9250602084013561346c81613b90565b929592945050506040919091013590565b6000806000806080858703121561349357600080fd5b843561349e81613b90565b935060208501356134ae81613b90565b925060408501359150606085013567ffffffffffffffff8111156134d157600080fd5b8501601f810187136134e257600080fd5b6134f187823560208401613308565b91505092959194509250565b6000806040838503121561351057600080fd5b823561351b81613b90565b915060208301356133e681613ba5565b6000806040838503121561353e57600080fd5b823561354981613b90565b946020939093013593505050565b6000806020838503121561356a57600080fd5b823567ffffffffffffffff8082111561358257600080fd5b818501915085601f83011261359657600080fd5b8135818111156135a557600080fd5b8660208260051b85010111156135ba57600080fd5b60209290920196919550909350505050565b6000602082840312156135de57600080fd5b813561201781613ba5565b6000602082840312156135fb57600080fd5b815161201781613ba5565b6000806040838503121561361957600080fd5b50508035926020909101359150565b60006020828403121561363a57600080fd5b813561201781613bb3565b60006020828403121561365757600080fd5b815161201781613bb3565b60006020828403121561367457600080fd5b813567ffffffffffffffff81111561368b57600080fd5b8201601f8101841361369c57600080fd5b6125fa84823560208401613308565b6000602082840312156136bd57600080fd5b5035919050565b6000602082840312156136d657600080fd5b5051919050565b600080604083850312156136f057600080fd5b8235915060208301356133e681613ba5565b60006020828403121561371457600080fd5b813560ff8116811461201757600080fd5b6000815180845261373d816020860160208601613a70565b601f01601f19169290920160200192915050565b60008351613763818460208801613a70565b835190830190613777818360208801613a70565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906137b390830184613725565b9695505050505050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b8181101561380a57845161ffff16835293830193918301916001016137ea565b5090979650505050505050565b60018060a01b038416815282602082015260606040820152600061383e6060830184613725565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561387f57835183529284019291840191600101613863565b50909695505050505050565b6020815260006120176020830184613725565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b8151151581526020808301516102008301919081840160005b600e8110156139d957825160ff16825291830191908301906001016139b9565b5050505060ff6040840151166101e083015292915050565b600061ffff80831681851680830382111561377757613777613b22565b60008219821115613a2157613a21613b22565b500190565b600082613a3557613a35613b38565b500490565b6000816000190483118215151615613a5457613a54613b22565b500290565b600082821015613a6b57613a6b613b22565b500390565b60005b83811015613a8b578181015183820152602001613a73565b838111156110da5750506000910152565b600181811c90821680613ab057607f821691505b602082108114156120b957634e487b7160e01b600052602260045260246000fd5b600061ffff80831681811415613ae957613ae9613b22565b6001019392505050565b6000600019821415613b0757613b07613b22565b5060010190565b600082613b1d57613b1d613b38565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610e2257600080fd5b8015158114610e2257600080fd5b6001600160e01b031981168114610e2257600080fdfea264697066735822122024b37e212aafe5cf6f1b7f24d74ea141717c5d2e041a131d4e697d559668353b64736f6c63430008070033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000003e25f2d9d34e2e5f9a3659695f8b470ce6c69df0000000000000000000000000000000000000000000000000000000000003a980000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1

-----Decoded View---------------
Arg [0] : _NEWT (address): 0x03e25f2d9D34E2e5f9a3659695F8B470Ce6C69df
Arg [1] : _maxTokens (uint256): 15000
Arg [2] : _vrfCoordinator (address): 0x3d2341ADb2D31f1c5530cDC622016af293177AE0
Arg [3] : _link (address): 0xb0897686c545045aFc77CF20eC7A532E3120E0F1

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000003e25f2d9d34e2e5f9a3659695f8b470ce6c69df
Arg [1] : 0000000000000000000000000000000000000000000000000000000000003a98
Arg [2] : 0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0
Arg [3] : 000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1


Deployed Bytecode Sourcemap

79894:13276:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54769:224;;;;;;;;;;-1:-1:-1;54769:224:0;;;;;:::i;:::-;;:::i;:::-;;;12257:14:1;;12250:22;12232:41;;12220:2;12205:18;54769:224:0;;;;;;;;90376:96;;;;;;;;;;-1:-1:-1;90376:96:0;;;;;:::i;:::-;;:::i;:::-;;40865:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42424:221::-;;;;;;;;;;-1:-1:-1;42424:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9504:32:1;;;9486:51;;9474:2;9459:18;42424:221:0;9340:203:1;41947:411:0;;;;;;;;;;-1:-1:-1;41947:411:0;;;;;:::i;:::-;;:::i;81061:43::-;;;;;;;;;;-1:-1:-1;81061:43:0;;;;;:::i;:::-;;:::i;:::-;;;27688:25:1;;;27676:2;27661:18;81061:43:0;27542:177:1;90976:108:0;;;;;;;;;;-1:-1:-1;90976:108:0;;;;;:::i;:::-;;:::i;55409:113::-;;;;;;;;;;-1:-1:-1;55497:10:0;:17;55409:113;;80682:45;;;;;;;;;;-1:-1:-1;80682:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;86408:389;;;;;;;;;;-1:-1:-1;86408:389:0;;;;;:::i;:::-;;:::i;82964:694::-;;;;;;;;;;-1:-1:-1;82964:694:0;;;;;:::i;:::-;;:::i;55077:256::-;;;;;;;;;;-1:-1:-1;55077:256:0;;;;;:::i;:::-;;:::i;90102:247::-;;;;;;;;;;-1:-1:-1;90102:247:0;;;;;:::i;:::-;;:::i;81219:27::-;;;;;;;;;;-1:-1:-1;81219:27:0;;;;;:::i;:::-;;:::i;:::-;;;27896:4:1;27884:17;;;27866:36;;27854:2;27839:18;81219:27:0;27724:184:1;90749:172:0;;;;;;;;;;-1:-1:-1;90749:172:0;;;;;:::i;:::-;;:::i;81251:26::-;;;;;;;;;;-1:-1:-1;81251:26:0;;;;;:::i;:::-;;:::i;89775:97::-;;;;;;;;;;-1:-1:-1;89855:11:0;;89775:97;;43724:185;;;;;;;;;;-1:-1:-1;43724:185:0;;;;;:::i;:::-;;:::i;80422:20::-;;;;;;;;;;-1:-1:-1;80422:20:0;;;;;;;;;;;27523:6:1;27511:19;;;27493:38;;27481:2;27466:18;80422:20:0;27349:188:1;55599:233:0;;;;;;;;;;-1:-1:-1;55599:233:0;;;;;:::i;:::-;;:::i;90505:190::-;;;;;;;;;;-1:-1:-1;90505:190:0;;;;;:::i;:::-;;:::i;81884:31::-;;;;;;;;;;-1:-1:-1;81884:31:0;;;;;;81816:24;;;;;;;;;;-1:-1:-1;81816:24:0;;;;-1:-1:-1;;;;;81816:24:0;;;13691:86;;;;;;;;;;-1:-1:-1;13762:7:0;;-1:-1:-1;;;13762:7:0;;;;13691:86;;40559:239;;;;;;;;;;-1:-1:-1;40559:239:0;;;;;:::i;:::-;;:::i;80639:21::-;;;;;;;;;;;;;:::i;83698:473::-;;;;;;:::i;:::-;;:::i;40289:208::-;;;;;;;;;;-1:-1:-1;40289:208:0;;;;;:::i;:::-;;:::i;84576:1818::-;;;;;;:::i;:::-;;:::i;64083:94::-;;;;;;;;;;;;;:::i;92278:79::-;;;;;;;;;;;;;:::i;81286:19::-;;;;;;;;;;-1:-1:-1;81286:19:0;;;;-1:-1:-1;;;;;81286:19:0;;;92713:102;;;;;;;;;;-1:-1:-1;92713:102:0;;;;;:::i;:::-;;:::i;92131:141::-;;;;;;;;;;-1:-1:-1;92131:141:0;;;;;:::i;:::-;;:::i;63432:87::-;;;;;;;;;;-1:-1:-1;63505:6:0;;-1:-1:-1;;;;;63505:6:0;63432:87;;78820:233;;;;;;;;;;-1:-1:-1;78820:233:0;;;;;:::i;:::-;;:::i;89639:130::-;;;;;;;;;;-1:-1:-1;89639:130:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;41034:104::-;;;;;;;;;;;;;:::i;81845:34::-;;;;;;;;;;;;;;;;80872:55;;;;;;;;;;-1:-1:-1;80872:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;42717:295;;;;;;;;;;-1:-1:-1;42717:295:0;;;;;:::i;:::-;;:::i;92985:178::-;;;;;;;;;;;;;:::i;89960:115::-;;;;;;;;;;-1:-1:-1;89960:115:0;;;;;:::i;:::-;;:::i;43980:328::-;;;;;;;;;;-1:-1:-1;43980:328:0;;;;;:::i;:::-;;:::i;80540:47::-;;;;;;;;;;;;80577:10;80540:47;;80279:26;;;;;;;;;;;;;;;;41209:334;;;;;;;;;;-1:-1:-1;41209:334:0;;;;;:::i;:::-;;:::i;91564:283::-;;;;;;;;;;-1:-1:-1;91564:283:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;81725:18::-;;;;;;;;;;;;;;;;84179:387;;;;;;:::i;:::-;;:::i;80732:47::-;;;;;;;;;;-1:-1:-1;80732:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12473:14:1;;12466:22;12448:41;;12537:4;12525:17;;;12520:2;12505:18;;12498:45;12421:18;80732:47:0;12284:265:1;81559:21:0;;;;;;;;;;-1:-1:-1;81559:21:0;;;;-1:-1:-1;;;;;81559:21:0;;;43083:164;;;;;;;;;;-1:-1:-1;43083:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;43204:25:0;;;43180:4;43204:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;43083:164;81433:17;;;;;;;;;;-1:-1:-1;81433:17:0;;;;-1:-1:-1;;;;;81433:17:0;;;91092:231;;;;;;;;;;-1:-1:-1;91092:231:0;;;;;:::i;:::-;;:::i;64332:192::-;;;;;;;;;;-1:-1:-1;64332:192:0;;;;;:::i;:::-;;:::i;80140:35::-;;;;;;;;;;;;;;;54769:224;54871:4;-1:-1:-1;;;;;;54895:50:0;;-1:-1:-1;;;54895:50:0;;:90;;;54949:36;54973:11;54949:23;:36::i;:::-;54888:97;54769:224;-1:-1:-1;;54769:224:0:o;90376:96::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;;;;;;;;;90445:21;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;:::-;;90376:96:::0;:::o;40865:100::-;40919:13;40952:5;40945:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40865:100;:::o;42424:221::-;42500:7;45907:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45907:16:0;42520:73;;;;-1:-1:-1;;;42520:73:0;;21912:2:1;42520:73:0;;;21894:21:1;21951:2;21931:18;;;21924:30;21990:34;21970:18;;;21963:62;-1:-1:-1;;;22041:18:1;;;22034:42;22093:19;;42520:73:0;21710:408:1;42520:73:0;-1:-1:-1;42613:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;42613:24:0;;42424:221::o;41947:411::-;42028:13;42044:23;42059:7;42044:14;:23::i;:::-;42028:39;;42092:5;-1:-1:-1;;;;;42086:11:0;:2;-1:-1:-1;;;;;42086:11:0;;;42078:57;;;;-1:-1:-1;;;42078:57:0;;24574:2:1;42078:57:0;;;24556:21:1;24613:2;24593:18;;;24586:30;24652:34;24632:18;;;24625:62;-1:-1:-1;;;24703:18:1;;;24696:31;24744:19;;42078:57:0;24372:397:1;42078:57:0;12524:10;-1:-1:-1;;;;;42170:21:0;;;;:62;;-1:-1:-1;42195:37:0;42212:5;12524:10;43083:164;:::i;42195:37::-;42148:168;;;;-1:-1:-1;;;42148:168:0;;20305:2:1;42148:168:0;;;20287:21:1;20344:2;20324:18;;;20317:30;20383:34;20363:18;;;20356:62;20454:26;20434:18;;;20427:54;20498:19;;42148:168:0;20103:420:1;42148:168:0;42329:21;42338:2;42342:7;42329:8;:21::i;:::-;42017:341;41947:411;;:::o;81061:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90976:108::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;91039:7:::1;91035:43;;;91048:8;:6;:8::i;:::-;90976:108:::0;:::o;91035:43::-:1;91068:10;:8;:10::i;86408:389::-:0;86638:5;;-1:-1:-1;;;;;86638:5:0;12524:10;-1:-1:-1;;;;;86614:30:0;;86610:146;;86661:41;12524:10;86694:7;86661:18;:41::i;:::-;86653:103;;;;-1:-1:-1;;;86653:103:0;;;;;;;:::i;:::-;86763:28;86773:4;86779:2;86783:7;86763:9;:28::i;82964:694::-;83020:7;83051:11;;83040:7;:22;83036:36;;-1:-1:-1;83071:1:0;;82964:694;-1:-1:-1;82964:694:0:o;83036:36::-;83185:1;83168:14;:10;83181:1;83168:14;:::i;:::-;:18;;;;:::i;:::-;83157:7;:29;83153:53;;-1:-1:-1;83195:11:0;;82964:694;-1:-1:-1;82964:694:0:o;83153:53::-;83286:1;83269:14;:10;83282:1;83269:14;:::i;:::-;:18;;;;:::i;:::-;83258:7;:29;83254:53;;-1:-1:-1;83296:11:0;;82964:694;-1:-1:-1;82964:694:0:o;83254:53::-;83387:1;83370:14;:10;83383:1;83370:14;:::i;:::-;:18;;;;:::i;:::-;83359:7;:29;83355:53;;-1:-1:-1;83397:11:0;;82964:694;-1:-1:-1;82964:694:0:o;83355:53::-;83488:1;83471:14;:10;83484:1;83471:14;:::i;:::-;:18;;;;:::i;:::-;83460:7;:29;83456:53;;-1:-1:-1;83498:11:0;;82964:694;-1:-1:-1;82964:694:0:o;83456:53::-;-1:-1:-1;83564:11:0;;82964:694;-1:-1:-1;82964:694:0:o;55077:256::-;55174:7;55210:23;55227:5;55210:16;:23::i;:::-;55202:5;:31;55194:87;;;;-1:-1:-1;;;55194:87:0;;14673:2:1;55194:87:0;;;14655:21:1;14712:2;14692:18;;;14685:30;14751:34;14731:18;;;14724:62;-1:-1:-1;;;14802:18:1;;;14795:41;14853:19;;55194:87:0;14471:407:1;55194:87:0;-1:-1:-1;;;;;;55299:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;55077:256::o;90102:247::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;90199:5:::1;:22:::0;;-1:-1:-1;;;;;90199:22:0;;::::1;-1:-1:-1::0;;;;;;90199:22:0;;::::1;;::::0;;;90228:4:::1;:26:::0;;;;::::1;::::0;;::::1;;::::0;;90291:6:::1;:25:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;90323:20:::1;:18;:20::i;:::-;;90102:247:::0;;;:::o;81219:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90749:172::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;90819:11:::1;:25:::0;90749:172::o;81251:26::-;;;;;;;;;;;43724:185;43862:39;43879:4;43885:2;43889:7;43862:39;;;;;;;;;;;;:16;:39::i;55599:233::-;55674:7;55710:30;55497:10;:17;;55409:113;55710:30;55702:5;:38;55694:95;;;;-1:-1:-1;;;55694:95:0;;25742:2:1;55694:95:0;;;25724:21:1;25781:2;25761:18;;;25754:30;25820:34;25800:18;;;25793:62;-1:-1:-1;;;25871:18:1;;;25864:42;25923:19;;55694:95:0;25540:408:1;55694:95:0;55807:10;55818:5;55807:17;;;;;;;;:::i;:::-;;;;;;;;;55800:24;;55599:233;;;:::o;90505:190::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;90610:1:::1;90586:21;:25;90578:57;;;::::0;-1:-1:-1;;;90578:57:0;;22686:2:1;90578:57:0::1;::::0;::::1;22668:21:1::0;22725:2;22705:18;;;22698:30;-1:-1:-1;;;22744:18:1;;;22737:49;22803:18;;90578:57:0::1;22484:343:1::0;90578:57:0::1;90646:41;::::0;-1:-1:-1;;;;;90646:18:0;::::1;::::0;90665:21:::1;90646:41:::0;::::1;;;::::0;::::1;::::0;;;90665:21;90646:18;:41;::::1;;;;;;;;;;;;;::::0;::::1;;;;40559:239:::0;40631:7;40667:16;;;:7;:16;;;;;;-1:-1:-1;;;;;40667:16:0;40702:19;40694:73;;;;-1:-1:-1;;;40694:73:0;;21141:2:1;40694:73:0;;;21123:21:1;21180:2;21160:18;;;21153:30;21219:34;21199:18;;;21192:62;-1:-1:-1;;;21270:18:1;;;21263:39;21319:19;;40694:73:0;20939:405:1;80639:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83698:473::-;13762:7;;-1:-1:-1;;;13762:7:0;;;;14016:9;14008:38;;;;-1:-1:-1;;;14008:38:0;;;;;;;:::i;:::-;83783:1:::1;83774:6;:10;;;83766:49;;;::::0;-1:-1:-1;;;83766:49:0;;19245:2:1;83766:49:0::1;::::0;::::1;19227:21:1::0;19284:2;19264:18;;;19257:30;19323:28;19303:18;;;19296:56;19369:18;;83766:49:0::1;19043:350:1::0;83766:49:0::1;83844:2;83834:6;:12;;;;83826:50;;;::::0;-1:-1:-1;;;83826:50:0;;23860:2:1;83826:50:0::1;::::0;::::1;23842:21:1::0;23899:2;23879:18;;;23872:30;23938:27;23918:18;;;23911:55;23983:18;;83826:50:0::1;23658:349:1::0;83826:50:0::1;83908:19;;::::0;::::1;80577:10;83908:19;:::i;:::-;83895:9;:32;83887:76;;;::::0;-1:-1:-1;;;83887:76:0;;18472:2:1;83887:76:0::1;::::0;::::1;18454:21:1::0;18511:2;18491:18;;;18484:30;18550:33;18530:18;;;18523:61;18601:18;;83887:76:0::1;18270:355:1::0;83887:76:0::1;83996:6;::::0;84015:4:::1;::::0;83996:15:::1;::::0;::::1;::::0;::::1;::::0;:6:::1;;:15;:::i;:::-;:23;;;;83974:82;;;::::0;-1:-1:-1;;;83974:82:0;;26508:2:1;83974:82:0::1;::::0;::::1;26490:21:1::0;26547:1;26527:18;;;26520:29;-1:-1:-1;;;26565:18:1;;;26558:39;26614:18;;83974:82:0::1;26306:332:1::0;83974:82:0::1;84074:9;84069:95;84093:6;84089:10;;:1;:10;84069:95;;;84145:6;84143:8:::0;;84121:31:::1;::::0;84131:10:::1;::::0;84145:6:::1;::::0;84143:8:::1;::::0;::::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;84121:31;;:9;:31::i;:::-;84101:3:::0;::::1;::::0;::::1;:::i;:::-;;;;84069:95;;40289:208:::0;40361:7;-1:-1:-1;;;;;40389:19:0;;40381:74;;;;-1:-1:-1;;;40381:74:0;;20730:2:1;40381:74:0;;;20712:21:1;20769:2;20749:18;;;20742:30;20808:34;20788:18;;;20781:62;-1:-1:-1;;;20859:18:1;;;20852:40;20909:19;;40381:74:0;20528:406:1;40381:74:0;-1:-1:-1;;;;;;40473:16:0;;;;;:9;:16;;;;;;;40289:208::o;84576:1818::-;13762:7;;-1:-1:-1;;;13762:7:0;;;;14016:9;14008:38;;;;-1:-1:-1;;;14008:38:0;;;;;;;:::i;:::-;12524:10;84716:9:::1;:22:::0;::::1;84708:43;;;::::0;-1:-1:-1;;;84708:43:0;;16965:2:1;84708:43:0::1;::::0;::::1;16947:21:1::0;17004:1;16984:18;;;16977:29;-1:-1:-1;;;17022:18:1;;;17015:38;17070:18;;84708:43:0::1;16763:331:1::0;84708:43:0::1;84766:6;::::0;84785:10:::1;::::0;84766:15:::1;::::0;84775:6;;84766::::1;;:15;:::i;:::-;:29;;84758:59;;;::::0;-1:-1:-1;;;84758:59:0;;15911:2:1;84758:59:0::1;::::0;::::1;15893:21:1::0;15950:2;15930:18;;;15923:30;-1:-1:-1;;;15969:18:1;;;15962:47;16026:18;;84758:59:0::1;15709:341:1::0;84758:59:0::1;84841:1;84832:6;:10;:26;;;;;84856:2;84846:6;:12;;84832:26;84824:58;;;::::0;-1:-1:-1;;;84824:58:0;;25394:2:1;84824:58:0::1;::::0;::::1;25376:21:1::0;25433:2;25413:18;;;25406:30;-1:-1:-1;;;25452:18:1;;;25445:49;25511:18;;84824:58:0::1;25192:343:1::0;84824:58:0::1;84908:11;::::0;84899:6:::1;::::0;::::1;;:20;84895:446;;;84934:21;84958:19;84971:6:::0;80577:10:::1;84958:19;:::i;:::-;-1:-1:-1::0;;;;;84990:21:0;::::1;;::::0;;;:10:::1;:21;::::0;;;;;84934:43;;-1:-1:-1;85015:1:0::1;84990:26;84986:135;;;80577:10;85049;85058:1;85049:6:::0;:10:::1;:::i;:::-;85047:26;;;;:::i;:::-;-1:-1:-1::0;;;;;85086:21:0;::::1;85110:1;85086:21:::0;;;:10:::1;:21;::::0;;;;:25;85031:42;-1:-1:-1;84986:135:0::1;85162:11;::::0;85143:6:::1;::::0;:15:::1;::::0;85152:6;;85143::::1;;:15;:::i;:::-;:30;;85135:74;;;::::0;-1:-1:-1;;;85135:74:0;;19600:2:1;85135:74:0::1;::::0;::::1;19582:21:1::0;19639:2;19619:18;;;19612:30;19678:33;19658:18;;;19651:61;19729:18;;85135:74:0::1;19398:355:1::0;85135:74:0::1;85243:9;85226:13;:26;85218:61;;;::::0;-1:-1:-1;;;85218:61:0;;16614:2:1;85218:61:0::1;::::0;::::1;16596:21:1::0;16653:2;16633:18;;;16626:30;-1:-1:-1;;;16672:18:1;;;16665:52;16734:18;;85218:61:0::1;16412:346:1::0;85218:61:0::1;84921:370;84895:446;;;85316:9;:14:::0;85308:23:::1;;;::::0;::::1;;85349:21;85471:24:::0;85498:5:::1;:46;;85529:15;::::0;;85542:1:::1;85529:15:::0;;::::1;::::0;::::1;::::0;;;85498:46:::1;;;85519:6;85506:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;85506:20:0::1;;85498:46;85471:73:::0;-1:-1:-1;85561:12:0::1;::::0;85582:663:::1;85603:6;85599:1;:10;85582:663;;;85625:6;:8:::0;;::::1;;::::0;:6:::1;:8;::::0;::::1;:::i;:::-;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;;;::::0;;;85656:6:::1;::::0;85649:14:::1;::::0;-1:-1:-1;85656:6:0::1;85649;:14::i;:::-;85642:21;;85746:17;85766:21;85782:4;85766:15;:21::i;:::-;85746:41;;85906:5;85905:6;:32;;;;85928:9;-1:-1:-1::0;;;;;85915:22:0::1;:9;-1:-1:-1::0;;;;;85915:22:0::1;;;85905:32;85901:295;;;86088:6;::::0;86067:28:::1;::::0;86077:9;;86088:6:::1;;86067:9;:28::i;:::-;85901:295;;;86140:5;::::0;86148:6:::1;::::0;86122:33:::1;::::0;-1:-1:-1;;;;;86140:5:0::1;::::0;86148:6:::1;;86122:9;:33::i;:::-;86180:6;::::0;86166:11;;86180:6:::1;::::0;;::::1;::::0;86166:8;;86175:1;;86166:11;::::1;;;;;:::i;:::-;;;;;;:20;;;;;;;;;::::0;::::1;85901:295;86230:6;::::0;86221:16:::1;::::0;86230:6:::1;;86221:8;:16::i;:::-;86204:33;::::0;;::::1;:::i;:::-;;;85616:629;85611:3;;;;;:::i;:::-;;;;85582:663;;;-1:-1:-1::0;86261:17:0;;86257:58:::1;;86280:4;::::0;:35:::1;::::0;-1:-1:-1;;;86280:35:0;;-1:-1:-1;;;;;10978:32:1;;;86280:35:0::1;::::0;::::1;10960:51:1::0;11027:18;;;11020:34;;;86280:4:0;;::::1;::::0;:9:::1;::::0;10933:18:1;;86280:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;86257:58;86326:5;86322:66;;;86333:5;::::0;:55:::1;::::0;-1:-1:-1;;;86333:55:0;;-1:-1:-1;;;;;86333:5:0;;::::1;::::0;:34:::1;::::0;:55:::1;::::0;86368:9;;86379:8;;86333:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;86322:66;84658:1736;;;;84576:1818:::0;;:::o;64083:94::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;64148:21:::1;64166:1;64148:9;:21::i;:::-;64083:94::o:0;92278:79::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;92331:20:::1;:18;:20::i;92713:102::-:0;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;92786:11:::1;:23:::0;92713:102::o;92131:141::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;92256:3:::1;:10:::0;92131:141::o;78820:233::-;78936:10;-1:-1:-1;;;;;78950:14:0;78936:28;;78928:72;;;;-1:-1:-1;;;78928:72:0;;24214:2:1;78928:72:0;;;24196:21:1;24253:2;24233:18;;;24226:30;24292:33;24272:18;;;24265:61;24343:18;;78928:72:0;24012:355:1;78928:72:0;92948:12;:25;-1:-1:-1;90376:96:0:o;89639:130::-;89712:15;;:::i;:::-;89743:20;;;;:11;:20;;;;;;;;89736:27;;;;;;;;;;;;;;;;;;;;;;;;;;89743:20;;89736:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;89736:27:0;;;-1:-1:-1;;;89736:27:0;;;;;;;;;;;;;;;-1:-1:-1;;89639:130:0:o;41034:104::-;41090:13;41123:7;41116:14;;;;;:::i;42717:295::-;-1:-1:-1;;;;;42820:24:0;;12524:10;42820:24;;42812:62;;;;-1:-1:-1;;;42812:62:0;;17706:2:1;42812:62:0;;;17688:21:1;17745:2;17725:18;;;17718:30;17784:27;17764:18;;;17757:55;17829:18;;42812:62:0;17504:349:1;42812:62:0;12524:10;42887:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;42887:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;42887:53:0;;;;;;;;;;42956:48;;12232:41:1;;;42887:42:0;;12524:10;42956:48;;12205:18:1;42956:48:0;;;;;;;42717:295;;:::o;92985:178::-;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;93064:9:::1;::::0;93057:42:::1;::::0;-1:-1:-1;;;93057:42:0;;93093:4:::1;93057:42;::::0;::::1;9486:51:1::0;93035:19:0::1;::::0;-1:-1:-1;;;;;93064:9:0::1;::::0;93057:27:::1;::::0;9459:18:1;;93057:42:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93113:9;::::0;93106:51:::1;::::0;-1:-1:-1;;;93106:51:0;;93133:10:::1;93106:51;::::0;::::1;10960::1::0;11027:18;;;11020:34;;;93035:64:0;;-1:-1:-1;;;;;;93113:9:0::1;::::0;93106:26:::1;::::0;10933:18:1;;93106:51:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;89960:115::-:0;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;90020:5:::1;:22:::0;;-1:-1:-1;;;;;;90020:22:0::1;-1:-1:-1::0;;;;;90020:22:0;::::1;;::::0;;90049:20:::1;:18;:20::i;43980:328::-:0;44155:41;12524:10;44188:7;44155:18;:41::i;:::-;44147:103;;;;-1:-1:-1;;;44147:103:0;;;;;;;:::i;:::-;44261:39;44275:4;44281:2;44285:7;44294:5;44261:13;:39::i;41209:334::-;45883:4;45907:16;;;:7;:16;;;;;;41282:13;;-1:-1:-1;;;;;45907:16:0;41308:76;;;;-1:-1:-1;;;41308:76:0;;23444:2:1;41308:76:0;;;23426:21:1;23483:2;23463:18;;;23456:30;23522:34;23502:18;;;23495:62;-1:-1:-1;;;23573:18:1;;;23566:45;23628:19;;41308:76:0;23242:411:1;41308:76:0;41397:21;41421:10;:8;:10::i;:::-;41397:34;;41473:1;41455:7;41449:21;:25;:86;;;;;;;;;;;;;;;;;41501:7;41510:18;:7;:16;:18::i;:::-;41484:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;41449:86;41442:93;41209:334;-1:-1:-1;;;41209:334:0:o;91564:283::-;91622:31;91697:17;91707:6;91697:9;:17::i;:::-;91683:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91683:32:0;;91666:49;;91731:9;91726:116;91743:17;91753:6;91743:9;:17::i;:::-;91741:1;:19;91726:116;;;91800:30;91820:6;91828:1;91800:19;:30::i;:::-;91780:14;91795:1;91780:17;;;;;;;;:::i;:::-;;;;;;;;;;:50;91761:3;;;;:::i;:::-;;;;91726:116;;;;91564:283;;;:::o;84179:387::-;13762:7;;-1:-1:-1;;;13762:7:0;;;;14016:9;14008:38;;;;-1:-1:-1;;;14008:38:0;;;;;;;:::i;:::-;84268:1:::1;84259:6;:10;;;84251:49;;;::::0;-1:-1:-1;;;84251:49:0;;19245:2:1;84251:49:0::1;::::0;::::1;19227:21:1::0;19284:2;19264:18;;;19257:30;19323:28;19303:18;;;19296:56;19369:18;;84251:49:0::1;19043:350:1::0;84251:49:0::1;84329:1;84319:6;:11;;;;84311:48;;;::::0;-1:-1:-1;;;84311:48:0;;26155:2:1;84311:48:0::1;::::0;::::1;26137:21:1::0;26194:2;26174:18;;;26167:30;26233:26;26213:18;;;26206:54;26277:18;;84311:48:0::1;25953:348:1::0;84311:48:0::1;84392:6;::::0;84411:3:::1;::::0;84392:15:::1;::::0;::::1;::::0;::::1;::::0;:6:::1;;:15;:::i;:::-;:22;;;;84370:81;;;::::0;-1:-1:-1;;;84370:81:0;;26508:2:1;84370:81:0::1;::::0;::::1;26490:21:1::0;26547:1;26527:18;;;26520:29;-1:-1:-1;;;26565:18:1;;;26558:39;26614:18;;84370:81:0::1;26306:332:1::0;84370:81:0::1;84469:9;84464:95;84488:6;84484:10;;:1;:10;84464:95;;;84540:6;84538:8:::0;;84516:31:::1;::::0;84526:10:::1;::::0;84540:6:::1;::::0;84538:8:::1;::::0;::::1;;;:::i;84516:31::-;84496:3:::0;::::1;::::0;::::1;:::i;:::-;;;;84464:95;;91092:231:::0;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;91197:13;91176:18:::1;91226:92;91246:10;91242:1;:14;91226:92;;;91309:1;91278:10;:28;91289:13;;91303:1;91289:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;91278:28:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;91278:28:0;:32;91258:3;::::1;::::0;::::1;:::i;:::-;;;;91226:92;;64332:192:::0;63505:6;;-1:-1:-1;;;;;63505:6:0;12524:10;63652:23;63644:68;;;;-1:-1:-1;;;63644:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64421:22:0;::::1;64413:73;;;::::0;-1:-1:-1;;;64413:73:0;;15504:2:1;64413:73:0::1;::::0;::::1;15486:21:1::0;15543:2;15523:18;;;15516:30;15582:34;15562:18;;;15555:62;-1:-1:-1;;;15633:18:1;;;15626:36;15679:19;;64413:73:0::1;15302:402:1::0;64413:73:0::1;64497:19;64507:8;64497:9;:19::i;39920:305::-:0;40022:4;-1:-1:-1;;;;;;40059:40:0;;-1:-1:-1;;;40059:40:0;;:105;;-1:-1:-1;;;;;;;40116:48:0;;-1:-1:-1;;;40116:48:0;40059:105;:158;;;-1:-1:-1;;;;;;;;;;30366:40:0;;;40181:36;30257:157;49800:174;49875:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;49875:29:0;-1:-1:-1;;;;;49875:29:0;;;;;;;;:24;;49929:23;49875:24;49929:14;:23::i;:::-;-1:-1:-1;;;;;49920:46:0;;;;;;;;;;;49800:174;;:::o;14491:118::-;13762:7;;-1:-1:-1;;;13762:7:0;;;;14016:9;14008:38;;;;-1:-1:-1;;;14008:38:0;;;;;;;:::i;:::-;14551:7:::1;:14:::0;;-1:-1:-1;;;;14551:14:0::1;-1:-1:-1::0;;;14551:14:0::1;::::0;;14581:20:::1;14588:12;12524:10:::0;;12444:98;14588:12:::1;14581:20;::::0;-1:-1:-1;;;;;9504:32:1;;;9486:51;;9474:2;9459:18;14581:20:0::1;;;;;;;14491:118::o:0;14750:120::-;13762:7;;-1:-1:-1;;;13762:7:0;;;;14286:41;;;;-1:-1:-1;;;14286:41:0;;14324:2:1;14286:41:0;;;14306:21:1;14363:2;14343:18;;;14336:30;-1:-1:-1;;;14382:18:1;;;14375:50;14442:18;;14286:41:0;14122:344:1;14286:41:0;14809:7:::1;:15:::0;;-1:-1:-1;;;;14809:15:0::1;::::0;;14840:22:::1;12524:10:::0;14849:12:::1;12444:98:::0;46112:348;46205:4;45907:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45907:16:0;46222:73;;;;-1:-1:-1;;;46222:73:0;;18832:2:1;46222:73:0;;;18814:21:1;18871:2;18851:18;;;18844:30;18910:34;18890:18;;;18883:62;-1:-1:-1;;;18961:18:1;;;18954:42;19013:19;;46222:73:0;18630:408:1;46222:73:0;46306:13;46322:23;46337:7;46322:14;:23::i;:::-;46306:39;;46375:5;-1:-1:-1;;;;;46364:16:0;:7;-1:-1:-1;;;;;46364:16:0;;:51;;;;46408:7;-1:-1:-1;;;;;46384:31:0;:20;46396:7;46384:11;:20::i;:::-;-1:-1:-1;;;;;46384:31:0;;46364:51;:87;;;-1:-1:-1;;;;;;43204:25:0;;;43180:4;43204:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;46419:32;46356:96;46112:348;-1:-1:-1;;;;46112:348:0:o;49104:578::-;49263:4;-1:-1:-1;;;;;49236:31:0;:23;49251:7;49236:14;:23::i;:::-;-1:-1:-1;;;;;49236:31:0;;49228:85;;;;-1:-1:-1;;;49228:85:0;;23034:2:1;49228:85:0;;;23016:21:1;23073:2;23053:18;;;23046:30;23112:34;23092:18;;;23085:62;-1:-1:-1;;;23163:18:1;;;23156:39;23212:19;;49228:85:0;22832:405:1;49228:85:0;-1:-1:-1;;;;;49332:16:0;;49324:65;;;;-1:-1:-1;;;49324:65:0;;17301:2:1;49324:65:0;;;17283:21:1;17340:2;17320:18;;;17313:30;17379:34;17359:18;;;17352:62;-1:-1:-1;;;17430:18:1;;;17423:34;17474:19;;49324:65:0;17099:400:1;49324:65:0;49402:39;49423:4;49429:2;49433:7;49402:20;:39::i;:::-;49506:29;49523:1;49527:7;49506:8;:29::i;:::-;-1:-1:-1;;;;;49548:15:0;;;;;;:9;:15;;;;;:20;;49567:1;;49548:15;:20;;49567:1;;49548:20;:::i;:::-;;;;-1:-1:-1;;;;;;;49579:13:0;;;;;;:9;:13;;;;;:18;;49596:1;;49579:13;:18;;49596:1;;49579:18;:::i;:::-;;;;-1:-1:-1;;49608:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;49608:21:0;-1:-1:-1;;;;;49608:21:0;;;;;;;;;49647:27;;49608:16;;49647:27;;;;;;;49104:578;;;:::o;92363:344::-;92411:17;92464:11;;92443:17;:7;15748:14;;15656:114;92443:17;:32;92439:95;;92486:19;:7;15867:19;;15885:1;15867:19;;;15778:127;92486:19;-1:-1:-1;92521:5:0;;92363:344::o;92439:95::-;92583:3;;92550:29;;-1:-1:-1;;;92550:29:0;;92573:4;92550:29;;;9486:51:1;92550:4:0;-1:-1:-1;;;;;92550:14:0;;;;9459:18:1;;92550:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;92542:92;;;;-1:-1:-1;;;92542:92:0;;18060:2:1;92542:92:0;;;18042:21:1;18099:2;18079:18;;;18072:30;18138:34;18118:18;;;18111:62;-1:-1:-1;;;18189:18:1;;;18182:41;18240:19;;92542:92:0;17858:407:1;92542:92:0;16233:1;92641:7;16216:18;92670:31;92688:7;;92697:3;;92670:17;:31::i;:::-;92663:38;;92363:344;:::o;46802:110::-;46878:26;46888:2;46892:7;46878:26;;;;;;;;;;;;:9;:26::i;91888:237::-;91941:7;92007:9;92035:16;92050:1;92035:12;:16;:::i;:::-;92098:12;;91982:135;;8378:2:1;8374:15;;;;-1:-1:-1;;8370:53:1;91982:135:0;;;8358:66:1;92025:27:0;;8440:12:1;;;8433:28;92061:15:0;8477:12:1;;;8470:28;8514:12;;;8507:28;;;8551:13;;;8544:29;8589:13;;91982:135:0;;;-1:-1:-1;;91982:135:0;;;;;;;;;91972:146;;91982:135;91972:146;;;;;91888:237;-1:-1:-1;;91888:237:0:o;89194:420::-;89286:11;;89276:6;;89256:7;;89276:6;;;;:21;;;:50;;-1:-1:-1;89302:18:0;89318:2;89311:3;89303:11;;;89302:18;:::i;:::-;89301:25;;89276:50;89272:75;;;12524:10;89335:12;12444:98;89272:75;89419:5;;:35;;-1:-1:-1;;;89419:35:0;;89450:3;89442:11;;;89419:35;;;27688:25:1;89403:13:0;;-1:-1:-1;;;;;89419:5:0;;:22;;27661:18:1;;89419:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89403:51;-1:-1:-1;;;;;;89547:21:0;;89543:46;;12524:10;89577:12;12444:98;64532:173;64607:6;;;-1:-1:-1;;;;;64624:17:0;;;-1:-1:-1;;;;;;64624:17:0;;;;;;;64657:40;;64607:6;;;64624:17;64607:6;;64657:40;;64588:16;;64657:40;64577:128;64532:173;:::o;45190:315::-;45347:28;45357:4;45363:2;45367:7;45347:9;:28::i;:::-;45394:48;45417:4;45423:2;45427:7;45436:5;45394:22;:48::i;:::-;45386:111;;;;-1:-1:-1;;;45386:111:0;;;;;;;:::i;91452:104::-;91512:13;91543:7;91536:14;;;;;:::i;93447:723::-;93503:13;93724:10;93720:53;;-1:-1:-1;;93751:10:0;;;;;;;;;;;;-1:-1:-1;;;93751:10:0;;;;;93447:723::o;93720:53::-;93798:5;93783:12;93839:78;93846:9;;93839:78;;93872:8;;;;:::i;:::-;;-1:-1:-1;93895:10:0;;-1:-1:-1;93903:2:0;93895:10;;:::i;:::-;;;93839:78;;;93927:19;93959:6;93949:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93949:17:0;;93927:39;;93977:154;93984:10;;93977:154;;94011:11;94021:1;94011:11;;:::i;:::-;;-1:-1:-1;94080:10:0;94088:2;94080:5;:10;:::i;:::-;94067:24;;:2;:24;:::i;:::-;94054:39;;94037:6;94044;94037:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;94037:56:0;;;;;;;;-1:-1:-1;94108:11:0;94117:2;94108:11;;:::i;:::-;;;93977:154;;56445:589;-1:-1:-1;;;;;56651:18:0;;56647:187;;56686:40;56718:7;57861:10;:17;;57834:24;;;;:15;:24;;;;;:44;;;57889:24;;;;;;;;;;;;57757:164;56686:40;56647:187;;;56756:2;-1:-1:-1;;;;;56748:10:0;:4;-1:-1:-1;;;;;56748:10:0;;56744:90;;56775:47;56808:4;56814:7;56775:32;:47::i;:::-;-1:-1:-1;;;;;56848:16:0;;56844:183;;56881:45;56918:7;56881:36;:45::i;56844:183::-;56954:4;-1:-1:-1;;;;;56948:10:0;:2;-1:-1:-1;;;;;56948:10:0;;56944:83;;56975:40;57003:2;57007:7;56975:27;:40::i;76884:1077::-;76994:17;77029:4;-1:-1:-1;;;;;77029:20:0;;77050:14;77066:4;77083:8;75714:1;77072:43;;;;;;;;12728:25:1;;;12784:2;12769:18;;12762:34;12716:2;12701:18;;12554:248;77072:43:0;;;;;;;;;;;;;77029:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;77351:15:0;77435:16;;;:6;:16;;;;;;;;;68393:51;;;;;13038:25:1;;;13079:18;;;13072:34;;;77428:4:0;13122:18:1;;;13115:60;13191:18;;;;13184:34;;;68393:51:0;;;;;;;;;;13010:19:1;;;;68393:51:0;;;68383:62;;;;;;;;;77889:16;;;;;;;:20;;77908:1;77889:20;:::i;:::-;77870:16;;;;:6;:16;;;;;:39;77923:32;77877:8;77947:7;69010:41;;;;;;;8770:19:1;;;;8805:12;;;8798:28;;;;69010:41:0;;;;;;;;;8842:12:1;;;;69010:41:0;;69000:52;;;;;;68843:215;47139:321;47269:18;47275:2;47279:7;47269:5;:18::i;:::-;47320:54;47351:1;47355:2;47359:7;47368:5;47320:22;:54::i;:::-;47298:154;;;;-1:-1:-1;;;47298:154:0;;;;;;;:::i;50539:799::-;50694:4;-1:-1:-1;;;;;50715:13:0;;4849:20;4897:8;50711:620;;50751:72;;-1:-1:-1;;;50751:72:0;;-1:-1:-1;;;;;50751:36:0;;;;;:72;;12524:10;;50802:4;;50808:7;;50817:5;;50751:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50751:72:0;;;;;;;;-1:-1:-1;;50751:72:0;;;;;;;;;;;;:::i;:::-;;;50747:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50993:13:0;;50989:272;;51036:60;;-1:-1:-1;;;51036:60:0;;;;;;;:::i;50989:272::-;51211:6;51205:13;51196:6;51192:2;51188:15;51181:38;50747:529;-1:-1:-1;;;;;;50874:51:0;-1:-1:-1;;;50874:51:0;;-1:-1:-1;50867:58:0;;50711:620;-1:-1:-1;51315:4:0;50539:799;;;;;;:::o;58548:988::-;58814:22;58864:1;58839:22;58856:4;58839:16;:22::i;:::-;:26;;;;:::i;:::-;58876:18;58897:26;;;:17;:26;;;;;;58814:51;;-1:-1:-1;59030:28:0;;;59026:328;;-1:-1:-1;;;;;59097:18:0;;59075:19;59097:18;;;:12;:18;;;;;;;;:34;;;;;;;;;59148:30;;;;;;:44;;;59265:30;;:17;:30;;;;;:43;;;59026:328;-1:-1:-1;59450:26:0;;;;:17;:26;;;;;;;;59443:33;;;-1:-1:-1;;;;;59494:18:0;;;;;:12;:18;;;;;:34;;;;;;;59487:41;58548:988::o;59831:1079::-;60109:10;:17;60084:22;;60109:21;;60129:1;;60109:21;:::i;:::-;60141:18;60162:24;;;:15;:24;;;;;;60535:10;:26;;60084:46;;-1:-1:-1;60162:24:0;;60084:46;;60535:26;;;;;;:::i;:::-;;;;;;;;;60513:48;;60599:11;60574:10;60585;60574:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;60679:28;;;:15;:28;;;;;;;:41;;;60851:24;;;;;60844:31;60886:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59902:1008;;;59831:1079;:::o;57335:221::-;57420:14;57437:20;57454:2;57437:16;:20::i;:::-;-1:-1:-1;;;;;57468:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;57513:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;57335:221:0:o;47796:382::-;-1:-1:-1;;;;;47876:16:0;;47868:61;;;;-1:-1:-1;;;47868:61:0;;21551:2:1;47868:61:0;;;21533:21:1;;;21570:18;;;21563:30;21629:34;21609:18;;;21602:62;21681:18;;47868:61:0;21349:356:1;47868:61:0;45883:4;45907:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45907:16:0;:30;47940:58;;;;-1:-1:-1;;;47940:58:0;;16257:2:1;47940:58:0;;;16239:21:1;16296:2;16276:18;;;16269:30;16335;16315:18;;;16308:58;16383:18;;47940:58:0;16055:352:1;47940:58:0;48011:45;48040:1;48044:2;48048:7;48011:20;:45::i;:::-;-1:-1:-1;;;;;48069:13:0;;;;;;:9;:13;;;;;:18;;48086:1;;48069:13;:18;;48086:1;;48069:18;:::i;:::-;;;;-1:-1:-1;;48098:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;48098:21:0;-1:-1:-1;;;;;48098:21:0;;;;;;;;48137:33;;48098:16;;;48137:33;;48098:16;;48137:33;47796:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:631:1:-;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:247::-;709:6;762:2;750:9;741:7;737:23;733:32;730:52;;;778:1;775;768:12;730:52;817:9;804:23;836:31;861:5;836:31;:::i;902:251::-;972:6;1025:2;1013:9;1004:7;1000:23;996:32;993:52;;;1041:1;1038;1031:12;993:52;1073:9;1067:16;1092:31;1117:5;1092:31;:::i;1418:388::-;1486:6;1494;1547:2;1535:9;1526:7;1522:23;1518:32;1515:52;;;1563:1;1560;1553:12;1515:52;1602:9;1589:23;1621:31;1646:5;1621:31;:::i;:::-;1671:5;-1:-1:-1;1728:2:1;1713:18;;1700:32;1741:33;1700:32;1741:33;:::i;:::-;1793:7;1783:17;;;1418:388;;;;;:::o;1811:529::-;1888:6;1896;1904;1957:2;1945:9;1936:7;1932:23;1928:32;1925:52;;;1973:1;1970;1963:12;1925:52;2012:9;1999:23;2031:31;2056:5;2031:31;:::i;:::-;2081:5;-1:-1:-1;2138:2:1;2123:18;;2110:32;2151:33;2110:32;2151:33;:::i;:::-;2203:7;-1:-1:-1;2262:2:1;2247:18;;2234:32;2275:33;2234:32;2275:33;:::i;:::-;2327:7;2317:17;;;1811:529;;;;;:::o;2345:456::-;2422:6;2430;2438;2491:2;2479:9;2470:7;2466:23;2462:32;2459:52;;;2507:1;2504;2497:12;2459:52;2546:9;2533:23;2565:31;2590:5;2565:31;:::i;:::-;2615:5;-1:-1:-1;2672:2:1;2657:18;;2644:32;2685:33;2644:32;2685:33;:::i;:::-;2345:456;;2737:7;;-1:-1:-1;;;2791:2:1;2776:18;;;;2763:32;;2345:456::o;2806:794::-;2901:6;2909;2917;2925;2978:3;2966:9;2957:7;2953:23;2949:33;2946:53;;;2995:1;2992;2985:12;2946:53;3034:9;3021:23;3053:31;3078:5;3053:31;:::i;:::-;3103:5;-1:-1:-1;3160:2:1;3145:18;;3132:32;3173:33;3132:32;3173:33;:::i;:::-;3225:7;-1:-1:-1;3279:2:1;3264:18;;3251:32;;-1:-1:-1;3334:2:1;3319:18;;3306:32;3361:18;3350:30;;3347:50;;;3393:1;3390;3383:12;3347:50;3416:22;;3469:4;3461:13;;3457:27;-1:-1:-1;3447:55:1;;3498:1;3495;3488:12;3447:55;3521:73;3586:7;3581:2;3568:16;3563:2;3559;3555:11;3521:73;:::i;:::-;3511:83;;;2806:794;;;;;;;:::o;3605:382::-;3670:6;3678;3731:2;3719:9;3710:7;3706:23;3702:32;3699:52;;;3747:1;3744;3737:12;3699:52;3786:9;3773:23;3805:31;3830:5;3805:31;:::i;:::-;3855:5;-1:-1:-1;3912:2:1;3897:18;;3884:32;3925:30;3884:32;3925:30;:::i;3992:315::-;4060:6;4068;4121:2;4109:9;4100:7;4096:23;4092:32;4089:52;;;4137:1;4134;4127:12;4089:52;4176:9;4163:23;4195:31;4220:5;4195:31;:::i;:::-;4245:5;4297:2;4282:18;;;;4269:32;;-1:-1:-1;;;3992:315:1:o;4312:615::-;4398:6;4406;4459:2;4447:9;4438:7;4434:23;4430:32;4427:52;;;4475:1;4472;4465:12;4427:52;4515:9;4502:23;4544:18;4585:2;4577:6;4574:14;4571:34;;;4601:1;4598;4591:12;4571:34;4639:6;4628:9;4624:22;4614:32;;4684:7;4677:4;4673:2;4669:13;4665:27;4655:55;;4706:1;4703;4696:12;4655:55;4746:2;4733:16;4772:2;4764:6;4761:14;4758:34;;;4788:1;4785;4778:12;4758:34;4841:7;4836:2;4826:6;4823:1;4819:14;4815:2;4811:23;4807:32;4804:45;4801:65;;;4862:1;4859;4852:12;4801:65;4893:2;4885:11;;;;;4915:6;;-1:-1:-1;4312:615:1;;-1:-1:-1;;;;4312:615:1:o;4932:241::-;4988:6;5041:2;5029:9;5020:7;5016:23;5012:32;5009:52;;;5057:1;5054;5047:12;5009:52;5096:9;5083:23;5115:28;5137:5;5115:28;:::i;5178:245::-;5245:6;5298:2;5286:9;5277:7;5273:23;5269:32;5266:52;;;5314:1;5311;5304:12;5266:52;5346:9;5340:16;5365:28;5387:5;5365:28;:::i;5428:248::-;5496:6;5504;5557:2;5545:9;5536:7;5532:23;5528:32;5525:52;;;5573:1;5570;5563:12;5525:52;-1:-1:-1;;5596:23:1;;;5666:2;5651:18;;;5638:32;;-1:-1:-1;5428:248:1:o;5681:245::-;5739:6;5792:2;5780:9;5771:7;5767:23;5763:32;5760:52;;;5808:1;5805;5798:12;5760:52;5847:9;5834:23;5866:30;5890:5;5866:30;:::i;5931:249::-;6000:6;6053:2;6041:9;6032:7;6028:23;6024:32;6021:52;;;6069:1;6066;6059:12;6021:52;6101:9;6095:16;6120:30;6144:5;6120:30;:::i;6185:450::-;6254:6;6307:2;6295:9;6286:7;6282:23;6278:32;6275:52;;;6323:1;6320;6313:12;6275:52;6363:9;6350:23;6396:18;6388:6;6385:30;6382:50;;;6428:1;6425;6418:12;6382:50;6451:22;;6504:4;6496:13;;6492:27;-1:-1:-1;6482:55:1;;6533:1;6530;6523:12;6482:55;6556:73;6621:7;6616:2;6603:16;6598:2;6594;6590:11;6556:73;:::i;6640:180::-;6699:6;6752:2;6740:9;6731:7;6727:23;6723:32;6720:52;;;6768:1;6765;6758:12;6720:52;-1:-1:-1;6791:23:1;;6640:180;-1:-1:-1;6640:180:1:o;6825:184::-;6895:6;6948:2;6936:9;6927:7;6923:23;6919:32;6916:52;;;6964:1;6961;6954:12;6916:52;-1:-1:-1;6987:16:1;;6825:184;-1:-1:-1;6825:184:1:o;7014:309::-;7079:6;7087;7140:2;7128:9;7119:7;7115:23;7111:32;7108:52;;;7156:1;7153;7146:12;7108:52;7192:9;7179:23;7169:33;;7252:2;7241:9;7237:18;7224:32;7265:28;7287:5;7265:28;:::i;7581:269::-;7638:6;7691:2;7679:9;7670:7;7666:23;7662:32;7659:52;;;7707:1;7704;7697:12;7659:52;7746:9;7733:23;7796:4;7789:5;7785:16;7778:5;7775:27;7765:55;;7816:1;7813;7806:12;7855:257;7896:3;7934:5;7928:12;7961:6;7956:3;7949:19;7977:63;8033:6;8026:4;8021:3;8017:14;8010:4;8003:5;7999:16;7977:63;:::i;:::-;8094:2;8073:15;-1:-1:-1;;8069:29:1;8060:39;;;;8101:4;8056:50;;7855:257;-1:-1:-1;;7855:257:1:o;8865:470::-;9044:3;9082:6;9076:13;9098:53;9144:6;9139:3;9132:4;9124:6;9120:17;9098:53;:::i;:::-;9214:13;;9173:16;;;;9236:57;9214:13;9173:16;9270:4;9258:17;;9236:57;:::i;:::-;9309:20;;8865:470;-1:-1:-1;;;;8865:470:1:o;9548:488::-;-1:-1:-1;;;;;9817:15:1;;;9799:34;;9869:15;;9864:2;9849:18;;9842:43;9916:2;9901:18;;9894:34;;;9964:3;9959:2;9944:18;;9937:31;;;9742:4;;9985:45;;10010:19;;10002:6;9985:45;:::i;:::-;9977:53;9548:488;-1:-1:-1;;;;;;9548:488:1:o;10041:740::-;-1:-1:-1;;;;;10287:32:1;;10269:51;;10257:2;10339;10357:18;;;10350:30;;;10429:13;;10242:18;;;10451:22;;;10209:4;;10530:15;;;;10339:2;10504;10489:18;;;10209:4;10573:182;10587:6;10584:1;10581:13;10573:182;;;10652:13;;10667:6;10648:26;10636:39;;10730:15;;;;10695:12;;;;10609:1;10602:9;10573:182;;;-1:-1:-1;10772:3:1;;10041:740;-1:-1:-1;;;;;;;10041:740:1:o;11065:385::-;11297:1;11293;11288:3;11284:11;11280:19;11272:6;11268:32;11257:9;11250:51;11337:6;11332:2;11321:9;11317:18;11310:34;11380:2;11375;11364:9;11360:18;11353:30;11231:4;11400:44;11440:2;11429:9;11425:18;11417:6;11400:44;:::i;:::-;11392:52;11065:385;-1:-1:-1;;;;;11065:385:1:o;11455:632::-;11626:2;11678:21;;;11748:13;;11651:18;;;11770:22;;;11597:4;;11626:2;11849:15;;;;11823:2;11808:18;;;11597:4;11892:169;11906:6;11903:1;11900:13;11892:169;;;11967:13;;11955:26;;12036:15;;;;12001:12;;;;11928:1;11921:9;11892:169;;;-1:-1:-1;12078:3:1;;11455:632;-1:-1:-1;;;;;;11455:632:1:o;13898:219::-;14047:2;14036:9;14029:21;14010:4;14067:44;14107:2;14096:9;14092:18;14084:6;14067:44;:::i;14883:414::-;15085:2;15067:21;;;15124:2;15104:18;;;15097:30;15163:34;15158:2;15143:18;;15136:62;-1:-1:-1;;;15229:2:1;15214:18;;15207:48;15287:3;15272:19;;14883:414::o;19758:340::-;19960:2;19942:21;;;19999:2;19979:18;;;19972:30;-1:-1:-1;;;20033:2:1;20018:18;;20011:46;20089:2;20074:18;;19758:340::o;22123:356::-;22325:2;22307:21;;;22344:18;;;22337:30;22403:34;22398:2;22383:18;;22376:62;22470:2;22455:18;;22123:356::o;24774:413::-;24976:2;24958:21;;;25015:2;24995:18;;;24988:30;25054:34;25049:2;25034:18;;25027:62;-1:-1:-1;;;25120:2:1;25105:18;;25098:47;25177:3;25162:19;;24774:413::o;26643:701::-;26874:13;;26867:21;26860:29;26842:48;;26909:4;26948:15;;;26942:22;26829:3;26814:19;;;26909:4;26984:18;;;26787:4;27084:178;27098:4;27095:1;27092:11;27084:178;;;27161:13;;27176:4;27157:24;27145:37;;27237:15;;;;27202:12;;;;27118:1;27111:9;27084:178;;;27088:3;;;;27332:4;27324;27316:6;27312:17;27306:24;27302:35;27293:6;27282:9;27278:22;27271:67;26643:701;;;;:::o;27913:224::-;27952:3;27980:6;28013:2;28010:1;28006:10;28043:2;28040:1;28036:10;28074:3;28070:2;28066:12;28061:3;28058:21;28055:47;;;28082:18;;:::i;28142:128::-;28182:3;28213:1;28209:6;28206:1;28203:13;28200:39;;;28219:18;;:::i;:::-;-1:-1:-1;28255:9:1;;28142:128::o;28275:120::-;28315:1;28341;28331:35;;28346:18;;:::i;:::-;-1:-1:-1;28380:9:1;;28275:120::o;28400:168::-;28440:7;28506:1;28502;28498:6;28494:14;28491:1;28488:21;28483:1;28476:9;28469:17;28465:45;28462:71;;;28513:18;;:::i;:::-;-1:-1:-1;28553:9:1;;28400:168::o;28573:125::-;28613:4;28641:1;28638;28635:8;28632:34;;;28646:18;;:::i;:::-;-1:-1:-1;28683:9:1;;28573:125::o;28703:258::-;28775:1;28785:113;28799:6;28796:1;28793:13;28785:113;;;28875:11;;;28869:18;28856:11;;;28849:39;28821:2;28814:10;28785:113;;;28916:6;28913:1;28910:13;28907:48;;;-1:-1:-1;;28951:1:1;28933:16;;28926:27;28703:258::o;28966:380::-;29045:1;29041:12;;;;29088;;;29109:61;;29163:4;29155:6;29151:17;29141:27;;29109:61;29216:2;29208:6;29205:14;29185:18;29182:38;29179:161;;;29262:10;29257:3;29253:20;29250:1;29243:31;29297:4;29294:1;29287:15;29325:4;29322:1;29315:15;29351:197;29389:3;29417:6;29458:2;29451:5;29447:14;29485:2;29476:7;29473:15;29470:41;;;29491:18;;:::i;:::-;29540:1;29527:15;;29351:197;-1:-1:-1;;;29351:197:1:o;29553:135::-;29592:3;-1:-1:-1;;29613:17:1;;29610:43;;;29633:18;;:::i;:::-;-1:-1:-1;29680:1:1;29669:13;;29553:135::o;29693:112::-;29725:1;29751;29741:35;;29756:18;;:::i;:::-;-1:-1:-1;29790:9:1;;29693:112::o;29810:127::-;29871:10;29866:3;29862:20;29859:1;29852:31;29902:4;29899:1;29892:15;29926:4;29923:1;29916:15;29942:127;30003:10;29998:3;29994:20;29991:1;29984:31;30034:4;30031:1;30024:15;30058:4;30055:1;30048:15;30074:127;30135:10;30130:3;30126:20;30123:1;30116:31;30166:4;30163:1;30156:15;30190:4;30187:1;30180:15;30206:127;30267:10;30262:3;30258:20;30255:1;30248:31;30298:4;30295:1;30288:15;30322:4;30319:1;30312:15;30338:127;30399:10;30394:3;30390:20;30387:1;30380:31;30430:4;30427:1;30420:15;30454:4;30451:1;30444:15;30470:131;-1:-1:-1;;;;;30545:31:1;;30535:42;;30525:70;;30591:1;30588;30581:12;30606:118;30692:5;30685:13;30678:21;30671:5;30668:32;30658:60;;30714:1;30711;30704:12;30729:131;-1:-1:-1;;;;;;30803:32:1;;30793:43;;30783:71;;30850:1;30847;30840:12

Swarm Source

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